基于R语言计算群体成员历史共同组参与次数的实现
问题描述
现有一份记录个体组归属的数据,包含字段:ID(个体ID)、GROUP_NUM(组编号)、Date(组创建日期)。需要编写R代码新增HistoryCount列,统计每个成员与当前组内其他成员在更早创建的组中共同参与的次数。
示例数据框
| ID | GROUP_NUM | Date |
|---|---|---|
| abc | 1 | 2022-01-15 |
| def | 1 | 2022-01-15 |
| ghi | 1 | 2022-01-15 |
| jkl | 1 | 2022-01-15 |
| abc | 2 | 2022-02-19 |
| mno | 2 | 2022-02-19 |
| pqr | 2 | 2022-02-19 |
| stv | 2 | 2022-02-19 |
| abc | 3 | 2022-05-11 |
| stv | 3 | 2022-05-11 |
| wxy | 3 | 2022-05-11 |
| zzz | 3 | 2022-05-11 |
| abc | 4 | 2022-10-06 |
| def | 4 | 2022-10-06 |
| pqr | 4 | 2022-10-06 |
| bbb | 4 | 2022-10-06 |
| abc | 5 | 2021-04-14 |
| stv | 5 | 2021-04-14 |
| pqr | 5 | 2021-04-14 |
| bbb | 5 | 2021-04-14 |
期望结果
| ID | GROUP_NUM | Date | HistoryCount |
|---|---|---|---|
| abc | 1 | 2022-01-15 | 0 |
| def | 1 | 2022-01-15 | 0 |
| ghi | 1 | 2022-01-15 | 0 |
| jkl | 1 | 2022-01-15 | 0 |
| abc | 2 | 2022-02-19 | 1 |
| mno | 2 | 2022-02-19 | 0 |
| pqr | 2 | 2022-02-19 | 1 |
| stv | 2 | 2022-02-19 | 1 |
| abc | 3 | 2022-05-11 | 2 |
| stv | 3 | 2022-05-11 | 2 |
| wxy | 3 | 2022-05-11 | 0 |
| zzz | 3 | 2022-05-11 | 0 |
| abc | 4 | 2022-10-06 | 4 |
| def | 4 | 2022-10-06 | 1 |
| ddd | 4 | 2022-10-06 | 0 |
| stv | 4 | 2022-10-06 | 3 |
| abc | 5 | 2021-04-14 | 0 |
| stv | 5 | 2021-04-14 | 0 |
| pqr | 5 | 2021-04-14 | 0 |
| ccc | 5 | 2021-04-14 | 0 |
参考代码(原方案)
此前@akrun提供的方案仅能识别存在历史共同组成员的群体,代码如下:
library(dplyr) df1 %>% group_by(ID) %>% mutate(indx = n_distinct(GROUP_NUM)) %>% ungroup %>% mutate(indx = indx * (duplicated(ID))) %>% group_by(GROUP_NUM) %>% mutate(HISTORY = +((indx > 0) & (sum(indx > 0) > 1)), indx = NULL) %>% ungroup
解决方案
要实现个体级别的历史共同组次数统计,需按时间顺序筛选更早的组,再统计每个个体与当前组其他成员的共同组数量。以下是基于dplyr和tidyr的实现代码:
library(dplyr) library(tidyr) # 将Date转换为日期类型,确保时间比较准确 df <- df %>% mutate(Date = as.Date(Date)) # 生成个体与当前组其他成员的历史共同组记录 common_history <- df %>% # 为每个组记录所有成员的列表 group_by(GROUP_NUM, Date) %>% mutate(group_members = list(ID)) %>% ungroup() %>% # 对每一行,筛选出当前组之前创建的所有组数据 rowwise() %>% mutate(prev_groups_data = list(filter(df, Date < !!Date))) %>% ungroup() %>% # 展开历史组数据,匹配当前组内的成员 unnest(prev_groups_data) %>% filter(ID %in% group_members) %>% # 统计每个个体在当前组中的历史共同组数量(去重) group_by(ID, GROUP_NUM, Date) %>% summarise(HistoryCount = n_distinct(prev_groups_data$GROUP_NUM), .groups = "drop") # 合并统计结果到原数据,未找到历史共同组的个体填充0 final_result <- df %>% left_join(common_history, by = c("ID", "GROUP_NUM", "Date")) %>% mutate(HistoryCount = replace_na(HistoryCount, 0)) print(final_result)
代码说明
- 日期转换:将
Date转为日期类型,避免字符串比较导致的错误。 - 组成员列表:为每个组生成成员列表,用于后续匹配当前组内的其他成员。
- 历史组筛选:对每个组,仅保留创建时间更早的组数据,确保统计范围符合要求。
- 共同组统计:对每个个体,统计其在历史组中与当前组其他成员共同参与的不同组数量,去重避免重复计数。
- 结果合并:将统计结果合并回原数据,缺失值填充为0,保证所有个体都有
HistoryCount值。
内容的提问来源于stack exchange,提问作者iwuzborn
相关产品推荐
相关产品推荐

