R语言按id分组计算每行距最近一次outcome=1的间隔天数如何实现
首先请确保你的数据集中date列已转换为Date类型,且每组id内的行已按日期升序排序,下面给出两种实现方案:
方案1:基础R实现(适配你原有tapply写法)
# 先转换date列类型 df$date <- as.Date(df$date) # 按id分组计算目标字段 df$days_since_outcome_1 <- unlist(tapply(1:nrow(df), INDEX = df$id, FUN = function(i) { group_df <- df[i, ] last_positive_date <- as.Date(NA) res <- numeric(nrow(group_df)) for (j in 1:nrow(group_df)) { current_date <- group_df$date[j] if (group_df$outcome[j] == 1) { res[j] <- ifelse(is.na(last_positive_date), 0, as.integer(current_date - last_positive_date)) # 更新最近的outcome=1的日期 last_positive_date <- current_date } else { res[j] <- ifelse(is.na(last_positive_date), 0, as.integer(current_date - last_positive_date)) } } res }))
方案2:dplyr实现(代码更简洁易读)
library(dplyr) df <- df %>% mutate(date = as.Date(date)) %>% group_by(id) %>% arrange(date, .by_group = TRUE) %>% # 自动确保组内按日期升序排序 mutate( # 仅保留outcome=1的日期,其余行填充NA,再用最近的非NA值向前填充 last_positive_date = if_else(outcome == 1, date, as.Date(NA)), last_positive_date = cummax(last_positive_date), days_since_outcome_1 = if_else(is.na(last_positive_date), 0, as.integer(date - last_positive_date)) ) %>% ungroup() %>% select(-last_positive_date)
两种方案均完全匹配你给出的测试场景要求:多outcome=1的情况自动取最近一次的日期计算差值,当前行之前无outcome=1记录时返回0。
内容的提问来源于stack exchange,提问作者fifigoblin
相关产品推荐
相关产品推荐

