movassat
movassat

Reputation: 13

All possible combination of summation of vectors in R

I have 3 vectors, A, B, C. They all have the same number of rows. What I am looking for is the all possible combination of summation of vectors. For this example, I want to have A+B, A+C, B+C, and A+B+C. Is there any command/package in R that can do that? In another words, I want all possible linear combinations of the 3 vectors with linear coefficients of 1. My real problem involves a lot of vectors, not just 3. I simplified it here.

Thanks

Upvotes: 0

Views: 335

Answers (3)

eipi10
eipi10

Reputation: 93881

library(tidyverse)

a = 1:3
b = 4:6
c = 7:9

dat = data.frame(a, b, c)

sum.fnc = function(data, n) {

  # Get combinations of columns to sum
  sum.vars = combn(names(data), n, simplify=FALSE)

  # Name the columns based on the vectors being summed
  names(sum.vars) = map(sum.vars, ~paste(.x, collapse="."))

  # Return the desired sums
  map(sum.vars, ~rowSums(data[ , .x]))
}

all.sums = map(2:length(dat), ~sum.fnc(dat, .x)) %>% flatten

all.sums
$a.b
[1] 5 7 9

$a.c
[1]  8 10 12

$b.c
[1] 11 13 15

$a.b.c
[1] 12 15 18
as.data.frame(all.sums)
  a.b a.c b.c a.b.c
1   5   8  11    12
2   7  10  13    15
3   9  12  15    18

Upvotes: 1

akrun
akrun

Reputation: 887971

One option is combn after placing the vectors in a list, then loop from 2 to length of list and apply combn on the list and get the colSums

lst1 <- list(A, B, C)
lapply(2:length(lst1), function(i) do.call(rbind, combn(lst1, i, 
        function(x) Reduce(`+`, x), simplify = FALSE)))

Also, for better efficiency, may be use comb_n from Rfast

data

lst1  <- list(A = 1:5, B = 6:10, C = 2:6)

Upvotes: 2

J.P. Le Cavalier
J.P. Le Cavalier

Reputation: 1345

Let's say we have the following 3 vectors x, y, and z

set.seed(20191206)

(x <- runif(10))
##   [1] 0.6735252 0.3566995 0.3849840 0.5937276 0.8116468 0.5734249 0.7149757 0.1567160 0.1757700 0.7636036

(y <- runif(10))
##   [1] 0.2748723077 0.4907480855 0.0004572209 0.5516090256 0.2216921777 0.8455295560 0.4692991707 0.3110730459 0.2288788261
##  [10] 0.3893694628

(z <- runif(10))
##   [1] 0.91941434 0.85875047 0.82157849 0.69223918 0.84506022 0.14031886 0.65145257 0.34698708 0.02684135 0.14984516

By appliying the following code, we get

apply(matrix(c(x, y, z), ncol=3), 1, function(x){unlist(lapply(c(1:3), function(y){combn(x, y, sum)}))})
##            [,1]      [,2]         [,3]      [,4]      [,5]      [,6]      [,7]      [,8]       [,9]     [,10]
##  [1,] 0.6735252 0.3566995 0.3849839806 0.5937276 0.8116468 0.5734249 0.7149757 0.1567160 0.17577005 0.7636036
##  [2,] 0.2748723 0.4907481 0.0004572209 0.5516090 0.2216922 0.8455296 0.4692992 0.3110730 0.22887883 0.3893695
##  [3,] 0.9194143 0.8587505 0.8215784931 0.6922392 0.8450602 0.1403189 0.6514526 0.3469871 0.02684135 0.1498452
##  [4,] 0.9483975 0.8474476 0.3854412015 1.1453367 1.0333390 1.4189544 1.1842749 0.4677890 0.40464887 1.1529731
##  [5,] 1.5929395 1.2154500 1.2065624737 1.2859668 1.6567070 0.7137437 1.3664283 0.5037031 0.20261140 0.9134488
##  [6,] 1.1942866 1.3494986 0.8220357141 1.2438482 1.0667524 0.9858484 1.1207517 0.6580601 0.25572018 0.5392146
##  [7,] 1.8678118 1.7061981 1.2070196946 1.8375758 1.8783992 1.5592733 1.8357275 0.8147761 0.43149023 1.3028182

where

  • row-1 = x
  • row-2 = y
  • row-3 = z
  • row-4 = x+y
  • row-5 = y+z
  • row-6 = x+z
  • row-7 = x+y+z

You can now generalize the above example to your specific problem.

I hope this code snippet is of any help for you!

Upvotes: 1

Related Questions