我有一个数据框(我的“真实”数据要大得多):

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/

10-11 22:33
查看更多