I am trying to find all possible unique combinations in R. It seems that there have been a lot of similar questions asked, but I was not able to find the same one.
My question is to find combinations of m number of elements from vector x, but m could be larger than x. For example, pick 3 elements from letters[1:2], which hopefully can return:
combn(letters[1:2],3)
[,1] [,2] [,3] [,4]
[1,] "a" "a" "a" "b"
[2,] "a" "a" "b" "b"
[3,] "a" "b" "b" "b"
But instead error in combn function n < m. There are similar functions including gtools:permutations, expand.grid.
Apologize again if someone asked the same questions previously, but I did not catch it. Thanks.
There are a few packages specifically built for this. The basic premise is that we need combinations with repetition of length m
where m
could be larger than the input vector. We start with the classic gtools
:
library(gtools)
combinations(2, 3, letters[1:2], repeats.allowed = TRUE)
[,1] [,2] [,3]
[1,] "a" "a" "a"
[2,] "a" "a" "b"
[3,] "a" "b" "b"
[4,] "b" "b" "b"
And then there is arrangements
which is a replacement for iterpc
(the package linked by @Gregor in the comments above):
library(arrangements)
arrangements::combinations(2, 3, letters[1:2], replace = TRUE)
[,1] [,2] [,3]
[1,] "a" "a" "a"
[2,] "a" "a" "b"
[3,] "a" "b" "b"
[4,] "b" "b" "b"
And finally there is RcppAlgos
, which I authored:
library(RcppAlgos)
comboGeneral(letters[1:2], 3, TRUE)
[,1] [,2] [,3]
[1,] "a" "a" "a"
[2,] "a" "a" "b"
[3,] "a" "b" "b"
[4,] "b" "b" "b"
combn
is an awesome function that ships as one of the base packages with R
, however one of its shortcomings is that it doesn't allow repetition (which is what is required here). I wrote a pretty comprehensive overview for problems exactly like this one that can be found here: A Walk Through a Slice of Combinatorics in R .
combn1=function(x,m){
n=ifelse(length(x)==1,ifelse(is.numeric(x),x,1),length(x))
if(n>=m) return(combn(x,m))
a=do.call(expand.grid, rep(list(x),m))
b=t(unique(t(apply(a,1,sort))))
`dimnames<-`(b,NULL)
}
combn1(letters[1],3)
[,1]
[1,] "a"
[2,] "a"
[3,] "a"
> combn1(letters[1:2],3)
[,1] [,2] [,3] [,4]
[1,] "a" "a" "a" "b"
[2,] "a" "a" "b" "b"
[3,] "a" "b" "b" "b"
> combn1(letters[1:3],3)
[,1]
[1,] "a"
[2,] "b"
[3,] "c"
This maybe worked, which list all the unique combinations without repeat
> v1 = letters[1:4]
> v1
[1] "a" "b" "c" "d"
> do.call("c",lapply(seq_along(v1),function(i) utils::combn(v1,i,FUN=list)))
[[1]]
[1] "a"
[[2]]
[1] "b"
[[3]]
[1] "c"
[[4]]
[1] "d"
[[5]]
[1] "a" "b"
[[6]]
[1] "a" "c"
[[7]]
[1] "a" "d"
[[8]]
[1] "b" "c"
[[9]]
[1] "b" "d"
[[10]]
[1] "c" "d"
[[11]]
[1] "a" "b" "c"
[[12]]
[1] "a" "b" "d"
[[13]]
[1] "a" "c" "d"
[[14]]
[1] "b" "c" "d"
[[15]]
[1] "a" "b" "c" "d"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.