Tyler
Tyler

Reputation: 55

Summation by elements of vectors in R

I'm looking for a much nicer way to sum vectors by elements. Suppose we have 3 vectors:

a <- c(1, 2, 3, 4)
b <- c(5, 6, 7, 8)
c <- c(9, 10, 11, 12)

I want

d = c(15, 18, 21, 24)

The way I've been working at it is through a for-loop, but I think that's a bit tedious, and can be slow with large vectors, ie:

for (j in 1:4){
   d[j] = sum(c(a[j], b[j], c[j]))
}

Is there a function in R that would just add these vectors together by element position?

Upvotes: 2

Views: 3683

Answers (3)

rbatt
rbatt

Reputation: 4807

@nongkrong is correct, a+b+c is the easiest way to do this.

@akrun also has valid points about NA's.

But I would like to point out 1) other functions that work similarly, 2) functions that are vectorized versions of their more common counterparts, and 3) the function that will help you perform this task in any situation.

  1. The same idiom works for a*b*c

    a*b*c
    [1]  45 120 231 384
    
  2. For min or max, there's a different function to use: pmin and pmax, respectively.

    pmin(a,b,c)
    [1] 1 2 3 4
    
  3. If you want to apply a function element-wise to a series of vectors, try mapply.

    mapply(sum, a, b, c) # this answers your question!
    [1] 15 18 21 24
    

    Note, in when using + in conjunction with mapply (i.e., mapply("+", a, b)) you can only use 2 vectors b/c + expects 2 values (whereas a+b+c handles 3 values at once but calls + twice!).

Also note that pmin and sum (within mapply) can handle NA's easily through the na.rm=TRUE arugment (e.g., mapply(sum, a, b, c, na.rm=TRUE))

Good luck, and welcome to vectorization and other nifty tricks in R :)

Upvotes: 2

akrun
akrun

Reputation: 887951

We can use colSums after we rbind the vectors 'a', 'b', and 'c'

 colSums(rbind(a,b,c))
 #[1] 15 18 21 24

Or we can place it in a list and use Reduce/+

Reduce(`+`, list(a,b,c))
#[1] 15 18 21 24

I used colSums as + have some limitations when there are NA elements. For example.

 a1 <- c(3, 2, NA, 1)
 b1 <- c(5, NA, 3, 2)
 a1+b1
 #[1]  8 NA NA  3

whereas na.rm argument in colSums can be useful for such conditions.

 colSums(rbind(a1,b1), na.rm=TRUE)
 #[1] 8 2 3 3

Even the Reduce approach is not good.

Upvotes: 5

Rorschach
Rorschach

Reputation: 32466

Try this

a+b+c

vectorized math! cheers

Upvotes: 6

Related Questions