【问题标题】:Fastest way to remove this list-wise for loop?删除这个列表式 for 循环的最快方法是什么?
【发布时间】:2014-01-23 00:10:13
【问题描述】:

使用 R:

我有一个长度为 n 的向量列表,对应于一个长度为 n 的 id 向量。所以列表中的每个向量都有 m 个 id。我还有一个值向量,长度为 m:

L1 = c(1,65,23)
L2 = c(1,23,45)
L3 = c(45,23)
L4 = c(45,65)

V2 = list(L1,L2,L3,L4)

IDs = c(1, 23, 45, 65)
Values = c(400, 500, 100, 150)
dat = data.frame(IDs, Values)

我想从相应的(按索引)列表中减去每个值。 在一个循环中,这将是这样的:

testFun = function(dat){
        y = list()
        for (i in 1:nrow(dat)){
        y[[i]] = dat$Value[i] - dat$Value[which(dat$IDs %in% V2[[i]])]

        }
    return(y)
    }
testFun(dat)

基本上,这是可行的,但不能很好地扩展。 任何帮助将非常感激!谢谢

【问题讨论】:

  • 什么是y? (您的示例不可重现)
  • @mnel y = list() 抱歉遗漏
  • 注意,你的[ ]中不需要which

标签: r performance list for-loop


【解决方案1】:

另一种方法是将结果保持为制表符形式。这是一个data.table解决方案

# convert your data to data.table
library(data.table)
DT <- data.table(dat, key="IDs")

DT[, Values - DT[.(V2[[i]])]$Values , by=list(i=seq(nrow(DT)))]
    i   V1
 1: 1    0
 2: 1  250
 3: 1 -100
 4: 2  100
 5: 2    0
 6: 2  400
 7: 3    0
 8: 3 -400
 9: 4   50
10: 4    0

【讨论】:

  • DT[, list(list(Values - DT[.(V2[[i]])]$Values)) , by=list(i=seq(nrow(DT)))] 将其保留为列表。
  • @menl,不错。我认为使用RES[.(3), _expr_] 可能会有优势(其中RES 是结果输出)。
  • 这个规模可以吗?在数据集中,我有 175,000 个 ID,每个 ID 都与平均长度为 500 的 V1 向量相关联
  • @Sarobinson,只有一种方法可以真正找出答案 :) 它不仅应该扩展,而且应该比使用 %in% 快得多。话虽如此,您应该根据 MNEL 的建议对这种方法进行基准测试。
  • 好的,所以 data.table 解决方案比循环更快,但仍然很慢(约 5 分钟)。还有其他方法吗?也许是 mcapply?
【解决方案2】:

这是另一个data.table 解决方案

DT <- data.table(dat, key = 'IDs')

DT[, col3 := vector(mode='list',length = nrow(DT))]

for (i in seq_along(V2)){
   set(DT, i = i, j = 'col3', value = list(list(DT[i,Values] - DT[.(V2[[i]])][['Values']])))
}

请注意,您正在创建一个长度为 175000、175000 次的向量。根据您当前的数据设置和您想要的结果,这将是您的时间限制因素。

【讨论】:

    猜你喜欢
    • 2017-06-28
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多