我有一个长向量x,另一个包含长度的v。我想求和x,以便答案y
是长度为length(v)
的向量,y[1]
为sum(x[1:v[i]])
,y[2]
为sum(x[(1+v[1]):(v[1]+v[2])])
, 等等。基本上,这是从维度length(x)
的空间到维度length(v)
之一执行稀疏矩阵乘法。但是,我宁愿不引进“先进机械”,尽管我可能不得不这样做。它需要非常非常快。任何人都可以想到比使用稀疏矩阵包更简单的东西吗?
示例 -
x <- c(1,1,3,4,5)
v <- c(2,3)
y <- myFunc(x,v)
y
应为c(2,12)
我愿意接受任何预处理 - 例如,在v中存储每个拉伸的起始索引。
答案 0 :(得分:8)
y <- cumsum(x)[cumsum(v)]
y <- c(y[1], diff(y))
这看起来正在做额外的工作,因为它正在计算整个矢量的cumsum,但它实际上比其他解决方案更快,对于小型和大量的组。
以下是我模拟数据的方法
set.seed(5)
N <- 1e6
n <- 10
x <- round(runif(N,0,100),1)
v <- as.vector(table(sample(n, N, replace=TRUE)))
在我的机器上n <- 10
的时间是:
更改为n <- 1e5
时间是:
我怀疑这比使用矩阵乘法更快,即使使用稀疏矩阵包,因为不必形成矩阵或进行任何乘法。如果需要更快的速度,我怀疑它可以通过用C写入来加快速度;使用inline
和rcpp
软件包并不难,但我会留给您。
答案 1 :(得分:1)
您可以使用rowsum
执行此操作。它应该相当快,因为它在后台使用C
代码。
y <- rowsum(x, rep(1:length(v), v))
答案 2 :(得分:1)
这是一个稍微不同的方法。
s <- rep(1:length(v), v)
l <- split(x, s)
y <- sapply(l, sum)
答案 3 :(得分:0)
尝试类似:
for (i in 1:length(v)) {
y[i] <- ifelse(i > 1,sum(x[v[i-1]:v[i]]), sum(x[1:v[i]]))
}