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\"
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
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)))