Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R fill values depending on combination

I have a list of several (variable) number of letters in combination, for example this:

vec = c("a", "b", "c")
comb = unlist(lapply(1:length(vec), combn, x = vec, simplify = FALSE), recursive = FALSE) 
# this creates all the combinations of the vector I am interested in, i.e. for three letters:
# a b c ab ac bc abc

For each combination, I am trying to fill elements depending on the position, into vectors with the same length as the number of vectors. So I am trying to get:

a =   200
b =   020
c =   002
ab =  220
ac =  202
bc =  022
abc = 222

Right now I am trying with loops replacing each element of an array i,j but since all values are "2" there must be a more efficient way to do this? Thanks so much!!

like image 244
user971102 Avatar asked Aug 05 '16 04:08

user971102


2 Answers

Starting just from vec, you can do...

comb_cases = do.call(expand.grid, lapply(vec, function(x) c("", x)))

  Var1 Var2 Var3
1               
2    a          
3         b     
4    a    b     
5              c
6    a         c
7         b    c
8    a    b    c

There's a blank row for the empty set, as there probably should be.

From here...

comb = do.call(paste0, comb_cases)
# [1] ""    "a"   "b"   "ab"  "c"   "ac"  "bc"  "abc"

do.call(paste0, split( ifelse(nchar(as.matrix(comb_cases)), 2, 0), col(comb_cases)) )
# [1] "000" "200" "020" "220" "002" "202" "022" "222"

ifelse is slow, but that can be fixed up later if it matters.

like image 158
Frank Avatar answered Nov 03 '22 09:11

Frank


This is still essentially a loop, but it might be easier to understand:

sapply( lapply(comb, match, vec), function(x) paste(replace(numeric(3), x, 2), collapse=""))
#[1] "200" "020" "002" "220" "202" "022" "222"
like image 27
thelatemail Avatar answered Nov 03 '22 10:11

thelatemail