可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This questions was asked previously but only for vectors with non-repeating elements. I was not able to find an easy solution to get all combinations from a vector with repeating elements. To illustrate I listed an example below.
x <- c('red', 'blue', 'green', 'red', 'green', 'red')
Vector x has 3 repeating elements for 'red' and 2 for 'green'. The expected outcome for all unique combinations would be like this.
# unique combinations with one element
'red'
'blue'
'green'
# unique combination with two elements
'red', 'blue' # same as 'blue','red'
'red', 'green'
'red', 'red'
'blue', 'green'
'green', 'green'
# unique combination with three elements
'red', 'blue', 'green'
'red', 'red', 'blue'
'red', 'red', 'green'
'red', 'red', 'red' # This is valid because there are three 'red's
'green', 'green', 'red'
'green', 'green', 'blue'
# more unique combinations with four, five, and six elements
回答1:
Use combn()
with lapply()
should do the trick.
x <- c('red', 'blue', 'green', 'red', 'green', 'red')
lapply(1:3, function(y) combn(x, y))
# [[1]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] "red" "blue" "green" "red" "green" "red"
# [[2]]
# [,1] [,2] [,3] [,4] [,5] [,6] ...
# [1,] "red" "red" "red" "red" "red" "blue" ...
# [2,] "blue" "green" "red" "green" "red" "green" ...
# [[3]]
# [,1] [,2] [,3] [,4] [,5] [,6] ...
# [1,] "red" "red" "red" "red" "red" "red" ...
# [2,] "blue" "blue" "blue" "blue" "green" "green" ...
# [3,] "green" "red" "green" "red" "red" "green" ...
All unique combinations
lapply(cc, function(y)
y[,!duplicated(apply(y, 2, paste, collapse="."))]
)
[[1]]
[1] "red" "blue" "green"
[[2]]
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] "red" "red" "red" "blue" "blue" "green" "green"
[2,] "blue" "green" "red" "green" "red" "red" "green"
[[3]]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] ...
[1,] "red" "red" "red" "red" "red" "red" "blue" ...
[2,] "blue" "blue" "green" "green" "red" "red" "green" ...
[3,] "green" "red" "red" "green" "green" "red" "red" ...
Although strictly speaking those aren't all unique combinations, as some of them are permutations of each other.
Properly unique combinations
lapply(cc, function(y)
y[,!duplicated(apply(y, 2, function(z) paste(sort(z), collapse=".")))]
)
# [[1]]
# [1] "red" "blue" "green"
# [[2]]
# [,1] [,2] [,3] [,4] [,5]
# [1,] "red" "red" "red" "blue" "green"
# [2,] "blue" "green" "red" "green" "green"
# [[3]]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] "red" "red" "red" "red" "red" "blue"
# [2,] "blue" "blue" "green" "green" "red" "green"
# [3,] "green" "red" "red" "green" "red" "green"
回答2:
library(DescTools)
x <- c('red', 'blue', 'green', 'red', 'green', 'red')
allSets <- lapply(1:length(x), function(i){
unique(t(apply(CombSet(x,i,repl = F),1,sort)))
})
#[1]]
#[,1] [,2] [,3] [,4] [,5] [,6]
#[1,] "red" "blue" "green" "red" "green" "red"
##[[2]]
#[,1] [,2]
#[1,] "blue" "red"
#[2,] "green" "red"
#[3,] "red" "red"
#[4,] "blue" "green"
#[5,] "green" "green"
#[[3]]
#[,1] [,2] [,3]
#[1,] "blue" "green" "red"
#[2,] "blue" "red" "red"
#[3,] "green" "red" "red"
#[4,] "green" "green" "red"
#[5,] "red" "red" "red"
#[6,] "blue" "green" "green"
#[[4]]
#[,1] [,2] [,3] [,4]
#[1,] "blue" "green" "red" "red"
#[2,] "blue" "green" "green" "red"
#[3,] "blue" "red" "red" "red"
#[4,] "green" "green" "red" "red"
#[5,] "green" "red" "red" "red"
#[[5]]
#[,1] [,2] [,3] [,4] [,5]
#[1,] "blue" "green" "green" "red" "red"
#[2,] "blue" "green" "red" "red" "red"
#[3,] "green" "green" "red" "red" "red"
#[[6]]
#[,1] [,2] [,3] [,4] [,5] [,6]
#[1,] "blue" "green" "green" "red" "red" "red"
回答3:
library(arrangements)
combinations(c("red", "blue", "green"), k = 2, freq = c(3, 1, 2))
# [,1] [,2]
# [1,] "red" "red"
# [2,] "red" "blue"
# [3,] "red" "green"
# [4,] "blue" "green"
# [5,] "green" "green"
combinations(c("red", "blue", "green"), k = 3, freq = c(3, 1, 2))
# [,1] [,2] [,3]
# [1,] "red" "red" "red"
# [2,] "red" "red" "blue"
# [3,] "red" "red" "green"
# [4,] "red" "blue" "green"
# [5,] "red" "green" "green"
# [6,] "blue" "green" "green"
If you don't want to manually enter the frequencies:
x <- c('red', 'blue', 'green', 'red', 'green', 'red')
tx <- table(x)
combinations(names(tx), k = 2, freq = tx)
# [,1] [,2]
# [1,] "blue" "green"
# [2,] "blue" "red"
# [3,] "green" "green"
# [4,] "green" "red"
# [5,] "red" "red"
Or using RcppAlgos
:
library(RcppAlgos)
comboGeneral(names(tx), m=2, freqs = tx)
# [,1] [,2]
# [1,] "blue" "green"
# [2,] "blue" "red"
# [3,] "green" "green"
# [4,] "green" "red"
# [5,] "red" "red"