我想开始使用dplyr代替ddply,但我无法掌握它是如何工作的(我已经阅读了文档)。
例如,为什么当我尝试 mutate() 某些东西时,"group_by"函数无法正常工作?
看山车:
图书馆(汽车)
假设我做了一个 data.frame,它是 mtcars 的摘要,按"cyl"和"gear"分组:
df1 <- mtcars %.%
group_by(cyl, gear) %.%
summarise(
newvar = sum(wt)
)
然后说我想进一步总结这个数据帧。使用 ddply,它会很简单,但是当我尝试使用 dplyr 时,它实际上并不是"分组":
df2 <- df1 %.%
group_by(cyl) %.%
mutate(
newvar2 = newvar + 5
)
仍然产生未分组的输出:
cyl gear newvar newvar2
1 6 3 6.675 11.675
2 4 4 19.025 24.025
3 6 4 12.375 17.375
4 6 5 2.770 7.770
5 4 3 2.465 7.465
6 8 3 49.249 54.249
7 4 5 3.653 8.653
8 8 5 6.740 11.740
我的语法有问题吗?
编辑:
如果我用 plyr 和 ddply 这样做:
df1 <- ddply(mtcars, .(cyl, gear), summarise, newvar = sum(wt))
然后要获得第二个 DF:
df2 <- ddply(df1, .(cyl), summarise, newvar2 = sum(newvar) + 5)
但是同样的方法,在 summarise() 函数中使用 sum(newvar) + 5 不适用于 dplyr...
我也有类似的问题。 我发现简单地分离plyr
解决了它:
detach(package:plyr)
library(dplyr)
将Dickoa的回答更进一步 - 正如Hadley所说"总结剥离了一层分组"。它会从您应用它的相反顺序中剥离分组,因此您可以只使用
mtcars %>%
group_by(cyl, gear) %>%
summarise(newvar = sum(wt)) %>%
summarise(newvar2 = sum(newvar) + 5)
请注意,如果您在第二行中使用group_by(gear, cyl)
,这将给出不同的答案。
要让您的第一次尝试正常工作:
df1 <- mtcars %>%
group_by(cyl, gear) %>%
summarise(newvar = sum(wt))
df2 <- df1 %>%
group_by(cyl) %>%
summarise(newvar2 = sum(newvar)+5)
如果使用summarise
而不是mutate
将plyr
代码转换为dplyr
,则会得到相同的结果。
library(plyr)
df1 <- ddply(mtcars, .(cyl, gear), summarise, newvar = sum(wt))
df2 <- ddply(df1, .(cyl), summarise, newvar2 = sum(newvar) + 5)
df2
## cyl newvar2
## 1 4 30.143
## 2 6 26.820
## 3 8 60.989
detach(package:plyr)
library(dplyr)
mtcars %.%
group_by(cyl, gear) %.%
summarise(newvar = sum(wt)) %.%
group_by(cyl) %.%
summarise(newvar2 = sum(newvar) + 5)
## cyl newvar2
## 1 4 30.143
## 2 8 60.989
## 3 6 26.820
编辑
由于summarise
删除了最后一个组(gear
),因此您可以跳过第二个group_by
(请参阅下面的@hadley评论)
library(dplyr)
mtcars %.%
group_by(cyl, gear) %.%
summarise(newvar = sum(wt)) %.%
summarise(newvar2 = sum(newvar) + 5)
## cyl newvar2
## 1 4 30.143
## 2 8 60.989
## 3 6 26.820
分离plyr
是解决问题的一种方法,因此您可以根据需要使用dplyr
函数...但是,如果您需要 plyr
中的其他函数来完成代码中的其他任务怎么办?
(在此示例中,我加载了dplyr
库和plyr
库)
假设我们有一个简单的 data.frame,当按不同的gname
级别分组时,我们想要计算变量 value
的分组和
> dx<-data.frame(gname=c(1,1,1,2,2,2,3,3,3), value = c(2,2,2,4,4,4,5,6,7))
> dx
gname value
1 1 2
2 1 2
3 1 2
4 2 4
5 2 4
6 2 4
7 3 5
8 3 6
9 3 7
但是,当我们尝试使用我们认为会产生dplyr
分组总和时,会发生以下情况:
dx %>% group_by(gname) %>% mutate(mysum=sum(value))
Source: local data frame [9 x 3]
Groups: gname
gname value mysum
1 1 2 36
2 1 2 36
3 1 2 36
4 2 4 36
5 2 4 36
6 2 4 36
7 3 5 36
8 3 6 36
9 3 7 36
它没有给我们想要的答案。 可能是因为dplyr
和plyr
之间的group_by
和/或mutate
函数的某些交互或重载。 我们可以分离plyr
,但另一种方法是对group_by
和mutate
的dplyr
版本进行唯一调用:
dx %>% dplyr::group_by(gname) %>% dplyr::mutate(mysum=sum(value))
Source: local data frame [9 x 3]
Groups: gname
gname value mysum
1 1 2 6
2 1 2 6
3 1 2 6
4 2 4 12
5 2 4 12
6 2 4 12
7 3 5 18
8 3 6 18
9 3 7 18
现在我们看到这按预期工作。
dplyr 正在按照您在示例中的预期工作。正如您指定的那样,Mutate 在创建 newvar2 时只会向 newvar 的每个值添加 5。无论您是否分组,这看起来都是一样的。但是,如果您指定的内容因组而异,您将获得不同的东西。例如:
df1 %.%
group_by(cyl) %.%
mutate(
newvar2 = newvar + mean(cyl)
)