如何更优雅地对R语言数据框执行group_by操作,统计每日Folder功能使用用户数
方案说明
你原有实现的核心问题是标记赋值逻辑颠倒:df1内的用户是100%确认使用过Folder功能,对应标记应该设为1,df2内用户无法确认对应标记设为0,否则最终统计结果不符合业务需求。
以下是更简洁高效的实现方案:
1. tidyverse 方案(逻辑清晰易读)
library(dplyr) # 原始样例数据 df1 <- data.frame(Date=c("2021-05-12","2021-05-15","2021-05-20"),user_ID=c("RZ625","TDH65","EJ7336")) df2 <- data.frame(Date=c("2021-05-12","2021-05-15","2021-05-22"),user_ID=c("IZ823","TDH65","SI826")) # 统计代码 final_df <- bind_rows( df1 %>% mutate(is_confirmed = 1), df2 %>% mutate(is_confirmed = 0) ) %>% # 按日期+用户去重,只要有一条确认记录就算使用过 group_by(Date, user_ID) %>% summarise(is_confirmed = max(is_confirmed), .groups = "drop") %>% # 按日期统计确认使用的用户数 group_by(Date) %>% summarise(Nb_Users_Folder_True = sum(is_confirmed), .groups = "drop")
运行后得到的结果符合预期:
| Date | Nb_Users_Folder_True |
|---|---|
| 2021-05-12 | 2 |
| 2021-05-15 | 1 |
| 2021-05-20 | 1 |
| 2021-05-22 | 0 |
2. data.table 方案(适合大数据量,性能更高)
如果你的数据量在百万级以上,推荐用data.table实现,运算速度会快很多:
library(data.table) # 转换为data.table格式 setDT(df1) setDT(df2) final_dt <- rbind( df1[, is_confirmed := 1], df2[, is_confirmed := 0] )[, .(is_confirmed = max(is_confirmed)), by = .(Date, user_ID) ][, .(Nb_Users_Folder_True = sum(is_confirmed)), by = Date]
方案优势
- 逻辑符合业务规则:明确区分两个表的确认属性,用
max判断用户当日是否有确认使用记录,避免赋值错误 - 代码简洁:无需提前修改原始表结构,通过管道/链式操作一气呵成
- 性能优异:都是向量化的分组运算,尤其是data.table方案适合大规模数据场景
内容的提问来源于stack exchange,提问作者ML_Enthousiast
相关产品推荐
相关产品推荐

