我有一个包含重复值的索引向量:
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)
但是,我想在&#34; order&#34;中进行减法。这样,在减去第一个索引值(0,1)之后,第二个减法将“#34;构建”#34;第一次减法。我想最终得到一个看起来像这样的矢量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技术?
答案 0 :(得分:4)
当然,有了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
答案 1 :(得分:2)
以下是在基础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])