2013-06-18 41 views
25

R函数expand.grid返回所提供参数元素之间的所有可能组合。例如expand.grid的非冗余版本

> expand.grid(c("aa", "ab", "cc"), c("aa", "ab", "cc")) 
    Var1 Var2 
1 aa aa 
2 ab aa 
3 cc aa 
4 aa ab 
5 ab ab 
6 cc ab 
7 aa cc 
8 ab cc 
9 cc cc 

你知道一个有效的办法直接获取(所以没有expand.grid之后的任何行比较)提供的矢量之间只有“唯一”的组合?输出将是

Var1 Var2 
1 aa aa 
2 ab aa 
3 cc aa 
5 ab ab 
6 cc ab 
9 cc cc 

编辑每个元素的结合本身可能从答案最终被丢弃。尽管(数学上)aa aa将是Var1的一个元素与另一个var2之间的一个(常规)唯一组合,但我实际上并不需要它。

该解决方案需要来自两个矢量产生对元件(即,一个来自每个输入矢量的 - 使得它可以被应用于多于2个输入)

+0

不是[this](https://stackoverflow.com/questions/12245213/how-to-generate-all-possible-combinations-of-vectors-without-caring-for-order)只是同一个问题? – 5th

+0

[如何生成所有可能的矢量组合而不关心顺序?](https://stackoverflow.com/questions/12245213/how-to-generate-all-possible-combinations-of-vectors-without-关怀订购) – 5th

+0

我不这么认为。这个问题涉及到单个向量的元素。接受的答案也提供了一种方法来产生从多个输入元素(2或更多) – Michele

回答

23

如何使用outer?但是这个特殊的函数将它们连接成一个字符串。

outer(c("aa", "ab", "cc"), c("aa", "ab", "cc") , "paste") 
#  [,1] [,2] [,3] 
#[1,] "aa aa" "aa ab" "aa cc" 
#[2,] "ab aa" "ab ab" "ab cc" 
#[3,] "cc aa" "cc ab" "cc cc" 

您还可以使用combn在两个向量的独特元素,如果你不想重复元素(如aa aa

vals <- c(c("aa", "ab", "cc"), c("aa", "ab", "cc")) 
vals <- unique(vals) 
combn(vals , 2) 
#  [,1] [,2] [,3] 
#[1,] "aa" "aa" "ab" 
#[2,] "ab" "cc" "cc" 
+0

哦,不,谢谢。我需要它们分开传递给其他函数。以前是完美的!我实际上意识到我不需要'aa','bb bb'和'cc cc'。所以如果你重新编辑回来,我会接受它:-) – Michele

10

如果两个矢量是相同的,还有的combinations功能在gtools包:

library(gtools) 
combinations(n = 3, r = 2, v = c("aa", "ab", "cc"), repeats.allowed = TRUE) 

#  [,1] [,2] 
# [1,] "aa" "aa" 
# [2,] "aa" "ab" 
# [3,] "aa" "cc" 
# [4,] "ab" "ab" 
# [5,] "ab" "cc" 
# [6,] "cc" "cc" 

而且没有"aa" "aa"

combinations(n = 3, r = 2, v = c("aa", "ab", "cc"), repeats.allowed = FALSE) 
+0

+1我不知道gtools,谢谢! –

+0

我注意到repeats.allowed还删除了自身对(如“aa”,“aa”),这些自我对实际上没有重复。这个功能有一个缺失的中间路线。 – Deleet

9

在基R,则可以使用此:

expand.grid.unique <- function(x, y, include.equals=FALSE) 
{ 
    x <- unique(x) 

    y <- unique(y) 

    g <- function(i) 
    { 
     z <- setdiff(y, x[seq_len(i-include.equals)]) 

     if(length(z)) cbind(x[i], z, deparse.level=0) 
    } 

    do.call(rbind, lapply(seq_along(x), g)) 
} 

结果:

> x <- c("aa", "ab", "cc") 
> y <- c("aa", "ab", "cc") 

> expand.grid.unique(x, y) 
    [,1] [,2] 
[1,] "aa" "ab" 
[2,] "aa" "cc" 
[3,] "ab" "cc" 

> expand.grid.unique(x, y, include.equals=TRUE) 
    [,1] [,2] 
[1,] "aa" "aa" 
[2,] "aa" "ab" 
[3,] "aa" "cc" 
[4,] "ab" "ab" 
[5,] "ab" "cc" 
[6,] "cc" "cc" 
+0

很棒的功能,非常感谢。 – Stu

+0

我注意到它缺少一种方法来获得自我关系,但不是重复的。例如(“aa”,“aa”)不是重复的,只会出现。在某些情况下,也需要自我关系,但不是重复。 – Deleet

3

尝试:

factors <- c("a", "b", "c") 

all.combos <- t(combn(factors,2)) 

    [,1] [,2] 
[1,] "a" "b" 
[2,] "a" "c" 
[3,] "b" "c" 

这将不包括每个因子的重复(例如“a”“a”),但如果需要,您可以轻松添加这些内容。

dup.combos <- cbind(factors,factors) 

    factors factors 
[1,] "a"  "a"  
[2,] "b"  "b"  
[3,] "c"  "c" 

all.combos <- rbind(all.combos,dup.combos) 

    factors factors 
[1,] "a"  "b"  
[2,] "a"  "c"  
[3,] "b"  "c"  
[4,] "a"  "a"  
[5,] "b"  "b"  
[6,] "c"  "c" 
4

以前的答案是缺乏一种方式来获得一个特定的结果,即保持自我,但对不同的订单删除的。该包具有用于这些目的的两个功能,即combinationspermutationsAccording to this website

  • 当顺序无关紧要时,它是一个组合。
  • 当订单确实重要时,它是一个置换。

在这两种情况下,我们决定把的重复是否允许与否,相应地,这两个功能有repeats.allowed说法,得到4个组合(可口元!)。这是值得的每一个这些。为了便于理解,我将矢量简化为单个字母。

排列组合与重复

最广泛的选择是让这两个自我的关系,不同的排序选项:

> permutations(n = 3, r = 2, repeats.allowed = T, v = c("a", "b", "c")) 
     [,1] [,2] 
[1,] "a" "a" 
[2,] "a" "b" 
[3,] "a" "c" 
[4,] "b" "a" 
[5,] "b" "b" 
[6,] "b" "c" 
[7,] "c" "a" 
[8,] "c" "b" 
[9,] "c" "c" 

这给了我们9个选项。该值可以从简单公式n^r(即3^2=9)中找到。对于熟悉SQL的用户,这是the Cartesian product/join。有两种方法可以限制这种情况:1)消除自我关系(不允许重复),或者2)删除不同的有序选项(即组合)。

组合与重复

如果我们要删除不同的排序选项,我们使用:

> combinations(n = 3, r = 2, repeats.allowed = T, v = c("a", "b", "c")) 
    [,1] [,2] 
[1,] "a" "a" 
[2,] "a" "b" 
[3,] "a" "c" 
[4,] "b" "b" 
[5,] "b" "c" 
[6,] "c" "c" 

这给了我们6个选项。该值的公式为(r+n-1)!/(r!*(n-1)!),即(2+3-1)!/(2!*(3-1)!)=4!/(2*2!)=24/4=6

排列组合没有重复

相反,如果我们希望禁止重复,我们使用:

> permutations(n = 3, r = 2, repeats.allowed = F, v = c("a", "b", "c")) 
    [,1] [,2] 
[1,] "a" "b" 
[2,] "a" "c" 
[3,] "b" "a" 
[4,] "b" "c" 
[5,] "c" "a" 
[6,] "c" "b" 

这也为我们提供了6个选项,但不同的!选项的数量与上述相同,但这是巧合。该值可以从公式n!/(n-r)!,即(3*2*1)/(3-2)!=6/1!=6中找到。

组合,而无需重复

最重要的限制是,当我们想既不自我关系/重复或不同订购的选件,在这种情况下,我们使用:

> combinations(n = 3, r = 2, repeats.allowed = F, v = c("a", "b", "c")) 
    [,1] [,2] 
[1,] "a" "b" 
[2,] "a" "c" 
[3,] "b" "c" 

这给我们提供了三种选择。选项的数量可以从相当复杂的公式n!/(r!(n-r)!)3*2*1/(2*1*(3-2)!)=6/(2*1!)=6/2=3来计算。