理解dplyr的group_by和tapply之间结果差异

3

我本来期望在这两次运行中看到相同的结果,但实际上它们是不同的。这让我怀疑自己是否真正了解dplyr代码的工作原理(我已经阅读了关于dplyr包和在线文档的所有内容)。是否有人能够解释为什么结果会不同,或者如何获得类似的结果?

library(dplyr)
x <- iris
x <- x %.%
    group_by(Species, Sepal.Width) %.%
    summarise (freq=n()) %.%
    summarise (mean_by_group = mean(Sepal.Width))  
print(x)

x <- iris
x <- tapply(x$Sepal.Width, x$Species, mean)
print(x)

更新:我认为这不是最有效的解决方法,但以下代码给出了与tapply方法匹配的结果。根据Hadley的建议,我逐行检查了结果,并使用dplyr找到了最好的解决方案。

library(dplyr)
x <- iris
x <- x %.%
    group_by(Species, Sepal.Width) %.%
    summarise (freq=n()) %.%
    mutate (mean_by_group = sum(Sepal.Width*freq)/sum(freq)) %.%
print(x)

更新:出于某些原因,我认为我必须将所有要分析的变量分组,这就是导致事情走错方向的原因。这就是我所需要的全部内容,更接近包中的示例。
x <- iris %.%
    group_by(Species) %.%
    summarise(Sepal.Width = mean(Sepal.Width))
print(x)

提示:逐行检查您的dplyr代码。 - hadley
1个回答

4

也许这...

- dplyr:

require(dplyr)

iris %>% group_by(Species) %>% summarise(mean_width = mean(Sepal.Width))

  # Source: local data frame [3 x 2]
  #
  #      Species        mean_width
  # 1     setosa             3.428
  # 2 versicolor             2.770
  # 3  virginica             2.974

- tapply:

tapply(iris$Sepal.Width, iris$Species, mean)

  # setosa versicolor  virginica 
  # 3.428      2.770      2.974 

注意:默认情况下,tapply() 简化输出,而 summarise() 不会:

typeof(tapply(iris$Sepal.Width, iris$Species, mean, simplify=TRUE))

  # [1] "double"

如果不是列表,则返回一个list
typeof(tapply(iris$Sepal.Width, iris$Species, mean, simplify=FALSE))

  # [1] "list"

因此,要从tapply()中获得相同类型的输出,您需要:

tbl_df( 
  data.frame( 
    mean_width = tapply( iris$Sepal.Width, 
                         iris$Species, 
                         mean )))

  # Source: local data frame [3 x 1]
  #
  #            mean_width
  # setosa          3.428
  # versicolor      2.770
  # virginica       2.974

这仍然不同!因为在这里unique(iris$Species)是一个属性而不是数据框的列...


这个方法可行,我已将其标记为答案,但你可能需要补充一点,即需要加载magrittr包才能启用%>%。在此之前我并不熟悉这个包。 - Michael Bellhouse
@MichaelBellhouse编辑帖子以包括require(dplyr)行。在加载时,dplyr会导入“magrittr”软件包的一小部分。感谢您的提醒。 - npjc
实际上,如果没有加载magrittr,您的代码对我来说无法运行: - Michael Bellhouse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接