dplyr 总结:相当于“.drop=FALSE"在输出中保留零长度的组 [英] dplyr summarise: Equivalent of ".drop=FALSE" to keep groups with zero length in output
问题描述
当将 summarise
与 plyr
的 ddply
函数一起使用时,默认情况下会删除空类别.您可以通过添加 .drop = FALSE
来更改此行为.但是,这在将 summarise
与 dplyr
一起使用时不起作用.有没有其他方法可以在结果中保留空类别?
When using summarise
with plyr
's ddply
function, empty categories are dropped by default. You can change this behavior by adding .drop = FALSE
. However, this doesn't work when using summarise
with dplyr
. Is there another way to keep empty categories in the result?
这里有一个虚假数据的例子.
Here's an example with fake data.
library(dplyr)
df = data.frame(a=rep(1:3,4), b=rep(1:2,6))
# Now add an extra level to df$b that has no corresponding value in df$a
df$b = factor(df$b, levels=1:3)
# Summarise with plyr, keeping categories with a count of zero
plyr::ddply(df, "b", summarise, count_a=length(a), .drop=FALSE)
b count_a
1 1 6
2 2 6
3 3 0
# Now try it with dplyr
df %.%
group_by(b) %.%
summarise(count_a=length(a), .drop=FALSE)
b count_a .drop
1 1 6 FALSE
2 2 6 FALSE
不完全是我所希望的.是否有 dplyr
方法可以实现与 plyr
中的 .drop=FALSE
相同的结果?
Not exactly what I was hoping for. Is there a dplyr
method for achieving the same result as .drop=FALSE
in plyr
?
推荐答案
自从 dplyr 0.8 group_by
获得了 .drop
参数您的要求:
Since dplyr 0.8 group_by
gained the .drop
argument that does just what you asked for:
df = data.frame(a=rep(1:3,4), b=rep(1:2,6))
df$b = factor(df$b, levels=1:3)
df %>%
group_by(b, .drop=FALSE) %>%
summarise(count_a=length(a))
#> # A tibble: 3 x 2
#> b count_a
#> <fct> <int>
#> 1 1 6
#> 2 2 6
#> 3 3 0
@Moody_Mudskipper 的回答还有一个附加说明:当一个或多个分组变量未编码为因子时,使用 .drop=FALSE
可能会产生潜在的意外结果.请参阅以下示例:
One additional note to go with @Moody_Mudskipper's answer: Using .drop=FALSE
can give potentially unexpected results when one or more grouping variables are not coded as factors. See examples below:
library(dplyr)
data(iris)
# Add an additional level to Species
iris$Species = factor(iris$Species, levels=c(levels(iris$Species), "empty_level"))
# Species is a factor and empty groups are included in the output
iris %>% group_by(Species, .drop=FALSE) %>% tally
#> Species n
#> 1 setosa 50
#> 2 versicolor 50
#> 3 virginica 50
#> 4 empty_level 0
# Add character column
iris$group2 = c(rep(c("A","B"), 50), rep(c("B","C"), each=25))
# Empty groups involving combinations of Species and group2 are not included in output
iris %>% group_by(Species, group2, .drop=FALSE) %>% tally
#> Species group2 n
#> 1 setosa A 25
#> 2 setosa B 25
#> 3 versicolor A 25
#> 4 versicolor B 25
#> 5 virginica B 25
#> 6 virginica C 25
#> 7 empty_level <NA> 0
# Turn group2 into a factor
iris$group2 = factor(iris$group2)
# Now all possible combinations of Species and group2 are included in the output,
# whether present in the data or not
iris %>% group_by(Species, group2, .drop=FALSE) %>% tally
#> Species group2 n
#> 1 setosa A 25
#> 2 setosa B 25
#> 3 setosa C 0
#> 4 versicolor A 25
#> 5 versicolor B 25
#> 6 versicolor C 0
#> 7 virginica A 0
#> 8 virginica B 25
#> 9 virginica C 25
#> 10 empty_level A 0
#> 11 empty_level B 0
#> 12 empty_level C 0
Created on 2019-03-13 by the reprex package (v0.2.1)
这篇关于dplyr 总结:相当于“.drop=FALSE"在输出中保留零长度的组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!