Есть ли словарь функциональности в R - PullRequest
6 голосов
/ 19 октября 2011

Есть ли способ создать «словарь» в R, чтобы в нем были пары?Кое-что с эффектом:

x=dictionary(c("Hi","Why","water") , c(1,5,4))
x["Why"]=5

Я спрашиваю это, потому что я на самом деле ищу функцию двух категориальных переменных., "b"), c (5,2))

     x  val
1    a  5 
2    b  2 

Я хочу вычислить x1 ^ 2 + x2 для всех комбинаций клавиш x

     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

А потом я хочучтобы иметь возможность получить результат, используя x1 и x2.Что-то вроде: get_result ["b", "a"] = 9

Какой самый лучший и эффективный способ сделать это?

Ответы [ 3 ]

7 голосов
/ 15 июня 2017

Я знаю три пакета R для словарей: hash, hashmap и dict.

Обновление в июле 2018 года: новый,container.

Обновление за сентябрь 2018 года: новый, коллекции

хеш

Ключи должны быть символьными строками.Значением может быть любой объект R.

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

Для получения ключей:

keys(h)
## [1] "1"   "4"   "foo"

Для получения значений:

values(h)
## $`1`
## [1] 42
## 
## $`4`
## $`4`$a
## [1] 1
## 
## $`4`$b
## [1] 2
## 
## 
## $foo
## [1] "bar"

Экземпляр print:

h
## <hash> containing 3 key-value pair(s).
##   1 : 42
##   4 : 1 2
##   foo : bar

Функция values принимает аргументы 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

hashmap

См. https://cran.r -project.org / web / packages / hashmap / README.html.

hashmap делает не гибкими для хранения произвольных типов объектов.

Ключи и значения ограничены «скалярными» объектами (длина-один символ, числовой, так далее.).Значения должны быть одного типа.

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

Красивые print Экземпляр:

H
## ## (character) => (numeric)  
## ##         [1] => [+9.000000]
## ##         [b] => [-0.122205]
## ##         [a] => [+0.154927]

Ошибки:

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)!

dict

В настоящее время доступно только на Github: https://github.com/mkuhn/dict

Сильные стороны : произвольные ключи и значения и быстрые.

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

Доступ кнесуществующий ключ выдает ошибку:

d[["not here"]]
## Error in d$get_or_stop(key): Key error: [1] "not here"

Но есть одна приятная особенность:

d$get("not here", "default value for missing key")
## [1] "default value for missing key"

Получить ключи:

d$keys()
## [[1]]
## [1] 4
## 
## [[2]]
## [1] 1
## 
## [[3]]
## [1] 2 3
## 
## [[4]]
## [1] "foo"

Получитьзначения:

d$values()
## [[1]]
## [1] 42
## 
## [[2]]
## [1] "Hello!"
## 
## [[3]]
## [1] "bar"
## 
## [[4]]
## [[4]]$a
## [1] 1
## 
## [[4]]$b
## [1] 2

Получить элементы:

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"

Нет print экземпляр.

Пакет также предоставляет функцию numvecdict для работы со словарем вкакие числа и строки (включая векторы каждого) можно использовать в качестве ключей, и которые могут хранить только векторы чисел.

3 голосов
/ 19 октября 2011

В этом случае векторы, матрицы, списки и т. Д. Ведут себя как «словари» в R, вы можете сделать что-то вроде следующего:

> (x <- structure(c(5,2),names=c("a","b"))) ## "dictionary"
a b 
5 2 
> (result <- outer(x,x,function(x1,x2) x1^2+x2))
   a  b
a 30 27
b  9  6
> result["b","a"]
[1] 9

Если вам нужна таблица, как показано в вашемНапример, просто измените ваш массив ...

> library(reshape)
> (dfr <- melt(result,varnames=c("x1","x2")))
  x1 x2 value
1  a  a    30
2  b  a     9
3  a  b    27
4  b  b     6
> transform(dfr,val1=x[x1],val2=x[x2])
  x1 x2 value val1 val2
1  a  a    30    5    5
2  b  a     9    2    5
3  a  b    27    5    2
4  b  b     6    2    2
1 голос
/ 19 октября 2011

См. Мой ответ на очень недавний вопрос . По сути, вы используете среды для этого типа функциональности.

Для случая более высокой размерности вам может быть лучше использовать array (двумерный), если вы хотите простой синтаксис для получения результата (вы можете назвать строки и столбцы). В качестве альтернативы вы можете paste объединить два ключа с разделителем, которого в них нет, а затем использовать его в качестве уникального идентификатора.

Чтобы быть конкретным, что-то вроде этого:

tmp<-data.frame(x=c("a", "b"), val=c(5,2))
tmp2<-outer(seq(nrow(tmp)), seq(nrow(tmp)), function(lhs, rhs){tmp$val[lhs] + tmp$val[rhs]})
dimnames(tmp2)<-list(tmp$x, tmp$x)
tmp2
tmp2["a", "b"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...