使用 summarise
和 plyr
的 ddply
函数时,默认情况下会删除空类别 . 您可以通过添加 .drop = FALSE
来更改此行为 . 但是,当 summarise
与 dplyr
一起使用时,这不起作用 . 还有另一种方法可以在结果中保留空类别吗?
这是假数据的一个例子 .
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
相同的结果?
3 回答
问题仍然存在,但与此同时,特别是因为您的数据已经考虑因素,您可以使用
complete
来自"tidyr"获取您可能正在寻找的内容:如果您希望替换值为零,则需要使用
fill
指定:dplyr解决方案:
首先制作分组df
然后我们通过
n()
计算总结那些发生的水平然后我们将结果合并到一个包含所有因子水平的数据框中:
最后,在这种情况下,因为我们正在查看计数,
NA
值将更改为0 .这也可以在功能上实现,请参阅答案:Add rows to grouped data with dplyr?
一个黑客:
为了感兴趣,我想我会在这种情况下发布 terrible hack . 我严重怀疑你应该真的这样做,但它显示
group_by()
如何生成atrributes,好像df$b
是一个字符向量而不是一个水平因素 . 另外,我没有't pretend to understand this properly -- but I am hoping this helps me learn -- this is the only reason I'米贴出来!定义数据集中不存在的“越界”值 .
将属性修改为"trick"
summarise()
:做总结:
索引并替换所有出现的oob_val
给出了预期的:
这不完全是问题中的问题,但至少对于这个简单的例子,你可以使用xtabs获得相同的结果,例如:
使用dplyr:
或更短:
结果(两种情况都相同):