Working with dictionaries/lists in R

后端 未结 7 1632
说谎
说谎 2020-12-07 09:14

I have trivial question: I couldn\'t find a dictionary data structure in R, so I used list instead (like \"word\"->number) So, right now I have problem how to get the list o

7条回答
  •  被撕碎了的回忆
    2020-12-07 09:54

    The reason for using dictionaries in the first place is performance. Although it is correct that you can use named vectors and lists for the task the issue is that they are becoming quite slow and memory hungry with more data.

    Yet what many people don't know is that R has indeed an inbuilt dictionary data structure: environments with the option hash = TRUE

    See the following example for how to make it work:

    # vectorize assign, get and exists for convenience
    assign_hash <- Vectorize(assign, vectorize.args = c("x", "value"))
    get_hash <- Vectorize(get, vectorize.args = "x")
    exists_hash <- Vectorize(exists, vectorize.args = "x")
    
    # keys and values
    key<- c("tic", "tac", "toe")
    value <- c(1, 22, 333)
    
    # initialize hash
    hash = new.env(hash = TRUE, parent = emptyenv(), size = 100L)
    # assign values to keys
    assign_hash(key, value, hash)
    ## tic tac toe 
    ##   1  22 333
    # get values for keys
    get_hash(c("toe", "tic"), hash)
    ## toe tic 
    ## 333   1
    # alternatively:
    mget(c("toe", "tic"), hash)
    ## $toe
    ## [1] 333
    ## 
    ## $tic
    ## [1] 1
    # show all keys
    ls(hash)
    ## [1] "tac" "tic" "toe"
    # show all keys with values
    get_hash(ls(hash), hash)
    ## tac tic toe 
    ##  22   1 333
    # remove key-value pairs
    rm(list = c("toe", "tic"), envir = hash)
    get_hash(ls(hash), hash)
    ## tac 
    ##  22
    # check if keys are in hash
    exists_hash(c("tac", "nothere"), hash)
    ##     tac nothere 
    ##    TRUE   FALSE
    # for single keys this is also possible:
    # show value for single key
    hash[["tac"]]
    ## [1] 22
    # create new key-value pair
    hash[["test"]] <- 1234
    get_hash(ls(hash), hash)
    ##  tac test 
    ##   22 1234
    # update single value
    hash[["test"]] <- 54321
    get_hash(ls(hash), hash)
    ##   tac  test 
    ##    22 54321
    

    Edit: On the basis of this answer I wrote a blog post with some more context: http://blog.ephorie.de/hash-me-if-you-can

提交回复
热议问题