R语言按规则替换指定行列部分NA值并新增标识列方法
R语言dplyr实现方案
你原代码的问题有两点:一是R中向量逻辑与要用&而非AND,且if_else的条件部分括号位置错误;二是没有按主题块分组判断行的相对位置,无法匹配「指定区间内替换NA」的规则。
完整可运行代码如下:
library(dplyr) df_processed <- df %>% # 以Asked=TRUE的行为分界,给每个主题块生成唯一分组ID mutate(group_id = cumsum(Asked)) %>% group_by(group_id) %>% mutate( # 定位当前组内第一个Answer所在行号,无Answer则取组尾+1 first_answer_pos = ifelse(any(type == "Answer", na.rm = T), min(which(type == "Answer")), n() + 1), # 按规则替换type值 type = case_when( row_number() == 1 ~ type, # 组内第一行即Asked=TRUE的标题行,保留原值 row_number() < first_answer_pos & is.na(type) ~ "Replies", TRUE ~ type ), # 生成replied标识列 replied = any(type == "Answer", na.rm = T) ) %>% ungroup() %>% # 移除中间辅助列 select(-group_id, -first_answer_pos)
逻辑说明
- 分组逻辑:用
cumsum(Asked)自动给每个主题块编号,每碰到一个Asked=TRUE的主题起始行,组号加1,同个主题下的所有评论共享同一个组号 - type替换规则:
- 每个主题的标题行(
Asked=TRUE)永远保留原有NA值,不做替换 - 组内第一个Answer出现位置之前的NA值,统一替换为
Replies,无论中间是否存在Question行,和你给出的预期输出完全匹配 - 原有Question、Answer值全部保留不改动
- 每个主题的标题行(
- replied列:按主题判断是否存在Answer类型的内容,同个主题下所有行的replied值一致,标识该主题是否收到正式回答
匹配效果校验
运行代码后输出结果和预期完全一致:
- Military guidelines主题下,3个Question后的2个NA被替换为Replies,后续Answer保留
- Network guidelines主题下无Question行,标题后到Answer前的2个NA被替换为Replies
- Statutory measures主题下Question和Answer之间的NA被替换为Replies
- Methods machines?主题下无Answer行,标题后的NA被替换为Replies,对应replied值为FALSE
内容的提问来源于stack exchange,提问作者Ranji Raj
相关产品推荐
相关产品推荐

