当前位置: 首页 > 知识库问答 >
问题:

返回所有可能的值组合

澹台啸
2023-03-14

我有下表:

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)、(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中我该怎么做?

共有3个答案

万俟沛
2023-03-14

这是一个基本解决方案。注释内联。

#for each length (not incl. 1 and number of unique values), create all possible combinations using combn
combiLs <- by(dat, dat$Group, function(x) {
    #number of elements to choose excl. 1 and all values
    idx <- seq_along(x$Value)[-c(1, nrow(x))]

    do.call(rbind, lapply(idx, function(m) {
        #for each number of elements, generate all combinations
        sets <- combn(x$Value, m, simplify=FALSE)

        #get OP's desired format
        combi <- rep(seq_along(sets), each=m)
        data.frame(
            Group=x$Group[1],
            Combi=paste(x$Group[1], combi, sep="."),
            Value=unlist(sets))
    }))
})

#final output
do.call(rbind, combiLs)

另一种可能的数据。表同时使用choose和combn实现:

res <- setDT(dat)[, {
        idx <- seq_along(Value)[-c(1, .N)]
        list(
            Set=paste0(Group[1], ".", unlist(lapply(idx, function(m) rep(seq_len(choose(.N, m)), each=m)))),
            Value=unlist(lapply(idx, function(m) as.vector(combn(Value, m))))
        )
    }, by=Group]

res[, Combi := unlist(Map(rep, x=seq_along(rle(Set)$values), each=rle(Set)$lengths))]

数据:

dat <- data.frame(Group=c(rep(1,4), rep(2,3)), Value=c("A","B","C","D","A","B","C"))
dat
长孙永思
2023-03-14

使用数据的可能解决方案。表:

library(data.table)
setDT(dat)[, .(Value = {n <- 2:(uniqueN(Value)-1);
                        unlist(lapply(n, function(x) combn(Value, x)))})
           , by = Group
           ][, Combi := cumsum(c(1, diff(match(Value, LETTERS)) < 0))][]

其中给出:

    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
汪辰阳
2023-03-14

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

其思想是使用combn(m=2然后3等)并将输出格式化为不同组和m值的tible。在那里,我们可以使用tidyverse函数map\u dfr和unest。最后,由于我们有多个id而不是一个id,我们构建了一个唯一id表,构建了唯一的组合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)
 类似资料:
  • 问题内容: 如何从数据库“ x”的同一列中返回值的所有可能组合的列表?例如,我有: 我想返回所有可能组合的列表,例如, .... 问题答案: 您尚未说明正在使用哪个RDBMS,或者您是否要将组合限制为仅包含集合的2个元素。 这是使用分层查询的Oracle答案: SQL小提琴 Oracle 11g R2架构设置 : 查询1 : 结果 : 查询2 : 结果 : 以及使用递归CTE的SQL Server

  • 我正在从第三方网站(家庭用电)检索JSON,根据我从网站请求的内容,返回的JSON可能是也可能不是数组。例如,如果我请求我的智能电表列表,我会得到这个(由于尺寸大,结果被截断): 其中 gwrcmd 是单个元素。 但是如果我要求过去半个小时的用电,我会得到这个: 看看 gwrcmd 现在是一个数组吗? 在我的Go应用程序中,我有一个类似这样的结构(再次,被截断,因为它持续了一段时间。“版本”下有更

  • 我正在等待(从USSD请求中)检索一个值,以便返回它(getUSSD):

  • 问题内容: 如果我做对了,确定何时编译源代码。 为了更好地支持多种操作系统,我对可能的功能很感兴趣。 当然,由于Go是开源的,因此可能存在无限的可能性。因此,我真正想要的是一个“通用列表”。 已知值为: 或或?我知道其中至少必须存在一个。 问题答案: 请注意,这些值在中定义。 随着围棋1.5(Q3 2015年),将成为 很多 更加完整。 见提交1eebb91由Minux马() :为 所有 通用架构

  • Random#nextLong()文档指出,此方法不会返回所有可能的长值: 返回此随机数生成器序列中的下一个伪随机、均匀分布的long值。的一般约定是伪随机生成并返回一个long值。方法由Random类实现,就好像通过: 因为类Random使用的种子只有48位,所以该算法不会返回所有可能的长值。 例如,数字是可生成的,但数字不是,即使它们唯一的区别是一个最低有效位,并且值本身是63位长。 有一种方