基于日期区间与阈值的DataFrame二值列编码技术求助
解决方案
问题分析
原代码存在以下关键问题:
- 分组错误:应按
IDrow分组,而非IDrow+Date,否则无法跨日期关联同一ID的NP1和NP2数据 - 日期逻辑错误:未提取每个ID对应的NP1基准日期,导致区间判断无效
- 数据类型问题:
value列被转为字符型,无法进行数值比较 - 缺失默认分支:
case_when未定义不满足条件时的返回值,导致结果出现NA
修正后的代码
library(dplyr) library(lubridate) # 构造数据时直接处理类型,避免后续转换问题 IDrow <- c("ID1", "ID1", "ID2", "ID3", "ID3", "ID3", "ID4", "ID4", "ID5", "ID5") type <- c("NP1", "NP2", "NP1", "NP1", "NP2", "NP2", "NP1", "NP2", "NP1", "NP2") Date <- ymd(c("2018-06-11","2018-08-21", "2016-04-23", "2015-11-24", "2015-11-24", "2016-11-24", "2015-01-01", "2018-01-01", "2013-04-04", "2013-04-04")) value <- as.numeric(c("4.5", "55", "4.7", "9.5", "7390", "308", "6.0", "100", "4.0", "13")) df <- data.frame(IDrow, type, Date, value) # 核心逻辑:按ID分组,判断是否存在符合条件的NP2 df <- df %>% group_by(IDrow) %>% mutate( # 提取当前ID的NP1日期(假设每个ID仅一个NP1) np1_date = Date[type == "NP1"], # 计算±1年的日期区间 date_low = np1_date - years(1), date_high = np1_date + years(1), # 检查是否存在满足所有条件的NP2记录 valid_np2_exists = any(type == "NP2" & Date >= date_low & Date <= date_high & value > 25), # 设置positive列:存在则为1,否则为0 positive = ifelse(valid_np2_exists, 1, 0) ) %>% # 移除辅助列(可选,根据需求保留) select(-np1_date, -date_low, -date_high, -valid_np2_exists) %>% ungroup() print(df)
代码说明
- 类型预处理:构造数据时直接将
Date转为日期型、value转为数值型,避免后续类型转换的麻烦 - 正确分组:按
IDrow分组,确保同一ID下的所有行可以共享NP1的基准日期信息 - 区间计算:基于每个ID的NP1日期,计算出±1年的上下限
- 条件判断:用
any()函数检查当前ID下是否存在满足所有条件的NP2记录,只要有一条符合,该ID所有行的positive都设为1 - 默认值设置:通过
ifelse直接定义两种情况的返回值,避免出现NA
内容的提问来源于stack exchange,提问作者SorenRand
相关产品推荐
相关产品推荐

