返回值的所有可能组合

标签 r combinations combinatorics

我有下表:

Group Value
----  ----
1     A
1     B
1     C
1     D
2     A
2     B
2     C

对于两组中的每一组,我想返回所有可能的值组合。对于第 1 组,例如,可能的组合是 (A,B)、(A,C)、(A,D)、(B,C)、(B,D)、(C,D)、(A, B、C)、(B、D、C)、(D、C、A)、(C、A、B)。类似地,对于第 2 组,它是 (A,B)、(A,C)、(B,C) [注:我不想考虑 (1) 只有一个值的组合,(2) 与所有值和 (3) 没有值的组合。因此,对于 n 个不同的值,我有 2^(n)-n-1-1 种组合]。

我想在附加列“Combi”的帮助下列出所有这些组合。此列对不同的组合进行连续编号。

Group Combi Value
----  ----  ----
1     1     A
1     1     B
1     2     A
1     2     C
1     3     A
1     3     D
1     4     B
1     4     C
1     5     B
1     5     D
1     6     C
1     6     C
1     7     A
1     7     B
1     7     C
1     8     B
1     8     C
1     8     D
1     9     C
1     9     D
1     9     A
1     10    D
1     10    A
1     10    B
2     11    A
2     11    B
2     12    A
2     12    C
2     13    B
2     13    C

我如何在 R 中执行此操作?

最佳答案

这是一个通用的 tidyverse 解决方案,应该适用于包含 3 个以上项目的值集。

想法是使用 combn(m = 2 然后 3 等)并将输出格式化为不同 Grouptibblem 值。从那里我们可以使用 tidyverse 函数 map_dfrunnest。最后,由于我们有多个 id 而不是一个,我们构建了一个唯一 id 表,构建了唯一的 combi id 并将其连接回我们的结果。

# convenience fonction to store combinations in a long format
combi_as_tibble <- function(n,values) combn(values,n) %>%
  {tibble(id = rep(seq(ncol(.)),each=nrow(.)),Value=c(.))}    
combi_as_tibble(2,letters[1:3]) # example
# # A tibble: 6 x 2
#      id Value
#   <chr> <chr>
# 1     1     a
# 2     1     b
# 3     2     a
# 4     2     c
# 5     3     b
# 6     3     c


df1 %>% group_by(Group) %>%
  summarize(combis = list(
    map_dfr(2:(length(unique(Value))-1),combi_as_tibble,Value,.id="id2")
  ))     %>% # by Group, build a long tibble with all combinations
  unnest %>% # unnest to get a long unnested table
  left_join(.,select(.,Group,id2,id) %>% distinct %>% mutate(combi=row_number())
  )      %>% # build combi ids
  select(Group,Value,combi) %>%
  as.data.frame

#    Group Value combi
# 1      1     A     1
# 2      1     B     1
# 3      1     A     2
# 4      1     C     2
# 5      1     A     3
# 6      1     D     3
# 7      1     B     4
# 8      1     C     4
# 9      1     B     5
# 10     1     D     5
# 11     1     C     6
# 12     1     D     6
# 13     1     A     7
# 14     1     B     7
# 15     1     C     7
# 16     1     A     8
# 17     1     B     8
# 18     1     D     8
# 19     1     A     9
# 20     1     C     9
# 21     1     D     9
# 22     1     B    10
# 23     1     C    10
# 24     1     D    10
# 25     2     A    11
# 26     2     B    11
# 27     2     A    12
# 28     2     C    12
# 29     2     B    13
# 30     2     C    13

数据

df1 <- read.table(text="Group Value
1     A
1     B
1     C
1     D
2     A
2     B
2     C",h=T,strin=F)

关于返回值的所有可能组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48863573/

相关文章:

r - 提取列名并与另一列匹配

r - 如何使用 apply 而不是 for 循环来实现 stringMatch 函数?

python - Python 中的 4 和算法

当 output_file 路径为绝对路径时,rmarkdown::render 会导致错误

r - 为什么 R 3.6.0 在评估表达式 ("Dogs"< "cats"时返回 FALSE )?

python - 根据喜好将一群人分成两半

java - 查找字符串 HashSet 的组合

python - 在 python 中使用组合来处理非常大的序列

algorithm - 将 n 写为 k 个数字之和的方法数,每个部分都有限制

algorithm - 计算 $2n$ 元素可以配对多少种方式的更快方法?