我有一个数据框(我的"真实"数据更大):
df = data.frame(id = c(1, 2, 2, 5, 6, 7), value = c("A", "B", "C", "D", "E", "F"))
然后我将其转换为列表:
list = split(df$value, df$id)
我现在想要通过id有效地访问列表中的值。显然,我可以使用
list[["6"]]
获得" E"。显然,随着ID号的增加,访问值需要更多时间。想象一个更大的列表,访问10001-20000中的每个值比访问1-10000需要更长的时间。
如何更快地访问这些值?我的想法是我将行ID与列表中的ID匹配,以便list[["6"]] == list[[6]]
,但我该怎么做?有更好的选择吗?
编辑:有关上下文的更多信息。我使用类似于这个的功能:
test_function = function(a, b) {
a = unique(list[[a]])
b = unique(list[[b]])
return (length(intersect(a, b)))
}
对看起来像这样的数据框使用apply:
a b
1 36 38
2 38 39
3 39 36
4 95 96
5 96 95
6 190 191
7 191 192
8 192 190
9 193 194
10 194 196
因此,对于数据帧中的每一行,我想计算两个ID的值列表之间的交集长度。
Edit2:谢谢你的所有答案。我已经测试了所有建议的方法,并发现为了我的具体目的,digEmAll的答案是最快的方法:
myEnv <- list2env(list)
get("10000",envir=myEnv)
答案 0 :(得分:3)
您可以使用hash
库,它应该比命名列表更快:
df <- data.frame(id = 1:1000000)
df$val <- c("A", "B", "C", "D", "E")
mylist <- split(df$val, df$id)
library(hash)
myhash <- hash(mylist)
myhash[["2"]]
[1] "B"
基准:
microbenchmark::microbenchmark(
myhash[["1000000"]],
mylist[["1000000"]]
)
Unit: microseconds
expr min lq mean median uq max neval
myhash[["1000000"]] 25.466 33.828 72.85514 103.5735 107.565 133.03 100
mylist[["1000000"]] 10765.207 10957.911 11076.01143 11044.0010 11120.398 12145.30 100
一个缺点是失去了兼容性,但为了这个目的,它应该可以正常工作
答案 1 :(得分:2)
感谢您的所有答案。我已经测试了所有建议的方法,并发现根据我的具体目的, digEmAll 的答案是最快的方式:
myEnv <- list2env(list)
get("10000",envir=myEnv)