r语言 - 使用重复索引对循环进行矢量化



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

 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,它是

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
下面是

在基本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])

最新更新