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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 01:30:24  来源:igfitidea点击:

Working with dictionaries/lists in R

rlisthashmaplookup

提问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 listtype 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 tablewhen 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.

等等。