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中的按组组合的主要内容,如果未能解决你的问题,请参考以下文章