R语言创建标记变量:识别ID是否在历史任意月份出现过
需求实现:标记历史月份已出现的ID
需求规则
- 生成标记变量
Flag - 若某ID在当前记录对应月份之前的任意月份已存在,当前记录标记为1,否则标记为0
示例输入数据
ID <- c(1,2,3,2,3,4,1,5) Month <- c(1,1,1,2,2,2,3,3) have <- data.frame(ID, Month)
输入数据结构:
| ID | Month |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 2 | 2 |
| 3 | 2 |
| 4 | 2 |
| 1 | 3 |
| 5 | 3 |
预期输出
| ID | Month | Flag |
|---|---|---|
| 1 | 1 | 0 |
| 2 | 1 | 0 |
| 3 | 1 | 0 |
| 2 | 2 | 1 |
| 3 | 2 | 1 |
| 4 | 2 | 0 |
| 1 | 3 | 1 |
| 5 | 3 | 0 |
实现代码
方法1:dplyr实现(推荐,可读性高)
核心逻辑:按ID分组后,每个ID首次出现(最早月份)的记录标记为0,同ID其余记录标记为1即可。如果原始数据未按月份排序,先排序再打标。
library(dplyr) # 若原始数据已按ID、Month排序,可直接用这段 want <- have %>% group_by(ID) %>% mutate(Flag = if_else(row_number() == 1, 0, 1)) %>% ungroup() # 若原始数据月份乱序,先排序再打标 want <- have %>% arrange(ID, Month) %>% group_by(ID) %>% mutate(Flag = if_else(row_number() == 1, 0, 1)) %>% ungroup()
方法2:Base R实现(无需安装第三方包)
核心逻辑:先计算每个ID首次出现的月份,再逐行判断当前记录月份是否大于该ID的首次出现月份,是则标记1,否则标记0。
# 计算每个ID首次出现的月份 first_month <- aggregate(Month ~ ID, data = have, FUN = min) # 匹配打标 have$Flag <- as.integer( have$Month > first_month$Month[match(have$ID, first_month$ID)] )
两种方法运行后得到的结果均和预期输出完全一致。
内容的提问来源于stack exchange,提问作者h09812349
相关产品推荐
相关产品推荐

