用R计算向量的滚动总和

时间:2011-11-01 23:50:38

标签: r matrix multiplication

我有一个长向量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中存储每个拉伸的起始索引。

4 个答案:

答案 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的时间是:

  • Brandon Bertelsen(for loop):0.017
  • Ramnath(rowsum):0.057
  • 约翰(分居/申请):0.280
  • Aaron(cumsum):0.008

更改为n <- 1e5时间是:

  • Brandon Bertelsen(for loop):2.181
  • Ramnath(rowsum):0.226
  • 约翰(分裂/申请):0.852
  • Aaron(cumsum):0.015

我怀疑这比使用矩阵乘法更快,即使使用稀疏矩阵包,因为不必形成矩阵或进行任何乘法。如果需要更快的速度,我怀疑它可以通过用C写入来加快速度;使用inlinercpp软件包并不难,但我会留给您。

答案 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]]))
}