R create vector with all possible combinations of elements of another vector (variants: negated and non-negated)

Viewed 44

Variant 1

I have a vector with n elements - let's say three for the sake of this example: elements <- c("A", "B", "C"). I would like to create a new vector containing all combinations of these n elements - regardless permutations but with the possibility to take 1 to n of them, such that I obtain: combinations <- c("A", "B", "C", "AB", "AC", "BC", "ABC"). Would there be an automatic way to do this (and with any number of elements of course)?

Variant 2

I would like to do the same operation, but with elements also having the possibility to be negated. Such that I obtain: combinations <- c("A", "B", "C", "~A", "~B", "~C", "AB", "AC", "BC", "~AB", "A~B", "~AC", "A~C", "~BC", "B~C", "~A~B", "~A~C", "~B~C", "ABC", "~ABC", "A~BC", "AB~C", "~A~BC", "~AB~C", "A~B~C", "~A~B~C"). Again, I would like this to be automatic (and with any number of elements).

Could someone help me?

2 Answers

We may use combn

unlist(lapply(seq_along(elements), \(i) if(i > 1) 
  combn(elements, i, FUN = paste, collapse = "") else elements))

-output

[1] "A"   "B"   "C"   "AB"  "AC"  "BC"  "ABC"

For the second case, may be

lst1 <- lapply(seq_along(elements), \(i) if(i > 1) 
   combn(elements, i, FUN = paste, collapse = "~") else elements)
lst2 <- lapply(seq_along(elements), \(i) if(i > 1)
  combn(elements, i, FUN = paste, collapse = "") else elements)
 unlist(Map(c, lst1, lapply(lst1, \(x) paste0("~", x)),
  lapply(lst2, \(x) paste0("~", x))))

I managed to solve the second variant. Probably not the shortest, nor the most elegant version but it works. The idea is to first create a grid based on the three values every element i can take [i, ~i, ""], to concatenate the three values in a new column, to remove the last row because the absence of all elements is not possible, and to make it a list:

my_vector <- vector(mode="numeric")

for(i in conditions){
  x <- c(paste("~",i, sep=""), i, "")
  my_vector <- cbind(my_vector, x)
}

my_vector <- as.data.frame(my_vector)
comb.df <- expand.grid(my_vector)
col.names <- rep(paste(LETTERS, "col", sep =""), length.out=ncol(comb.df))
colnames(comb.df) <- col.names 
comb.df <- unite(comb.df, "all", 1:ncol(comb.df), sep="", remove = T)
combinations <- comb.df[!apply(comb.df == "", 1, all), ]    
combinations
Related