我正在尝试创建两个数据集,一个使用以下代码按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"
我认为这表明每个配对的虚拟变量是必要的。但是,如果有人能够提供更好或更有效的方式,那么真正的数据集中会有很多配对。
提前致谢
答案 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
已修订根据海报评论进行修订,增加了第二种方法,并进行了一些小改进。