【问题标题】:List of all combinations of a minimum value using combn使用 combn 的最小值的所有组合的列表
【发布时间】:2017-03-22 19:40:50
【问题描述】:

这是我的数据:

      [,1] [,2] [,3]
[1,]    2    3    4
[2,]    2    3    5
[3,]    2    3    6
[4,]    2    4    5
[5,]    2    4    6
[6,]    2    4    2
[7,]    2    4    4
[8,]    2    4    9
[9,]    2    4    10
[10,]   2    4    3

如何找到大于 25 的第 3 列的所有组合?我正在努力如何使用 combn 功能,因为帮助功能似乎不太直观。

【问题讨论】:

  • 前两列是否有任何意义,即是否也应该考虑它们?
  • 还有,什么操作?求和?乘法?求幂?请扩展您的问题以包含更多详细信息以及您的预期输出。
  • 不需要考虑它们,尽管我将它们留在那里,因为稍后我将要分配行名称并使用结果向量引用它们。
  • 我想返回大于(或等于*)到 25 的第 3 列可能组合的向量列表。例如,一种组合是 [8,] [9,] 和 [ 3,]。输出需要是包含超过 25 个的所有可能组合的向量列表。我将重命名每一行 name1,....,name10 并且列表应该类似于 [[name1]] 并具有以下组合。因此,第 3 列的所有条目也可能是一个组合。

标签: r combn


【解决方案1】:

如果你想要一个非循环版本:

x <- read.table(text="2    3    4
2    3    5
2    3    6
2    4    5
2    4    6
2    4    2
2    4    4
2    4    9
2    4    10
2    4    3",stringsAsFactors=FALSE, header=FALSE)

res <- Map(combn, list(x[,3]), seq_along(x[,3]), simplify = FALSE)
unlist(res, recursive = FALSE)[lapply(unlist(res, recursive = FALSE),sum)>=25]

[[1]]
[1]  6  9 10

[[2]]
[1]  6  9 10

[[3]]
[1]  4  5  6 10
...
[[613]]
[1]  4  6  5  6  2  4  9 10  3

[[614]]
[1]  5  6  5  6  2  4  9 10  3

[[615]]
 [1]  4  5  6  5  6  2  4  9 10  3

编辑 要返回行名而不是​​数字向量:

rownames(x) <- paste0("row",1:10)
res <- list(Map(combn, list(x[,3]), seq_along(x[,3]), simplify = FALSE),
 Map(combn, list(rownames(x)), seq_along(rownames(x)), simplify = FALSE))
unlist(res[[2]], recursive = FALSE)[lapply(unlist(res[[1]], recursive = FALSE),sum)>=25]

[[1]]
[1] "row3" "row8" "row9"

[[2]]
[1] "row5" "row8" "row9"

[[3]]
[1] "row1" "row2" "row3" "row9"
...
[[613]]
[1] "row1"  "row3"  "row4"  "row5"  "row6"  "row7"  "row8"  "row9"  "row10"

[[614]]
[1] "row2"  "row3"  "row4"  "row5"  "row6"  "row7"  "row8"  "row9"  "row10"

[[615]]
 [1] "row1"  "row2"  "row3"  "row4"  "row5"  "row6"  "row7"  "row8"  "row9"  "row10"

EDIT2 获取列表中与最小总和匹配的元素,在本例中为 25。这为您提供了总和为 25 的 42 个组合。

res <- Map(combn, list(x[,3]), seq_along(x[,3]), simplify = FALSE)
res3 <- unlist(res, recursive = FALSE)[lapply(unlist(res, recursive = FALSE),sum)>=25]
res3[which(rapply(res3,sum)==min(rapply(res3,sum)))]

如前所述获取相应的行名:

rownames(x) <- paste0("row",1:10)
res4 <- list(Map(combn, list(x[,3]), seq_along(x[,3]), simplify = FALSE),
            Map(combn, list(rownames(x)), seq_along(rownames(x)), simplify = FALSE))
unlist(res4[[2]], recursive = FALSE)[lapply(unlist(res4[[1]], recursive = FALSE),sum)>=25][which(rapply(res3,sum)==min(rapply(res3,sum)))]

【讨论】:

  • 这比我的要好,应该是公认的答案(赞成)。我相应地编辑了我的答案;我想他很快就会用你的作为接受的答案......
  • 感谢两位的帮助。另一个快速的问题,因为你一直很有帮助,对于结果向量,我将如何返回行名而不是​​向量值?我还没有添加名称,但我正要添加。
  • 我有最后一个问题(我保证!),目前我有很多不太有用的组合,因为我对满足 >25 的最低标准的组合感兴趣,所以一旦向量值的总和达到 25,那么我希望向量“中断”以删除不必要的向量。例如,如果第 3 列中的 4 个值等于 26,则无需继续添加向量值。我仍然希望列表中的所有可能组合具有符合此条件的行名。
  • 太棒了——非常感谢。我尝试在 for 循环中使用 for 循环,但尝试删除每个单独列表的元素时事情变得一团糟。
【解决方案2】:

以下内容应适用于固定长度;对于具有可变长度的所有组合,需要更高级的东西(编辑:请参阅@PLapointe 的帖子(应该是公认的答案)或只是一个简单的循环):

x <- c(4, 5, 6, 5, 6, 2, 4, 9, 10, 3)

res <- combn(x, 3)

这将返回一个如下所示的矩阵(我只显示第一个条目):

    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23]
[1,]    4    4    4    4    4    4    4    4    4     4     4     4     4     4     4     4     4     4     4     4     4     4     4
[2,]    5    5    5    5    5    5    5    5    6     6     6     6     6     6     6     5     5     5     5     5     5     6     6
[3,]    6    5    6    2    4    9   10    3    5     6     2     4     9    10     3     6     2     4     9    10     3     2     4

然后,您可以从那里选择列总和大于阈值的组合:

res[, colSums(res) >= 25]

这将给

    [,1] [,2]
[1,]    6    6
[2,]    9    9
[3,]   10   10

由于您现在有重复的条目(不确定它们是否需要),您可以简单地执行以下操作(或简单的循环):

res2 <- combn(unique(x), 3)

res2[, colSums(res2) >= 25]

然后返回

[1]  6  9 10

【讨论】:

  • 我可以用 for 循环重复其他组合,还是单独做?
  • @Aesler:一个可以在 1 和 length(x) 之间运行的循环可能会起作用。但我想还有比这更聪明的解决方案。将调查...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 2011-12-09
相关资源
最近更新 更多