R:第1组和非第2组的汇总

时间:2014-03-13 21:38:10

标签: database r aggregate

我正在尝试创建两个数据集,一个使用以下代码按2组汇总数据:

x = rnorm(1:100)
g1 = sample(LETTERS[1:3], 100, replace = TRUE)
g2 = sample(LETTERS[24:26], 100, replace = TRUE)

aggregate(x, list(g1, g2), mean)

第二个需要按第一组而不是第二组汇总数据。

如果我们考虑前一个例子中的可能对:

A - X    B - X    C - X
A - Y    B - Y    C - Y
A - Z    B - Z    C - Z

第二个数据集应该将数据汇总为外群的平均值。

A - not X
A - not Y
A - not Z etc. 

有没有办法在R中操作聚合函数来实现这一目的? 或者我也认为可能存在可以用这种方式表示数据的虚拟变量,尽管我不确定它的外观。

我在这里找到了这个答案: R using aggregate to find a function (mean) for "all other"

我认为这表明每个配对的虚拟变量是必要的。但是,如果有人能够提供更好或更有效的方式,那么真正的数据集中会有很多配对。

提前致谢

1 个答案:

答案 0 :(得分:2)

首先让我们重复生成数据(使用set.seed):

# same as question but added set.seed for reproducibility
set.seed(123)
x = rnorm(1:100)
g1 = sample(LETTERS[1:3], 100, replace = TRUE)
g2 = sample(LETTERS[24:26], 100, replace = TRUE)

现在我们有两个使用聚合的解决方案:

1)ave

# x equals the sums over the groups and n equals the counts
ag = cbind(aggregate(x, list(g1, g2), sum),
            n = aggregate(x, list(g1, g2), length)[, 3])

ave.not <- function(x, g) ave(x, g, FUN = sum) - x
transform(ag, 
     x = NULL, # don't need x any more
     n = NULL, # don't need n any more
     mean = x/n, 
     mean.not = ave.not(x, Group.1) / ave.not(n, Group.1)
)

这给出了:

  Group.1 Group.2       mean     mean.not
1       A       X  0.3155084 -0.091898832
2       B       X -0.1789730  0.332544353
3       C       X  0.1976471  0.014282465
4       A       Y -0.3644116  0.236706489
5       B       Y  0.2452157  0.099240545
6       C       Y -0.1630036  0.179833987
7       A       Z  0.1579046 -0.009670734
8       B       Z  0.4392794  0.033121335
9       C       Z  0.1620209  0.033714943

要仔细检查均值下的第一个值,并在mean.not:

下检查
> mean(x[g1 == "A" & g2 == "X"])
[1] 0.3155084
> mean(x[g1 == "A" & g2 != "X"])
[1] -0.09189883

2)sapply 这是第二种方法,它给出了相同的答案:

ag <- aggregate(list(mean = x), list(g1, g2), mean)
f <- function(i) mean(x[g1 == ag$Group.1[i] & g2 != ag$Group.2[i]]))
ag$mean.not = sapply(1:nrow(ag), f)
ag

已修订根据海报评论进行修订,增加了第二种方法,并进行了一些小改进。