【问题标题】:Vectorize loop with repeating indices使用重复索引矢量化循环
【发布时间】:2017-11-15 19:59:51
【问题描述】:

我有一个包含重复值的索引向量:

 IN <- c(1, 1, 2, 2, 3, 4, 5)     

我想用这些索引减去两个向量:

ST <- c(0, 0, 0, 0, 0, 0, 0)
SB <- c(1, 1, 1, 1, 1, 1, 1)

但是,我想按“顺序”进行减法,这样在减去第一个索引值 (0, 1) 后,第二次减法将“建立”第一次减法。我想最终得到一个看起来像这样的向量 FN:

c(-2, -2, -1, -1, -1, 0, 0)

这在 for 循环中很容易做到:

for(i in seq_along(IN)){
  ST[IN[i]] <- ST[IN[i]] - SB[IN[i]]
}

但是我需要在长向量上多次运行这个循环,这可能需要好几个小时。有什么方法可以矢量化这个任务并避免 for 循环?也许使用 data.table 技术?

【问题讨论】:

  • 感谢您的回复。我必须做一些测试,看看哪种方法最能满足我的需求,但两者都能完成工作。

标签: r vector vectorization


【解决方案1】:

这是在基础 R 中使用 aggregate 的选项:

ag <- aggregate(.~IN, data.frame(IN, ST[IN]-SB[IN]), sum)
replace(ST, ag[,1], ag[,2])

#[1] -2 -2 -1 -1 -1  0  0

或者使用xtabs

d <- as.data.frame(xtabs(B~A, data.frame(A=IN, B=ST[IN]-SB[IN])))
replace(ST, d[,1], d[,2])

【讨论】:

    【解决方案2】:

    当然,使用 data.table,它是

    library(data.table)
    DT = data.table(ST)
    mDT = data.table(IN, SB)[, .(sub = sum(SB)), by=.(w = IN)]
    DT[mDT$w, ST := ST - mDT$sub ]
    
       ST
    1: -2
    2: -2
    3: -1
    4: -1
    5: -1
    6:  0
    7:  0
    

    或者使用基础 R:

    w = sort(unique(IN))
    ST[w] <- ST[w] - tapply(SB, IN, FUN = sum)
    # [1] -2 -2 -1 -1 -1  0  0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      • 2021-04-29
      • 1970-01-01
      • 2017-06-18
      • 1970-01-01
      • 1970-01-01
      • 2012-09-24
      相关资源
      最近更新 更多