Is there a way to create a "dictionary" in R, such that it has pairs? Something to the effect of:
x=dictionary(c("Hi","Why","water") , c(1,5,4)) x["Why"]=5
I'm asking this because I am actually looking for a two categorial variables function.
So that if x=dictionary(c("a","b"),c(5,2))
x val 1 a 5 2 b 2
I want to compute x1^2+x2 on all combinations of x keys
x1 x2 val1 val2 x1^2+x2 1 a a 5 5 30 2 b a 2 5 9 3 a b 5 2 27 4 b b 2 2 6
And then I want to be able to retrieve the result using x1 and x2. Something to the effect of: get_result["b","a"] = 9
what is the best, efficient way to do this?
Dict is a R package which implements a key-value dictionary data structure based on R6 class. It is designed to be similar usages with other languages' dictionary implementations (e.g. Python). R's vector and list , of course can have names, so you can get and set value by a name (key) like a dictionary.
1 Answer. For a dictionary in R, you can use the list data structure. You can set the names of the elements of a list using the names() function set equal to a vector of names.
One can only put one type of object into a dictionary. If one wants to put a variety of types of data into the same dictionary, e.g. for configuration information or other common data stores, the superclass of all possible held data types must be used to define the dictionary.
I know three R packages for dictionaries: hash
, hashmap
, and dict
.
Update July 2018: a new one, container
.
Update September 2018: a new one, collections
Keys must be character strings. A value can be any R object.
library(hash) ## hash-2.2.6 provided by Decision Patterns h <- hash() # set values h[["1"]] <- 42 h[["foo"]] <- "bar" h[["4"]] <- list(a=1, b=2) # get values h[["1"]] ## [1] 42 h[["4"]] ## $a ## [1] 1 ## ## $b ## [1] 2 h[c("1", "foo")] ## <hash> containing 2 key-value pair(s). ## 1 : 42 ## foo : bar h[["key not here"]] ## NULL
To get keys:
keys(h) ## [1] "1" "4" "foo"
To get values:
values(h) ## $`1` ## [1] 42 ## ## $`4` ## $`4`$a ## [1] 1 ## ## $`4`$b ## [1] 2 ## ## ## $foo ## [1] "bar"
The print
instance:
h ## <hash> containing 3 key-value pair(s). ## 1 : 42 ## 4 : 1 2 ## foo : bar
The values
function accepts the arguments of sapply
:
values(h, USE.NAMES=FALSE) ## [[1]] ## [1] 42 ## ## [[2]] ## [[2]]$a ## [1] 1 ## ## [[2]]$b ## [1] 2 ## ## ## [[3]] ## [1] "bar" values(h, keys="4") ## 4 ## a 1 ## b 2 values(h, keys="4", simplify=FALSE) ## $`4` ## $`4`$a ## [1] 1 ## ## $`4`$b ## [1] 2
See https://cran.r-project.org/web/packages/hashmap/README.html.
hashmap
does not offer the flexibility to store arbitrary types of objects.
Keys and values are restricted to "scalar" objects (length-one character, numeric, etc.). The values must be of the same type.
library(hashmap) H <- hashmap(c("a", "b"), rnorm(2)) H[["a"]] ## [1] 0.1549271 H[[c("a","b")]] ## [1] 0.1549271 -0.1222048 H[[1]] <- 9
Beautiful print
instance:
H ## ## (character) => (numeric) ## ## [1] => [+9.000000] ## ## [b] => [-0.122205] ## ## [a] => [+0.154927]
Errors:
H[[2]] <- "Z" ## Error in x$`[[<-`(i, value): Not compatible with requested type: [type=character; target=double]. H[[2]] <- c(1,3) ## Warning in x$`[[<-`(i, value): length(keys) != length(values)!
Currently available only on Github: https://github.com/mkuhn/dict
Strengths: arbitrary keys and values, and fast.
library(dict) d <- dict() d[[1]] <- 42 d[[c(2, 3)]] <- "Hello!" # c(2,3) is the key d[["foo"]] <- "bar" d[[4]] <- list(a=1, b=2) d[[1]] ## [1] 42 d[[c(2, 3)]] ## [1] "Hello!" d[[4]] ## $a ## [1] 1 ## ## $b ## [1] 2
Accessing to a non-existing key throws an error:
d[["not here"]] ## Error in d$get_or_stop(key): Key error: [1] "not here"
But there is a nice feature to deal with that:
d$get("not here", "default value for missing key") ## [1] "default value for missing key"
Get keys:
d$keys() ## [[1]] ## [1] 4 ## ## [[2]] ## [1] 1 ## ## [[3]] ## [1] 2 3 ## ## [[4]] ## [1] "foo"
Get values:
d$values() ## [[1]] ## [1] 42 ## ## [[2]] ## [1] "Hello!" ## ## [[3]] ## [1] "bar" ## ## [[4]] ## [[4]]$a ## [1] 1 ## ## [[4]]$b ## [1] 2
Get items:
d$items() ## [[1]] ## [[1]]$key ## [1] 4 ## ## [[1]]$value ## [[1]]$value$a ## [1] 1 ## ## [[1]]$value$b ## [1] 2 ## ## ## ## [[2]] ## [[2]]$key ## [1] 1 ## ## [[2]]$value ## [1] 42 ## ## ## [[3]] ## [[3]]$key ## [1] 2 3 ## ## [[3]]$value ## [1] "Hello!" ## ## ## [[4]] ## [[4]]$key ## [1] "foo" ## ## [[4]]$value ## [1] "bar"
No print
instance.
The package also provides the function numvecdict
to deal with a dictionary in which numbers and strings (including vectors of each) can be used as keys, and that can only store vectors of numbers.
You can use just data.frame
and row.names
to do this:
x=data.frame(row.names=c("Hi","Why","water") , val=c(1,5,4)) x["Why",] [1] 5
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With