Ben Z
Ben Z

Reputation: 105

how to cross add multiple vectors with unequal n with each element in another

If I have

A<-c(1,7)
B<-c(8,9)
C<-c(10,11,13)

I wish to have

 Sum<-c(1+8+10, 1+8+11, 1+8+13, 1+9+10, 1+9+11, 1+9+13, 7+8+10, 7+8+11, 7+8+13, 
        7+9+10, 7+9+11, 7+9+13)

Is there an easy way to do that in R?

*********update************

Sorry for not being clear before, I really wish to seek for a generalized solution, say I have

A<-c(a1,a2)
B<-c(b1,b2)
C<-c(c1,c2,c3)

And what I really wish would be

 Sum<-c(a1+b1+c1, a1+b1+c2, a1+b1+c3, a1+b2+c1, a1+b2+c2, a1+b2+c3,a2+b1+c1, a2+b1+c2, a2+b1+c3, a2+b2+c1, a2+b2+c2, a2+b2+c3)

and keep it in this order regardless of the values of ABC.

Update 2

The correct answer should be expand.grid(C, B, A)

Upvotes: 2

Views: 73

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 389135

We could use expand.grid with rowSums

rowSums(expand.grid(A, B, C))

#[1] 19 25 20 26 20 26 21 27 22 28 23 29

Some explanation - expand.grid returns a row for every combination of A, B and C

expand.grid(A, B, C)

#   Var1 Var2 Var3
#1     1    8   10
#2     7    8   10
#3     1    9   10
#4     7    9   10
#5     1    8   11
#6     7    8   11
#7     1    9   11
#8     7    9   11
#9     1    8   13
#10    7    8   13
#11    1    9   13
#12    7    9   13

and then we take sum for each row.


We can also use double outer

c(outer(outer(A, B, "+"), C, "+"))
#[1] 19 25 20 26 20 26 21 27 22 28 23 29

EDIT

If the order of the output is important, we can order them after using expand.grid

mat <- expand.grid(A, B, C)
rowSums(mat[order(mat$Var1, mat$Var2, mat$Var3), ])
#19 20 22 20 21 23 25 26 28 26 27 29 

Or if you have many columns and don't want to call each column by name you could do

rowSums(mat[do.call(order,mat), ])
#19 20 22 20 21 23 25 26 28 26 27 29 

Upvotes: 6

akrun
akrun

Reputation: 887511

Here is an option with CJ

library(data.table)
CJ(A, B, C)[, Reduce(`+`, .SD)]
#[1] 19 20 22 20 21 23 25 26 28 26 27 29

Upvotes: 3

Related Questions