user2588829
user2588829

Reputation: 1583

All combinations of all sizes?

There are thousands of results on SO when I search for "vector combinations in R" but I can't find the answer to my question. Apologies if it is a duplicate:

I have a vector (1,2,3,4) and I want to find all combinations (n choose 2) to (n choose n). In other words, for this vector I would want:

1,2,3,4
1,2,3
1,2,4
1,3,4
2,3,4
1,2
1,3
1,4
2,3
2,4
3,4

And hopefully the code would be generalizable so that once I have a larger vector, it would be able to generalize.

Thanks!

Upvotes: 4

Views: 1882

Answers (2)

A5C1D2H2I1M1N2O1R2T1
A5C1D2H2I1M1N2O1R2T1

Reputation: 193507

Perhaps combn in conjunction with lapply might be helpful:

x <- 1:4
lapply(seq_along(x), function(y) combn(x, y))
# [[1]]
#      [,1] [,2] [,3] [,4]
# [1,]    1    2    3    4
# 
# [[2]]
#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    1    1    1    2    2    3
# [2,]    2    3    4    3    4    4
# 
# [[3]]
#      [,1] [,2] [,3] [,4]
# [1,]    1    1    1    2
# [2,]    2    2    3    3
# [3,]    3    4    4    4
# 
# [[4]]
#      [,1]
# [1,]    1
# [2,]    2
# [3,]    3
# [4,]    4

As @Roland points out, there is also a simplify argument to combn that when set to FALSE would create a nested list of individual column vectors rather than a matrix of all the results. For example, instead of list item [[3]] above being presented as a matrix, if you used lapply(seq_along(x), function(y) combn(x, y)), for the combinations of length 3 you would get:

# [[3]]
# [[3]][[1]]
# [1] 1 2 3
# 
# [[3]][[2]]
# [1] 1 2 4
# 
# [[3]][[3]]
# [1] 1 3 4
# 
# [[3]][[4]]
# [1] 2 3 4

Upvotes: 3

dickoa
dickoa

Reputation: 18437

If you prefer compact code

Map(combn, list(x), seq_along(x))
## [[1]]
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4

## [[2]]
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    1    1    2    2    3
## [2,]    2    3    4    3    4    4

## [[3]]
##      [,1] [,2] [,3] [,4]
## [1,]    1    1    1    2
## [2,]    2    2    3    3
## [3,]    3    4    4    4

## [[4]]
##      [,1]
## [1,]    1
## [2,]    2
## [3,]    3
## [4,]    4

To avoid repetition, you'll have to deal with nested list but you can simplify the result using unlist

res <- Map(combn, list(x), seq_along(x), simplify = FALSE)
unlist(res, recursive = FALSE)
## [[1]]
## [1] 1

## [[2]]
## [1] 2

## [[3]]
## [1] 3

## [[4]]
## [1] 4

## [[5]]
## [1] 1 2

## [[6]]
## [1] 1 3

## [[7]]
## [1] 1 4

## [[8]]
## [1] 2 3

## [[9]]
## [1] 2 4

## [[10]]
## [1] 3 4

## [[11]]
## [1] 1 2 3

## [[12]]
## [1] 1 2 4

## [[13]]
## [1] 1 3 4

## [[14]]
## [1] 2 3 4

## [[15]]
## [1] 1 2 3 4

Upvotes: 5

Related Questions