3

每次我在 data.frame 上进行聚合时,我都默认使用该"by = list(...)"参数。但我确实在 stackoverflow 和“公式”参数中使用波浪号 (~) 的其他地方看到了解决方案。我有点将“by”参数视为围绕这些变量的“pivot”。

在某些情况下,输出完全相同。例如:

aggregate(cbind(df$A, df$B, df$C), FUN = sum, by = list("x" = df$D, "y" = df$E))

AND

aggregate(cbind(df$A, df$B, df$C) ~ df$E, FUN = sum)

两者有什么区别,什么时候用哪个?

4

2 回答 2

7

我不会完全不同意您使用哪种方法并不重要,但是,重要的是要注意它们的行为确实不同。

我将用一个小例子来说明。

以下是一些示例数据:

set.seed(1)
mydf <- data.frame(A = c(1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4),
                   B = LETTERS[c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2)],
                   matrix(sample(100, 36, replace = TRUE), nrow = 12))
mydf[3:5] <- lapply(mydf[3:5], function(x) {
  x[sample(nrow(mydf), 1)] <- NA
  x
})
mydf
#    A B X1  X2 X3
# 1  1 A 27  69 27
# 2  1 A 38  NA 39
# 3  1 A 58  77  2
# 4  2 A 91  50 39
# 5  2 A 21  72 87
# 6  3 B 90 100 35
# 7  3 B 95  39 49
# 8  3 B 67  78 60
# 9  3 B 63  94 NA
# 10 4 B NA  22 19
# 11 4 B 21  66 83
# 12 4 B 18  13 67

一是公式界面。以下三个命令都将产生相同的输出。

aggregate(cbind(X1, X2, X3) ~ A + B, mydf, sum)
aggregate(cbind(X1, X2, X3) ~ ., mydf, sum)
aggregate(. ~ A + B, mydf, sum)
#   A B  X1  X2  X3
# 1 1 A  85 146  29
# 2 2 A 112 122 126
# 3 3 B 252 217 144
# 4 4 B  39  79 150

这是“by”接口的相关命令。打字很麻烦(但如果需要,可以使用 来解决with)。

aggregate(cbind(mydf$X1, mydf$X2, mydf$X3), 
          by = list(mydf$A, mydf$B), sum)
  Group.1 Group.2  V1  V2  V3
1       1       A 123  NA  68
2       2       A 112 122 126
3       3       B 315 311  NA
4       4       B  NA 101 169

现在,停下来,记下任何差异。

我脑海中浮现的两个是:

  1. 公式方法在保留方面做得更好,names 它不允许您直接在命令中控制名称,您可以data.frame方法中执行此操作:

    aggregate(cbind(NewX1 = mydf$X1, NewX2 = mydf$X2, NewX3 = mydf$X3), 
              by = list(NewA = mydf$A, NewB = mydf$B), sum)
    
  2. 公式方法和data.frame方法对NA值的处理方式不同。要使用公式方法获得与使用方法相同的结果data.frame,您需要使用na.action = na.pass.

    aggregate(. ~ A + B, mydf, sum, na.action=na.pass)
    

同样,说“我认为这并不重要”并不是完全错误的,而且我不会在这里陈述我的偏好,因为这并不是 Stack Overflow 的真正意义,但始终阅读函数很重要在做出此类决定之前仔细记录。

于 2013-11-07T15:41:39.577 回答
1

从帮助页面,

aggregate.formula is a standard formula interface to aggregate.data.frame

所以我认为这并不重要。使用您喜欢的任何方法,或者适合您工作区中现有变量和公式的方法。

于 2013-11-07T13:45:04.633 回答