expand.grid的非冗余版本

expand.grid的非冗余版本,r,combinations,R,Combinations,R函数expand.grid返回所提供参数元素之间的所有可能组合。e、 g > 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

R
函数
expand.grid
返回所提供参数元素之间的所有可能组合。e、 g

> 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
Var1
的一个元素和
var2
的另一个元素之间的一个(常规)唯一组合


解决方案需要从两个向量中产生成对的元素(即,每个输入向量中有一个元素,以便可以应用于两个以上的输入)

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

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"
如果不需要重复元素(例如,
aa
),也可以对两个向量的唯一元素使用
combn


vals如果两个向量相同,则
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)

在base 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))
}
expand.grid.unique尝试:


factors之前的答案缺乏获得特定结果的方法,即保留自我配对,但删除不同顺序的配对。gtools包有两个功能用于这些目的,
组合
排列

  • 当顺序不重要时,它是一个组合
  • 当顺序确实重要时,它是一种排列
在这两种情况下,我们都可以决定是否允许重复,相应地,这两个函数都有一个
repeats.allowed
参数,产生4个组合(美妙的meta!)。每一个都值得一看。为了便于理解,我将向量简化为单个字母

重复排列 最广泛的选择是允许自我关系和不同顺序的选择:

> 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的用户

有两种方法可以限制这一点: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" 
> 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个选择。该值的公式为
(r+n-1)/(r!*(n-1)!
(2+3-1)/(2!*(3-1)!)=4!/(2*2!)=24/4=6

无重复排列 相反,如果我们不允许重复,我们使用:

> 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" 
> 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/(右)
(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

您可以使用“大于”操作来过滤冗余组合。这适用于数字和字符向量

> grid <- expand.grid(c("aa", "ab", "cc"), c("aa", "ab", "cc"), stringsAsFactors = F)
> grid[grid$Var1 >= grid$Var2, ]
  Var1 Var2
1   aa   aa
2   ab   aa
3   cc   aa
5   ab   ab
6   cc   ab
9   cc   cc
>网格网格[grid$Var1>=grid$Var2,]
Var1 Var2
1 aa aa
2 ab aa
3毫升aa
5 ab ab
6毫升ab
9毫升

这不应该太慢你的代码。如果您要扩展包含较大元素的向量(例如,两个数据帧列表),我建议使用引用原始向量的数字索引。

这是一个非常难看的版本,适用于我处理类似问题

AHP_code = letters[1:10] 
 temp. <- expand.grid(AHP_code, AHP_code, stringsAsFactors = FALSE)
  temp. <- temp.[temp.$Var1 != temp.$Var2, ] # remove AA, BB, CC, etc. 
  temp.$combo <- NA 
  for(i in 1:nrow(temp.)){  # vectorizing this gave me weird results, loop worked fine. 
    temp.$combo[i] <- paste0(sort(as.character(temp.[i, 1:2])), collapse = "")
  }
  temp. <- temp.[!duplicated(temp.$combo),]
  temp. 

AHP\u code=字母[1:10]

临时雇员哦,不,谢谢。我需要将它们分开以传递给其他函数。前一个是完美的!我实际上意识到我不需要
aaaa
bbbb
cc
。因此,如果您重新编辑,我将接受:-)我注意到repeats.allowed也会删除实际上不重复的自对,例如(“aa”,“aa”)。这个函数缺少一个中间方法。我注意到它缺少一个方法来包含自我关系,但不包括重复的关系。例如(“aa”、“aa”)不是重复项,因为它只出现在屏幕上。在某些情况下,一个人也想要自我关系,但不是重复的。这不是同一个问题吗?我不这么认为。它从单个向量询问元素。接受的答案还提供了一种从多个输入元素(2个或更多)生成组合的方法
> grid <- expand.grid(c("aa", "ab", "cc"), c("aa", "ab", "cc"), stringsAsFactors = F)
> grid[grid$Var1 >= grid$Var2, ]
  Var1 Var2
1   aa   aa
2   ab   aa
3   cc   aa
5   ab   ab
6   cc   ab
9   cc   cc
AHP_code = letters[1:10] 
 temp. <- expand.grid(AHP_code, AHP_code, stringsAsFactors = FALSE)
  temp. <- temp.[temp.$Var1 != temp.$Var2, ] # remove AA, BB, CC, etc. 
  temp.$combo <- NA 
  for(i in 1:nrow(temp.)){  # vectorizing this gave me weird results, loop worked fine. 
    temp.$combo[i] <- paste0(sort(as.character(temp.[i, 1:2])), collapse = "")
  }
  temp. <- temp.[!duplicated(temp.$combo),]
  temp.