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

时间:2018-08-20 21:38:50

标签: r

这是我的载体:

vec <- c("A", "B", "C")

而且,我想获得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)

我尝试了以下操作:

#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))

但无法获得所需的结果。您能否提出解决方案,尤其是在vec中使用不同数量的元素?

2 个答案:

答案 0 :(得分: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

如果您想排除全0的情况,建议您事后进行。这会给出所有 8 组合。


感谢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

对时间好奇吗?在这个小例子中,base解决方案的速度提高了约6倍,尽管两者都足够快,没关系。在更长的输入中,这个比例似乎保持不变,vec = LETTERS[1:10]使我的速度提高了约6倍。与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

答案 1 :(得分:0)

base R解决方案更好,但这是用于生成笛卡尔的sqldf解决方案

x_vec <- data.frame( mycol = c("A", "B", "C"), stringsAsFactors = F)

sqldf::sqldf("Select a.mycol mycol1, b.mycol mycol2, c.mycol mycol3  From x_vec a, x_vec b, x_vec c") %>% 
  mutate(myid = 1:n()) %>% 
  reshape2::melt(id.vars = "myid") %>%
  mutate(variable = 1) %>%  unique() %>% 
  reshape2::dcast(myid~value, fill = 0, value.var = "variable") %>% 
  select(-myid) %>% unique()