nCr中r的所有可能值的组合

Gee*_*eet 1 r

这是我的矢量:

vec <- c("A", "B", "C")
Run Code Online (Sandbox Code Playgroud)

而且,我希望获得vec的所有7种组合.

desired_output <- tibble( ~A, ~B, ~C,
                           1,  0,  0,
                           0,  1,  0,
                           0,  0,  1,
                           1,  1,  0,
                           1,  0,  1,
                           0,  1,  1,
                           1,  1,  1)
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法:

#install.packages("gtools")
library(gtools)
r <- c(1,2, 3)
df1 <- purrr::map(r, ~combinations(3,.x,vec))
df2 <- per %>% map_dfr(~data.frame(.x))
Run Code Online (Sandbox Code Playgroud)

但无法获得理想的结果.你能建议一个解决方案,特别是在vec中有不同数量的元素吗?

Gre*_*gor 8

基础解决方案

vec = c("A", "B", "C")
inp = rep(list(0:1), length(vec))
names(inp) = vec
do.call(expand.grid, inp)
#   A B C
# 1 0 0 0
# 2 1 0 0
# 3 0 1 0
# 4 1 1 0
# 5 0 0 1
# 6 1 0 1
# 7 0 1 1
# 8 1 1 1
Run Code Online (Sandbox Code Playgroud)

这给出了所有8种组合,如果你想要排除全0情况我建议事后做.


感谢Henrik的评论,这是一个purrr版本:

vec = c("A", "B", "C")
library(purrr)
pur = rerun(length(vec), 0:1)
names(pur) = vec
cross_df(pur)
# # A tibble: 8 x 3
#       A     B     C
#   <int> <int> <int>
# 1     0     0     0
# 2     1     0     0
# 3     0     1     0
# 4     1     1     0
# 5     0     0     1
# 6     1     0     1
# 7     0     1     1
# 8     1     1     1
Run Code Online (Sandbox Code Playgroud)

对时间感到好奇吗?在这个小例子中,base解决方案的速度提高了大约6倍,尽管两者都足够快,但这并不重要.在较长的输入上,这个比例似乎保持不变,我的速度提高了大约6倍vec = LETTERS[1:10].试过LETTERS[1:20]但厌倦了等待,所以我流产了.

vec = LETTERS[1:10]
microbenchmark(
  base = {
    inp = rep(list(0:1), length(vec));
    names(inp) = vec;
    do.call(expand.grid, inp);},
  purrr = {
    pur = rerun(length(vec), 0:1);
    names(pur) = vec;
    cross_df(pur);
  },
  times = 10L
)
# Unit: microseconds
#   expr       min        lq      mean     median        uq       max neval
#   base   789.668   868.152  1023.248   967.4635  1096.962  1388.559    10
#  purrr 45617.167 45960.080 59621.746 54181.5545 78944.986 87511.789    10
Run Code Online (Sandbox Code Playgroud)