1

I have a data set with 5 different variables (e.g., a, b, c, d, and e). I want to have simple code (preferably with the tidyverse) that allows me to take the mean for each possible combination of the variables. For example, the mean of "ab", "ac", ..., all the way to "abcde". Is there a simple way of doing this?

All I've tried is manually creating the code for each variable. However, it seems like something like a loop would be more appropriate.

For example, if my data looked like this:

a <- rnorm(10, 0, 1)
b <- rnorm(10, 0, 1)
c <- rnorm(10, 0, 1)
d <- rnorm(10, 0, 1)
e <- rnorm(10, 0, 1)
data <- cbind.data.frame(a,b,c,d,e)

I want the data to look like the output as if I had done this for each combination of a, b, c, d, e:

data$ab <- (data$a + data$b)/2
.
.
.
data$abcde <- (data$a + data$b + data$c + data$d + data$e)/5
user2917781
  • 273
  • 2
  • 10

1 Answers1

3

You can generate the combinations with combn and compute means for each combination with rowMeans:

all.combs <- unlist(lapply(2:ncol(data), function(x) combn(colnames(data), x, simplify = F)), recursive = F)

m <- lapply(all.combs, function(x) rowMeans(data[, x]))
data[sapply(all.combs, paste0, collapse = '')] <- m


# example output
data[, c('ab', 'ac', 'abcde')]
#            ab          ac       abcde
# 1   0.9145668 -0.15422891  0.46534449
# 2   1.0593771  0.36834739 -0.28974715
# 3   0.8504790  0.37486041  0.58032864
# 4   0.8392725  1.67687954  0.62420232
# 5  -0.1612623 -0.31145576  0.06580884
# 6  -0.6140748 -0.05931374 -0.01082605
# 7   0.4424551  0.75504165  0.53706206
# 8  -0.1202238 -0.02772524  0.43865296
# 9  -1.3020701 -0.18290837 -0.61781512
# 10 -0.7414824 -1.56409902 -1.12516693
mt1022
  • 16,834
  • 5
  • 48
  • 71
  • This definitely gets the job done. If I can figure out a solution using the tidyverse, I'll post it. – user2917781 Jun 02 '19 at 13:11
  • @user2917781 something like: `map(1:ncol(df), ~ combn(colnames(df), ., simplify = FALSE)) %>% flatten()` should get you going in the right direction. – JasonAizkalns Jun 02 '19 at 13:12