Consider the following dataframe with 4 columns:
df = data.frame(A = rnorm(10), B = rnorm(10), C = rnorm(10), D = rnorm(10))
The columns A, B, C, D belong to different groups, and the groups are defined in a separate dataframe:
groups = data.frame(Class = c("A","B","C","D"), Group = c("G1", "G2", "G2", "G1"))
#> groups
#  Class Group
#1     A    G1
#2     B    G2
#3     C    G2
#4     D    G1
I would like to average elements of the columns that belong to the same group, and get something similar to:
#> res
#            G1          G2
#1  -0.30023039 -0.71075139
#2   0.53053443 -0.12397126
#3   0.21968567 -0.46916160
#4  -1.13775100 -0.61266026
#5   1.30388130 -0.28021734
#6   0.29275876 -0.03994522
#7  -0.09649998  0.59396983
#8   0.71334020 -0.29818438
#9  -0.29830924 -0.47094084
#10 -0.36102888 -0.40181739
where each cell of G1 is the mean of the relative cells of A and D, and each cell of G2 is the mean of the relative cells of B and C, etc.
I was able to achieve this result, but in a rather brute force way:
l = levels(groups$Group)
res = data.frame(matrix(nc = length(levels), nr = nrow(df)))
for(i in 1:length(l)) {
    df.sub = df[which(groups$Group == l[i])]
    res[,i] = apply(df.sub, 1, mean)
}
names(res) <- l
Is there a better way of doing this? In reality, I have more than 20 columns and more than 10 groups.
Thank you!
 
     
    