R中summarise()弃用后的替代方案及免distinct优化方法
解决dplyr 1.1.0中
summarise()警告与reframe()冗余distinct()的问题 问题场景
在dplyr 1.1.0及以上版本中,使用summarise()时如果每组返回多行数据,会触发弃用警告并提示改用reframe()。但直接用reframe()会保留组内所有行,必须额外调用distinct()才能得到原summarise()预期的每组一行结果。现需计算各业务单元(business_unit)及年份(year)的登录数除以病例数,并生成ggplot可视化,要求实现更简洁的代码。
示例数据:
business_unit <- c("BU1", "BU1", "BU1", "BU2", "BU2", "BU2", "BU2", "BU3", "BU3") year <- c(2020, 2020, 2020, 2020, 2020, 2022, 2020, 2021, 2022) sickness_cases <- c(10, 10, 10, 8, 8, 18, 5, 9, 14) user_name <- c("John", "John", "Alice", "Alice", "Alice", "Alice", "Paul", "Bob", "Bob") example_data <- data.frame(business_unit, year, sickness_cases, user_name)
简洁实现方案
问题根源在于原代码中summarise()计算logins/sickness_cases时,sickness_cases在每组内有重复值,导致生成多行结果。只需在summarise()中先提取每组唯一的sickness_cases值,即可让summarise()每组返回单行,既避免警告,又无需额外调用distinct()。
优化后的分组计算代码
grouped_data <- example_data %>% group_by(business_unit, year) %>% summarise( logins = n(), # 提取每组唯一的病例数值(因每组内sickness_cases重复,first/unique均可) sickness_cases = first(sickness_cases), logins_div_sickness_case = logins / sickness_cases, .groups = "drop" # 可选:自动解除分组状态,后续操作更灵活 )
整合ggplot的一站式代码
可直接将数据处理与可视化整合到管道中,无需单独存储中间数据:
example_data %>% group_by(business_unit, year) %>% summarise( logins = n(), sickness_cases = unique(sickness_cases), logins_div_sickness_case = logins / sickness_cases, .groups = "drop" ) %>% ggplot(aes(x = business_unit, y = logins_div_sickness_case)) + geom_bar(position = "dodge", stat = "identity") + facet_grid(~year)
说明
- 使用
first(sickness_cases)或unique(sickness_cases)均可提取每组的病例数,因为示例数据中每组的sickness_cases值完全重复;若实际场景中组内存在不同病例值,需根据业务逻辑选择合适的聚合方式(如mean()、sum()等)。 - 添加
.groups = "drop"可自动解除分组状态,避免后续操作中因分组带来的潜在问题,可选但推荐使用。
内容的提问来源于stack exchange,提问作者Sofia
相关产品推荐
相关产品推荐

