list 在 R 中使用字典/列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2858014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Working with dictionaries/lists in R
提问by Ivri
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 of keys. Anybody knows?
我有一个小问题:我在 R 中找不到字典数据结构,所以我改用列表(如“单词”->数字)所以,现在我遇到了如何获取键列表的问题。有人知道吗?
回答by Dirk Eddelbuettel
Yes, the list
type is a good approximation. You can use names()
on your list to set and retrieve the 'keys':
是的,该list
类型是一个很好的近似值。您可以names()
在列表中使用来设置和检索“密钥”:
> foo <- vector(mode="list", length=3)
> names(foo) <- c("tic", "tac", "toe")
> foo[[1]] <- 12; foo[[2]] <- 22; foo[[3]] <- 33
> foo
$tic
[1] 12
$tac
[1] 22
$toe
[1] 33
> names(foo)
[1] "tic" "tac" "toe"
>
回答by Calimo
You do not even need lists if your "number" values are all of the same mode. If I take Dirk Eddelbuettel's example:
如果您的“数字”值都是相同的模式,您甚至不需要列表。如果我以 Dirk Eddelbuettel 的例子为例:
> 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
回答by andilabs
To extend a little bit answer of Calimo I present few more things you may find useful while creating this quasi dictionaries in R:
为了扩展 Calimo 的一些答案,我提供了一些在 R 中创建这个准词典时您可能会发现有用的东西:
a) how to return all the VALUES of the dictionary:
a) 如何返回字典的所有 VALUES:
>as.numeric(foo)
[1] 12 22 33
b) check whether dictionary CONTAINS KEY:
b) 检查字典是否包含 KEY:
>'tic' %in% names(foo)
[1] TRUE
c) how to ADD NEW key, value pair to dictionary:
c) 如何向字典添加新的键、值对:
c(foo,tic2=44)
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)
d) 如何满足 REAL DICTIONARY 的要求 - 键不能重复(唯一键)?您需要结合 b) 和 c) 并构建函数来验证是否存在这样的密钥,并执行您想要的操作:例如,不允许插入,如果新的与旧的不同,则更新值,或者以某种方式重建密钥(例如添加一些数字,所以它是唯一的)
e) how to DELETE pair BY KEY from dictionary:
e) 如何从字典中 DELETE pair BY KEY:
foo<-foo[which(foo!=foo[["tac"]])]
foo<-foo[which(foo!=foo[["tac"]])]
回答by vonjd
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 indeedan inbuilt dictionary data structure: environments with the option hash = TRUE
然而很多人不知道的是,R确实有一个内置的字典数据结构:带有选项的环境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
编辑:在这个答案的基础上,我写了一篇包含更多上下文的博客文章:http: //blog.ephorie.de/hash-me-if-you-can
回答by Ng?c Linh V?
The package hashis now available: https://cran.r-project.org/web/packages/hash/hash.pdf
包哈希现在可用: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"
回答by Nettle
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"
回答by Gabriel Perdue
I'll just comment you can get a lot of mileage out of table
when trying to "fake" a dictionary also, e.g.
我只是评论一下,table
当你试图“伪造”一本字典时,你也可以获得很多好处,例如
> 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.
等等。