Search code examples
rcombn

List of all combinations of a minimum value using combn


Here is my data:

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

How would I find all combinations of column 3 that are greater than 25? I am struggling how to use the combn function as the help function doesn't seem too intuitive.


Solution

  • If you want a non-loop version:

    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
    

    EDIT To return rownames instead of the number vector:

    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 To get the elements of the list that match the minimum sum, in this case 25. This gives you the 42 combinations that sum to 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)))]
    

    To get the corresponding rownames as asked before:

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