如何在长格式数据集中对比多行数据生成新变量Aim
问题描述
我有如下长格式数据集:
| ID | year | Address | Classification |
|---|---|---|---|
| 1 | 2020 | A | NA |
| 1 | 2021 | A | NA |
| 1 | 2022 | B | B_ |
| 2 | 2020 | C | NA |
| 2 | 2021 | D | NA |
| 2 | 2022 | F | F_ |
| 3 | 2020 | G | NA |
| 3 | 2021 | G | NA |
| 3 | 2022 | G | G_ |
| 4 | 2020 | H | NA |
| 4 | 2021 | I | NA |
| 4 | 2022 | H | H_ |
每个对象在2022年基于当年地址有对应的Classification,其他年份该字段为NA。我希望将2022年的分类推广至其他年份:若其他年份的地址与该对象2022年的地址相同,则将对应Classification的NA替换为2022年的分类值,最终得到含Aim列的数据集:
| ID | year | Address | Classification | Aim |
|---|---|---|---|---|
| 1 | 2020 | A | NA | NA |
| 1 | 2021 | A | NA | NA |
| 1 | 2022 | B | B_ | B_ |
| 2 | 2020 | C | NA | NA |
| 2 | 2021 | D | NA | NA |
| 2 | 2022 | F | F_ | F_ |
| 3 | 2020 | G | NA | G_ |
| 3 | 2021 | G | NA | G_ |
| 3 | 2022 | G | G_ | G_ |
| 4 | 2020 | H | NA | H_ |
| 4 | 2021 | I | NA | NA |
| 4 | 2022 | H | H_ | H_ |
我曾尝试转为宽格式用dplyr处理,但因NA值问题未成功,现寻求更优实现方法。
解决方案
使用dplyr的分组+条件判断即可实现,无需转宽格式,具体步骤如下:
- 按
ID分组,提取每个ID在2022年的地址和分类作为参考值; - 对每一行做条件判断:2022年的行直接取
Classification作为Aim;其他年份若地址匹配该ID2022年的地址,则取2022年的分类值,否则保持NA。
代码实现
library(dplyr) # 构造原始数据集(如果已有数据集可跳过这部分) df <- tibble( ID = c(1,1,1,2,2,2,3,3,3,4,4,4), year = c(2020,2021,2022,2020,2021,2022,2020,2021,2022,2020,2021,2022), Address = c("A","A","B","C","D","F","G","G","G","H","I","H"), Classification = c(NA,NA,"B_",NA,NA,"F_",NA,NA,"G_",NA,NA,"H_") ) # 生成目标数据集 result <- df %>% group_by(ID) %>% mutate( # 提取当前ID2022年的地址和分类作为参考 ref_addr = first(Address[year == 2022]), ref_class = first(Classification[year == 2022]), # 按规则生成Aim列 Aim = case_when( year == 2022 ~ Classification, Address == ref_addr ~ ref_class, TRUE ~ NA_character_ ) ) %>% # 移除临时参考列 select(-ref_addr, -ref_class) %>% ungroup() print(result)
代码说明
group_by(ID):确保每个ID的参考值独立计算,不互相干扰;ref_addr和ref_class:通过first()提取每个ID2022年的唯一地址和分类值;case_when():多条件分支处理,优先级从高到低:先处理2022年的行,再匹配地址,最后默认返回NA;select():清理临时生成的参考列,保持结果数据结构整洁。
运行代码后即可得到目标数据集。
内容的提问来源于stack exchange,提问作者Tormod
相关产品推荐
相关产品推荐

