如何定位个体首个非缺失值并将其后续的NA值替换为0
核心实现逻辑
先定位每个用户首次非缺失就诊记录的列位置,首次位置之后的缺失值替换为0,首次位置之前的缺失值保留原样即可,以下是两种常用的R语言实现方案:
方案1:tidyverse 长表转换实现(逻辑清晰,不易出错)
library(tidyverse) WANT <- HAVE %>% # 宽格式转为长格式,方便按用户分组处理 pivot_longer(cols = Jan:Jul, names_to = "month", values_to = "visit_count") %>% group_by(ID) %>% mutate( # 提取当前用户首次非NA就诊的位置 first_visit_idx = which(!is.na(visit_count))[1], # 位置在首次就诊之后的NA替换为0,其余保留原值 visit_count = case_when( row_number() > first_visit_idx & is.na(visit_count) ~ 0, TRUE ~ visit_count ) ) %>% select(-first_visit_idx) %>% # 转回宽格式得到结果 pivot_wider(names_from = month, values_from = visit_count) %>% ungroup()
方案2:Base R 逐行遍历实现(无需加载第三方包)
# 定位所有月份列的索引 month_col_idx <- which(colnames(HAVE) %in% c("Jan","Feb","Mar","Apr","May","June","Jul")) # 逐行处理每个用户 for (i in seq(nrow(HAVE))) { # 查找当前行第一个非NA的就诊列位置,无就诊记录则跳过 first_non_na <- Position(\(x) !is.na(x), HAVE[i, month_col_idx], nomatch = 0) if (first_non_na == 0) next # 对首次就诊之后的列,将NA替换为0 process_col_idx <- month_col_idx[(first_non_na + 1):length(month_col_idx)] current_row_vals <- unlist(HAVE[i, process_col_idx]) current_row_vals[is.na(current_row_vals)] <- 0 HAVE[i, process_col_idx] <- current_row_vals } WANT <- HAVE
以上两种方案运行后得到的WANT数据集和你给出的预期结果完全一致。
内容的提问来源于stack exchange,提问作者Sophia
相关产品推荐
相关产品推荐

