R语言分组后填充数据框:将不同行值映射至对应日期列
R语言DataFrame格式转换解决方案
原始数据
创建数据的代码:
df <- read.table(text=" id mast merti cysts max_date 001 1 0 0 30,55 001 0 0 0 38,98 002 0 1 0 24,59 002 1 0 0 33,24", header = TRUE)
对应数据结构:
| id | mast | merti | cysts | max_date |
|---|---|---|---|---|
| 001 | 1 | 0 | 0 | 30,55 |
| 001 | 0 | 0 | 0 | 38,98 |
| 002 | 0 | 1 | 0 | 24,59 |
| 002 | 1 | 0 | 0 | 33,24 |
目标格式
需要转换为如下单行聚合的结构:
| id | D1 | D2 | D3 | d1_date | d2_date | d3_date |
|---|---|---|---|---|---|---|
| 001 | 1 | 0 | 0 | 30,55 | 38,98 | 38,98 |
| 002 | 1 | 1 | 0 | 33,24 | 24,59 | 33,24 |
尝试的代码及问题
之前尝试的代码存在两个问题:一是错误引用了不存在的illness列,二是仅生成了行级日期标记,未按id聚合为单行且未处理无匹配项的日期填充:
library(tidyverse) df %>% separate(illness, into=c("D1","D2", "D3"), sep=",") %>% group_by(id) %>% mutate( d1_date = ifelse(D1 == 1, max_date, NA), d2_date = ifelse(D2 == 1, max_date, NA), d3_date = ifelse(D3 == 1, max_date, NA))
得到的结果存在大量NA值,且未完成聚合:
| id | D1 | D2 | D3 | d1_date | d2_date | d3_date |
|---|---|---|---|---|---|---|
| 001 | 1 | 0 | 0 | 30,55 | NA | NA |
| 001 | 0 | 0 | 0 | NA | NA | NA |
| 002 | 0 | 1 | 0 | NA | 24,59 | NA |
| 002 | 1 | 0 | 0 | 33,24 | NA | NA |
正确实现方法
通过重命名列、分组聚合并处理日期填充逻辑,实现目标格式:
library(tidyverse) df %>% # 重命名原始列匹配目标的D1/D2/D3 rename(D1 = mast, D2 = merti, D3 = cysts) %>% group_by(id) %>% summarise( # 聚合D列:只要组内有1则记为1 D1 = max(D1), D2 = max(D2), D3 = max(D3), # 日期逻辑:有匹配的D=1则取对应日期,无匹配则取组内最大日期 d1_date = ifelse(any(D1 == 1), max_date[which(D1 == 1)], max(max_date)), d2_date = ifelse(any(D2 == 1), max_date[which(D2 == 1)], max(max_date)), d3_date = ifelse(any(D3 == 1), max_date[which(D3 == 1)], max(max_date)) )
逻辑说明:
- 先将原始的
mast/merti/cysts列重命名为D1/D2/D3,对齐目标列名 - 按
id分组后,对D列取最大值,实现"只要组内有1则保留1"的聚合逻辑 - 日期列处理:优先取对应D=1行的
max_date,若组内无匹配项,则取该组的最大max_date,匹配目标示例的填充规则
运行后即可得到符合要求的聚合结果。
内容的提问来源于stack exchange,提问作者jakim_M
相关产品推荐
相关产品推荐

