2016-08-05 45 views
8

值I具有的字母数(可变)数量的组合的列表,例如这样的:ř填补取决于组合

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 

对于每个组合,我试图填补根据位置元素,成与矢量数量相同长度的矢量。所以,我想获得:

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

现在我用循环替换阵列I,J,但由于所有值的每个元素都试图“2”,必须有这样做更有效的方式? 非常感谢!

回答

9

刚刚从vec,你可以做启动...

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 

有一个空行的空集,因为有可能应该是。

从这里开始......

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是缓慢的,但以后可以搞掂,如果它很重要。

+2

'comb_cases'非常聪明 –

6

这本质上仍然是一个循环,但它可能是更容易理解:

sapply(lapply(comb, match, vec), function(x) paste(replace(numeric(3), x, 2), collapse="")) 
#[1] "200" "020" "002" "220" "202" "022" "222" 
5

这是一个不同的选项与factor

sapply(comb, function(x) paste(table(factor(x, levels = vec))*2, collapse="")) 
#[1] "200" "020" "002" "220" "202" "022" "222" 

我们也可以利用的FUN参数combn

unlist(sapply(seq_along(vec), function(x) combn(vec, x, 
    FUN = function(y) paste(table(factor(y, levels= vec))*2, collapse='')))) 
#[1] "200" "020" "002" "220" "202" "022" "222" 

或稍微紧凑型

unlist(lapply(seq_along(vec), function(x) combn(vec, x, FUN = 
     function(y) paste((vec %in% y)*2, collapse="")))) 
#[1] "200" "020" "002" "220" "202" "022" "222"