我有一个数据框(我的“真实”数据要大得多):
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)
最佳答案
您可以改用 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
一个缺点是兼容性的损失,但为此目的它应该可以很好地工作
关于R ID 列匹配行号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36480274/