[R] sum portions of a vector
Marc Schwartz
marc_schwartz at me.com
Mon Dec 10 22:29:42 CET 2012
On Dec 10, 2012, at 2:52 PM, David Winsemius <dwinsemius at comcast.net> wrote:
>
> On Dec 10, 2012, at 11:29 AM, Sam Steingold wrote:
>
>> How do I sum portions of a vector into another vector?
>> E.g., for
>> --8<---------------cut here---------------start------------->8---
>>> vec <- 1:10
>>> breaks <- c(3,8,10)
>> --8<---------------cut here---------------end--------------->8---
>> I want to get a vector of length 3 with content
>> --8<---------------cut here---------------start------------->8---
>> 6 = 1+2+3
>> 30 = 4+5+6+7+8
>> 19 = 9+10
>> --8<---------------cut here---------------end--------------->8---
>> Obviously, I could write a loop, but I would rather have a vectorized
>> version.
>
> > tapply(vec, cut(vec, breaks=c(-Inf, breaks), include.lowest=TRUE), sum)
> [-Inf,3] (3,8] (8,10]
> 6 30 19
One gotcha there David, as I think you were on the right track earlier with findInterval(). The result with this approach, using cut(), takes advantage of the idiosyncrasy of Sam's example, which uses a sorted vector (1:10) that is equivalent to the indices of the same vector (1:10).
If Sam really is using 'breaks' as the indices into 'vec' and not as ranges for the values to be summed, as cut() does, then findInterval() works:
set.seed(1)
vec2 <- sample(vec)
> vec2
[1] 3 4 5 7 2 8 9 6 10 1
[-Inf,3] = 3+2+1 = 6
(3,8] = 4+5+7+8+6 = 30
(8,10] = 9+10 = 19
> tapply(vec2, cut(vec2, breaks=c(-Inf, breaks), include.lowest=TRUE), sum)
[-Inf,3] (3,8] (8,10]
6 30 19
as compared to:
3+4+5 = 12
7+2+8+9+6 = 32
10+1 = 11
> as.vector(sapply(split(vec2, findInterval(seq(along = vec), breaks + 1)), sum))
[1] 12 32 11
Regards,
Marc
More information about the R-help
mailing list