使用 combn 列出最小值的所有组合

List of all combinations of a minimum value using combn

这是我的数据:

      [,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

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

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

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

res <- combn(x, 3)

这将 return 看起来像这样的矩阵(我只显示第一个条目):

    [,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

从那里,您可以 select 列总和大于阈值的组合:

res[, colSums(res) >= 25]

这将给出

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

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

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

res2[, colSums(res2) >= 25]

然后 return

[1]  6  9 10

如果你想要非循环版本:

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

编辑 要 return rownames 而不是数字向量:

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