Sum every nth points

2020-01-27 03:28发布

I have a vector and I need to sum every n numbers and return the results. This is the way I plan on doing it currently. Any better way to do this?

v = 1:100
n = 10
sidx = seq.int(from=1, to=length(v), by=n)
eidx = c((sidx-1)[2:length(sidx)], length(v))
thesum = sapply(1:length(sidx), function(i) sum(v[sidx[i]:eidx[i]]))

This gives:

thesum
 [1]  55 155 255 355 455 555 655 755 855 955

标签: r sum apply
9条回答
Lonely孤独者°
2楼-- · 2020-01-27 04:04

Update

The olde version don't work. Here a ne awnser that use rep to create the grouping factor. No need to use cut:

n <- 5 
vv <- sample(1:1000,100)
seqs <- seq_along(vv)
tapply(vv,rep(seqs,each=n)[seqs],FUN=sum)

You can use tapply

tapply(1:100,cut(1:100,10),FUN=sum)

or to get a list

by(1:100,cut(1:100,10),FUN=sum)

EDIT

In case you have 1:92, you can replace your cut by this :

cut(1:92,seq(1,92,10),include.lowest=T)
查看更多
Bombasti
3楼-- · 2020-01-27 04:04

A little late to the party, but I don't see a rowsum() answer yet. rowsum() is proven more efficient than tapply() and I think it would also be very efficient relative to a few of the other responses as well.

rowsum(v, rep(seq_len(length(v)/n), each=n))[,1]
#  1   2   3   4   5   6   7   8   9  10 
# 55 155 255 355 455 555 655 755 855 955

Using @Josh O'Brien's grouping technique would likely improve efficiency even more.

rowsum(v, (seq_along(v)-1) %/% n)[,1]
#  0   1   2   3   4   5   6   7   8   9 
# 55 155 255 355 455 555 655 755 855 955 

Simply wrap in unname() to drop the group names.

查看更多
疯言疯语
4楼-- · 2020-01-27 04:10
v <- 1:100

n <- 10

cutpoints <- seq( 1 , length( v ) , by = n )

categories <- findInterval( 1:length( v ) , cutpoints )

tapply( v , categories , sum )
查看更多
登录 后发表回答