Non-redundant version of expand.grid

后端 未结 7 1276
北海茫月
北海茫月 2020-12-01 01:56

The R function expand.grid returns all possible combination between the elements of supplied parameters. e.g.

> expand.grid(c(\"         


        
相关标签:
7条回答
  • 2020-12-01 02:25

    In base R, you can use this:

    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))
    }
    

    Results:

    > 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 讨论(0)
  • 2020-12-01 02:29

    Try:

    factors <- c("a", "b", "c")
    
    all.combos <- t(combn(factors,2))
    
         [,1] [,2]
    [1,] "a"  "b" 
    [2,] "a"  "c" 
    [3,] "b"  "c"
    

    This will not include duplicates of each factor (e.g. "a" "a"), but you can add those on easily if needed.

    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" 
    
    0 讨论(0)
  • 2020-12-01 02:33

    If the two vectors are the same, there's the combinations function in the gtools package:

    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"
    

    And without "aa" "aa", etc.

    combinations(n = 3, r = 2, v = c("aa", "ab", "cc"), repeats.allowed = FALSE)
    
    0 讨论(0)
  • 2020-12-01 02:41

    here's a very ugly version that worked for me on a similar problem.

    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. 
    
    
    0 讨论(0)
  • 2020-12-01 02:43

    You can use a "greater than" operation to filter redundant combinations. This works with both numeric and character vectors.

    > 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
    

    This shouldn't slow down your code too much. If you're expanding vectors containing larger elements (e.g. two lists of dataframes), I recommend using numeric indices that refer to the original vectors.

    0 讨论(0)
  • 2020-12-01 02:44

    How about using outer? But this particular function concatenates them into one character string.

    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"
    

    You can also use combn on the unique elements of the two vectors if you don't want the repeating elements (e.g. 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 讨论(0)
提交回复
热议问题