dplyr
makes this pretty straightforward:
library(dplyr)
inner_join(df %>% group_by(sym, a1) %>% summarise(b1.mean=mean(b1)),
df %>% group_by(sym, a2) %>% summarise(b2.mean=mean(b2)))
# Joining by: "sym"
# Source: local data frame [4 x 5]
# Groups: sym
#
# sym a1 b1.mean a2 b2.mean
# 1 a 1 2 2 2.5
# 2 a 2 3 2 2.5
# 3 b 1 6 1 6.5
# 4 b 2 7 1 6.5
If you want a single column for a
, and want to fill non-appearing combinations with NA
as in your example solution, then left_join
is an option:
left_join(df %>% group_by(sym, a=a1) %>% summarise(b1.mean=mean(b1)),
df %>% group_by(sym, a=a2) %>% summarise(b2.mean=mean(b2)),
by=c('sym', 'a'))
# Source: local data frame [4 x 4]
# Groups: sym
#
# sym a b1.mean b2.mean
# 1 a 1 2 NA
# 2 a 2 3 2.5
# 3 b 1 6 6.5
# 4 b 2 7 NA
Hat-tip to @beginnerR for reminding me about dplyr
join
operations.
EDIT
In response to the comments, if you have more than two groupings, and want to join all the resulting tables together, then here's one way to do this:
# Example data
set.seed(1)
(d <- data.frame(sym=sample(letters[1:4], 10, replace=T),
a1=sample(5, 10, replace=TRUE),
a2=sample(5, 10, replace=TRUE),
a3=sample(5, 10, replace=TRUE),
b1=runif(10), b2=runif(10), b3=runif(10)))
# sym a1 a2 a3 b1 b2 b3
# 1 b 2 5 3 0.8209463 0.47761962 0.91287592
# 2 b 1 2 3 0.6470602 0.86120948 0.29360337
# 3 c 4 4 3 0.7829328 0.43809711 0.45906573
# 4 d 2 1 1 0.5530363 0.24479728 0.33239467
# 5 a 4 2 5 0.5297196 0.07067905 0.65087047
# 6 d 3 2 4 0.7893562 0.09946616 0.25801678
# 7 d 4 1 4 0.0233312 0.31627171 0.47854525
# 8 c 5 2 1 0.4772301 0.51863426 0.76631067
# 9 c 2 5 4 0.7323137 0.66200508 0.08424691
# 10 a 4 2 3 0.6927316 0.40683019 0.87532133
L <- mapply(function(x, y) {
grpd <- eval(substitute(group_by(d, sym, a=x), list(x=as.name(x))))
eval(substitute(summarise(grpd, mean(y)), list(y=as.name(y))))
}, paste0('a', 1:3), paste0('b', 1:3), SIMPLIFY=FALSE)
Reduce(function(...) left_join(..., all=T), L)
# Source: local data frame [9 x 5]
# Groups: sym
#
# sym a mean(b1) mean(b2) mean(b3)
# 1 a 4 0.6112256 NA NA
# 2 b 1 0.6470602 NA NA
# 3 b 2 0.8209463 0.86120948 NA
# 4 c 2 0.7323137 0.51863426 NA
# 5 c 4 0.7829328 0.43809711 0.08424691
# 6 c 5 0.4772301 0.66200508 NA
# 7 d 2 0.5530363 0.09946616 NA
# 8 d 3 0.7893562 NA NA
# 9 d 4 0.0233312 NA 0.36828101