R中的按组组合

Posted

技术标签:

【中文标题】R中的按组组合【英文标题】:Combinations by group in R 【发布时间】:2016-11-08 08:41:47 【问题描述】:

我有一个关于按组组合的问题。

我的小样本如下所示:

sample <- data.frame(
  group=c("a","a","a","a","b","b","b"),
  number=c(1,2,3,2,4,5,3)
)

如果我将combn的功能应用于数据框,它会给出以下结果,即“数字”列下的所有值的组合,无论该值属于哪个组:

         [,1] [,2]
   [1,]    1    2
   [2,]    1    3
   [3,]    1    2
   [4,]    1    4
   [5,]    1    5
   [6,]    1    3
   [7,]    2    3
   [8,]    2    2
   [9,]    2    4
  [10,]    2    5
  [11,]    2    3
  [12,]    3    2
  [13,]    3    4
  [14,]    3    5
  [15,]    3    3
  [16,]    2    4
  [17,]    2    5
  [18,]    2    3
  [19,]    4    5
  [20,]    4    3
  [21,]    5    3

我用于上述结果的代码如下:

t(combn((sample$number), 2))

但是,我想获得组内的组合结果(即“a”、“b”)。因此,我想要得到的结果应该是这样的:

     [,1] [,2] [,3]
[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

除了组合之外,我还想获得指示的列 组。

【问题讨论】:

【参考方案1】:

我们可以通过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

或者一个紧凑的选择是

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

或者使用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)))

【讨论】:

levels(sample$group) 不是比unique(as.character(sample$group)) 更具可读性吗? @jiggunjer 可以,但也需要考虑顺序【参考方案2】:

这是一个基本 R 选项,使用 (1) split 创建每个唯一组条目的 data.frames 列表,(2) lapply 循环遍历每个列表元素并使用 combn 计算组合, (3) do.call(rbind, ...) 将列表元素收集回单个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

还有一个 dplyr 选项:

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

【讨论】:

以上是关于R中的按组组合的主要内容,如果未能解决你的问题,请参考以下文章

在 R 中按组转置数据

在 R 中按组创建组合

如何拆分-应用-组合 R 中的多个变量/列

用 R 中的多列按组计算百分比

R:根据上/下行中的值按组识别行

如何按组进行汇总并使用R中的dplyr获取总体数据集的摘要