R-添加新分组列时聚合函数的结果不同

时间:2018-07-03 17:38:10

标签: r aggregate-functions

我是R入门者,被困在里面,找不到解决方案。任何评论都受到高度赞赏。这是问题所在:

我有一个数据框df。 列将转换为char(属性)和num。 我想通过使用聚合函数来减少数据帧(不是dply的选择)。

当我使用进行聚合时

df_agg <- aggregate(df["AMOUNT"], df[c("ATTRIBUTE1")], sum)

我得到正确的结果。但我想按更多属性分组。例如,当添加更多属性时

df_agg <- aggregate(df["AMOUNT"], df[c("ATTRIBUTE1", "ATTRIBUTE2")], sum)

然后,聚集结果会改变。 Amount的总和不再等于第一个第一次聚集(或原始数据帧)的结果。

让任何人知道导致此行为的原因。

2 个答案:

答案 0 :(得分:1)

我的最佳猜测是您的某些分组列中缺少值。演示内置mtcars数据,该数据没有缺失值,一切都很好:

sum(mtcars$mpg)
# [1] 642.9
sum(aggregate(mtcars["mpg"], mtcars[c("am")], sum)$mpg)
# [1] 642.9
sum(aggregate(mtcars["mpg"], mtcars[c("am", "cyl")], sum)$mpg)
# [1] 642.9

但是,如果我们在分组变量中引入缺失值,则该值将不包含在聚合中:

mt = mtcars
mt$cyl[1] = NA
sum(aggregate(mt["mpg"], mt[c("am", "cyl")], sum)$mpg)
# [1] 621.9

最简单的解决方法是用NA以外的其他内容(可能是字符串"missing"填充缺失值。

答案 1 :(得分:0)

我认为@Gregor正确指出了问题可能是具有NA的分组变量。 dplyr处理NA的分组方式与aggregate不同。

我们还有一个aggregate的替代解决方案。请注意,该文件建议

`by`   a list of grouping elements, each as long as the variables in the data
       frame x. The elements are coerced to factors before use.

这是线索。您可以使用factor将分组变量转换为exclude="",这将确保NA是因素的一部分。

set.seed(1)

df <- data.frame(ATTRIBUTE1 = sample(LETTERS[1:3], 10, replace = TRUE),
                 ATTRIBUTE2 = sample(letters[1:3], 10, replace = TRUE),
                 AMOUNT = 1:10)

df$ATTRIBUTE2[5] <- NA


aggregate(df["AMOUNT"], by = list(factor(df$ATTRIBUTE1,exclude = ""),
                                  factor(df$ATTRIBUTE2, exclude="")), sum)

#   Group.1 Group.2 AMOUNT
# 1       A       a      1
# 2       B       a      2
# 3       B       b      9
# 4       C       b     10
# 5       A       c     10
# 6       B       c     11
# 7       C       c      7
# 8       A    <NA>      5

未将分组变量显式转换为factor以包含NA的结果如下:

aggregate(df["AMOUNT"], df[c("ATTRIBUTE1", "ATTRIBUTE2")], sum)
#   ATTRIBUTE1 ATTRIBUTE2 AMOUNT
# 1          A          a      1
# 2          B          a      2
# 3          B          b      9
# 4          C          b     10
# 5          A          c     10
# 6          B          c     11
# 7          C          c      7