Reputation: 55
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
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.
The same idiom works for a*b*c
a*b*c
[1] 45 120 231 384
For min
or max
, there's a different function to use: pmin
and
pmax
, respectively.
pmin(a,b,c)
[1] 1 2 3 4
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
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