Combinations by group in R

后端 未结 2 1402
谎友^
谎友^ 2020-12-11 04:55

I have a question about combinations by group.

My mini-sample looks like this:

sample <- data.frame(
  group=c(\"a\",\"a\",\"a\",\"a\",\"b\",\"b\"         


        
相关标签:
2条回答
  • 2020-12-11 05:38

    Here's a base R option using (1) split to create a list of data.frames per unique group-entry, (2) lapply to loop over each list element and compute the combinations using combn, (3) do.call(rbind, ...) to collect the list elements back into a single data.frame.

    do.call(rbind, lapply(split(sample, sample$group), {
       function(x) data.frame(group = x$group[1], t(combn(x$number, 2)))
    }))
    
    #    group X1 X2
    #a.1     a  1  2
    #a.2     a  1  3
    #a.3     a  1  2
    #a.4     a  2  3
    #a.5     a  2  2
    #a.6     a  3  2
    #b.1     b  4  5
    #b.2     b  4  3
    #b.3     b  5  3
    

    And a dplyr option:

    library(dplyr)
    sample %>% group_by(group) %>% do(data.frame(t(combn(.$number, 2))))
    #Source: local data frame [9 x 3]
    #Groups: group [2]
    #
    #   group    X1    X2
    #  (fctr) (dbl) (dbl)
    #1      a     1     2
    #2      a     1     3
    #3      a     1     2
    #4      a     2     3
    #5      a     2     2
    #6      a     3     2
    #7      b     4     5
    #8      b     4     3
    #9      b     5     3
    
    0 讨论(0)
  • 2020-12-11 05:40

    We can use a group by function with data.table

    library(data.table)
    setDT(sample)[, {i1 <-  combn(number, 2)
                       list(i1[1,], i1[2,]) }, by =  group]
    #    group V1 V2
    #1:     a  1  2
    #2:     a  1  3
    #3:     a  1  2
    #4:     a  2  3
    #5:     a  2  2
    #6:     a  3  2
    #7:     b  4  5
    #8:     b  4  3
    #9:     b  5  3
    

    Or a compact option would be

    setDT(sample)[, transpose(combn(number, 2, FUN = list)), by = group]
    

    Or using base R

     lst <- by(sample$number, sample$group, FUN = combn, m= 2)
     data.frame(group = rep(unique(as.character(sample$group)), 
                            sapply(lst, ncol)), t(do.call(cbind, lst)))
    
    0 讨论(0)
提交回复
热议问题