Working with dictionaries/lists in R

后端 未结 7 1623
说谎
说谎 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:50

    You do not even need lists if your "number" values are all of the same mode. If I take Dirk Eddelbuettel's example:

    > foo <- c(12, 22, 33)
    > names(foo) <- c("tic", "tac", "toe")
    > foo
    tic tac toe
     12  22  33
    > names(foo)
    [1] "tic" "tac" "toe"
    

    Lists are only required if your values are either of mixed mode (for example characters and numbers) or vectors.

    For both lists and vectors, an individual element can be subsetted by name:

    > foo["tac"]
    tac 
     22 
    

    Or for a list:

    > foo[["tac"]]
    [1] 22
    
    0 讨论(0)
  • 2020-12-07 09:50

    The package hash is now available: https://cran.r-project.org/web/packages/hash/hash.pdf

    Examples

    h <- hash( keys=letters, values=1:26 )
    h <- hash( letters, 1:26 )
    h$a
    # [1] 1
    h$foo <- "bar"
    h[ "foo" ]
    # <hash> containing 1 key-value pair(s).
    #   foo : bar
    h[[ "foo" ]]
    # [1] "bar"
    
    0 讨论(0)
  • 2020-12-07 09:51

    To extend a little bit answer of Calimo I present few more things you may find useful while creating this quasi dictionaries in R:

    a) how to return all the VALUES of the dictionary:

    >as.numeric(foo)
    [1] 12 22 33
    

    b) check whether dictionary CONTAINS KEY:

    >'tic' %in% names(foo)
    [1] TRUE
    

    c) how to ADD NEW key, value pair to dictionary:

    c(foo,tic2=44)

    results:

    tic       tac       toe     tic2
    12        22        33        44 
    

    d) how to fulfill the requirement of REAL DICTIONARY - that keys CANNOT repeat(UNIQUE KEYS)? You need to combine b) and c) and build function which validates whether there is such key, and do what you want: e.g don't allow insertion, update value if the new differs from the old one, or rebuild somehow key(e.g adds some number to it so it is unique)

    e) how to DELETE pair BY KEY from dictionary:

    foo<-foo[which(foo!=foo[["tac"]])]

    0 讨论(0)
  • 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

    0 讨论(0)
  • 2020-12-07 09:56

    I'll just comment you can get a lot of mileage out of table when trying to "fake" a dictionary also, e.g.

    > x <- c("a","a","b","b","b","c")
    > (t <- table(x))
    x
    a b c 
    2 3 1 
    > names(t)
    [1] "a" "b" "c"
    > o <- order(as.numeric(t))
    > names(t[o])
    [1] "c" "a" "b"
    

    etc.

    0 讨论(0)
  • 2020-12-07 10:04

    Shorter variation of Dirk's answer:

    # Create a Color Palette Dictionary 
    > color <- c('navy.blue', 'gold', 'dark.gray')
    > hex <- c('#336A91', '#F3C117', '#7F7F7F')
    
    > # Create List
    > color_palette <- as.list(hex)
    > # Name List Items
    > names(color_palette) <- color
    > 
    > color_palette
    $navy.blue
    [1] "#336A91"
    
    $gold
    [1] "#F3C117"
    
    $dark.gray
    [1] "#7F7F7F"
    
    0 讨论(0)
提交回复
热议问题