如何在dplyr的summarize中按分组统计数值变量的零值出现次数
问题:dplyr分组统计时,如何新增每月工作时长为0的天数?
我在用dplyr的summarize做月度工作时长统计时,已经搞定了总时长、日均时长和每周平均时长的计算,但想加一个每月工作时长为0的天数统计项时卡壳了。
目前能正常运行的统计代码:
library(tidyverse) work_slack %>% group_by(Month_Name) %>% summarize(Sum_Work = round((sum(Mins_Work,na.rm = T))/60), Mean_Work_Day = round(mean(Mins_Work,na.rm = T)/60), Per_Week_Sum = round((sum(Mins_Work,na.rm = T))/60/4)) %>% arrange(desc(Sum_Work))
我试着用count(Mins_Work = 0)来统计0值次数,但这段代码直接报错跑不起来:
work_slack %>% group_by(Month_Name) %>% summarize(Sum_Work = round((sum(Mins_Work,na.rm = T))/60), Mean_Work_Day = round(mean(Mins_Work,na.rm = T)/60), Per_Week_Sum = round((sum(Mins_Work,na.rm = T))/60/4), Breaks = count(Mins_Work = 0)) %>% arrange(desc(Sum_Work))
想请教下怎么在summarize的流程里,按月份统计Mins_Work等于0的次数?
解决方案
嗨,这个问题很常见~在summarize函数里是不能直接嵌套count()的,给你两种简单的实现方式,第一种最直接高效:
方法1:用sum()直接计数(推荐)
R里的逻辑值(TRUE/FALSE)会被自动当作1和0来计算,所以我们可以直接对Mins_Work == 0这个条件求和,就能得到每个月工作时长为0的天数。记得加上na.rm = T,避免NA值干扰计数结果:
library(tidyverse) work_slack %>% group_by(Month_Name) %>% summarize(Sum_Work = round(sum(Mins_Work, na.rm = T)/60), Mean_Work_Day = round(mean(Mins_Work, na.rm = T)/60), Per_Week_Sum = round(sum(Mins_Work, na.rm = T)/60/4), # 统计Mins_Work等于0的次数,忽略NA Breaks = sum(Mins_Work == 0, na.rm = T)) %>% arrange(desc(Sum_Work))
方法2:先单独统计0值次数再合并(备选)
如果你更习惯用count()函数,可以先单独统计每个月的0值天数,再和原统计结果合并:
# 先统计每个月工作时长为0的天数 zero_counts <- work_slack %>% filter(Mins_Work == 0) %>% group_by(Month_Name) %>% count(name = "Breaks") # 合并到原统计结果中,没有0值的月份设为0 work_slack %>% group_by(Month_Name) %>% summarize(Sum_Work = round(sum(Mins_Work, na.rm = T)/60), Mean_Work_Day = round(mean(Mins_Work, na.rm = T)/60), Per_Week_Sum = round(sum(Mins_Work, na.rm = T)/60/4)) %>% left_join(zero_counts, by = "Month_Name") %>% mutate(Breaks = replace_na(Breaks, 0)) %>% arrange(desc(Sum_Work))
小提示
- 方法1更简洁,一步到位完成所有统计,优先推荐使用。
- 一定要注意处理NA值,不然如果你的
Mins_Work列有NA,Mins_Work == 0会返回NA,导致sum()结果也变成NA,加上na.rm = T就能解决这个问题。
内容的提问来源于stack exchange,提问作者Shawn Hemelstrand
相关产品推荐
相关产品推荐

