R填充值取决于组合

use*_*102 8 arrays binary combinations loops r

我有一个组合的几个(可变)字母的列表,例如:

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
Run Code Online (Sandbox Code Playgroud)

对于每个组合,我试图根据位置填充元素到与向量数量相同的向量中.所以我想得到:

a =   200
b =   020
c =   002
ab =  220
ac =  202
bc =  022
abc = 222
Run Code Online (Sandbox Code Playgroud)

现在我正在尝试使用循环替换数组i,j的每个元素但是因为所有值都是"2",所以必须有更有效的方法来执行此操作?非常感谢!!

Fra*_*ank 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
Run Code Online (Sandbox Code Playgroud)

空集有一个空行,因为可能应该有.

从这里...

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"
Run Code Online (Sandbox Code Playgroud)

ifelse 很慢,但如果重要的话可以在以后解决.

  • `comb_cases`在那里非常聪明 (2认同)

the*_*ail 6

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

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


akr*_*run 5

这是一个不同的选项 factor

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

我们也可以利用这个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"
Run Code Online (Sandbox Code Playgroud)

或者是稍微紧凑的版本

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"
Run Code Online (Sandbox Code Playgroud)