如何对R中列表中的特定向量求和

时间:2014-05-20 22:09:50

标签: r vector

我知道这应该很简单,但我不能这样做......我有一个称为数据的数据框,可以很好地工作,并使用正确的列标题和所有内容完成我想要的操作。我可以调用colSums()来获取21个数字的列表,这些数字是每列的总和。

> a <-  colSums(data,na.rm = TRUE)
> names(a) <- NULL
> a
 [1] 1000000.00  680000.00  170000.00  462400.00  115600.00  144500.00  314432.00   78608.00   98260.00  122825.00  213813.76   53453.44   66816.80
[14]   83521.00  104401.25  145393.36   36348.34   45435.42   56794.28   70992.85   88741.06

问题是我需要一个单独的第一个数字的列表,接下来的两个的总和,接下来的3的总和,接下来的4的总和等,直到我用完数字。我想它看起来像这样:

c(sum(a[1]),sum(a[2:3]),sum(a[4:6])... etc.

非常感谢任何帮助或不同的方式!

谢谢。

3 个答案:

答案 0 :(得分:2)

你应该只需要sqrt(length(vector))的顺序出去。 seq函数允许您指定起始整数和长度,因此将一系列整数发送到seq(1 + x *(x-1)/ 2,length = x)应创建正确的序列集。目前尚不清楚最后的不完整序列是应该返回结果还是NA,所以我输入na.rm = TRUE。你可能会另有决定。 (您没有说明数据帧,而是一个普通的数字向量。

sumsegs <- function(vec) sapply(1:sqrt(2*length(vec)), function(x) 
                             sum( vec[seq(1+x*(x-1)/2, length=x)], na.rm=TRUE)  )

a <- scan()
 1000000.00 680000.00 170000.00 462400.00 115600.00 144500.00 314432.00 78608.00 98260.00 122825.00 213813.76 53453.44 66816.80  83521.00 104401.25 145393.36 36348.34 45435.42 56794.28 70992.85 88741.06
# 22: enter carriage return to stop scan input
#Read 21 items
 sumsegs(a)
#[1] 1000000.0  850000.0  722500.0  614125.0  522006.2  443705.3

我不确定发送到内部函数的数字的右上限是多少。 sqrt(length(vec))太短,但sqrt(2*length(vec))似乎在较低的数字“工作”。

> sapply( sapply(1:sqrt(2*100), function(x) seq(1+x*(x-1)/2, length=x) ), max)
 [1]   1   3   6  10  15  21  28  36  45  55  66  78  91 105
> sapply( sapply(1:sqrt(100), function(x) seq(1+x*(x-1)/2, length=x) ), max)
 [1]  1  3  6 10 15 21 28 36 45 55

这是一个函数,它返回如此形成的序列中的最后一个元素,并使因子2.1而不是2校正长度为500-1000的范围内的微小缺陷:

 tail(lapply( sapply(1:sqrt(2.1*500), function(x) seq(1+x*(x-1)/2, length=x) ), max),1 )
[[1]]
[1] 528
 tail(lapply( sapply(1:sqrt(2.1*500), function(x) seq(1+x*(x-1)/2, length=x) ), max),1 )
[[1]]
[1] 496

走高似乎并没有降低“时代2”的修正。对此可能有一些密码理论解释。

tail(lapply( sapply(1:sqrt(2*100000), function(x) seq(1+x*(x-1)/2, length=x) ), max),1 )
[[1]]
[1] 100128

答案 1 :(得分:1)

另一种更天真的方法是:

    sums=colSums(data)
    n=0 # number of sums
    i=1 # currentIndex
    intermediate=0;
    newIndex=1;
    newVec <- vector()
    while(i<length(sums)) {
        for(j in i:(i+n)) {
            if(j<=length(sums)) 
                intermediate=intermediate+sums[j]
        }
        if(n>1){
        i=i+n+1;
        }
        else{
        i=i+1;
        }
        newVec=c(newVec, intermediate);
        intermediate=0;
        n=n+1;
    }

答案 2 :(得分:0)

以下是使用rep(...)by(...)

的类似方法
n <- (-1+sqrt(1+8*length(a)))/2   # number of groups
groups <- rep(1:n,1:n)            # indexing vector
result <- as.vector(by(a,groups,sum))
result
# [1] 1000000.0  850000.0  722500.0  614125.0  522006.2  443705.3