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

时间:2017-03-21 14:09:28

标签: r 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

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

2 个答案:

答案 0 :(得分:3)

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

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而不是数字向量:

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.这将为您提供42个总和为25的组合。

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:

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

答案 1 :(得分:1)

以下内容适用于固定长度;对于所有具有可变长度的组合,需要更高级的东西(编辑:参见@ 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