基于对应_det列条件批量替换_res列值(tidyverse实现)
问题描述
现有如下数据集:
| V1_res | V1_det | V2_res | V2_det | V3_res | V3_det |
|---|---|---|---|---|---|
| 0.1 | N | 0.4 | Y | 0.4 | N |
| 0.3 | N | 0.5 | Y | 0.3 | Y |
| 0.5 | Y | 0.1 | N | 0.2 | N |
需求:当对应行的_det列值为"N"时,将对应的_res列值替换为NA。由于实际数据集列数远多于3列,需要基于tidyverse的批量处理方案,避免逐列操作。
解决方案
这里提供两种基于tidyverse的批量处理方案,无需手动逐列定义:
方案一:长格式转换后批量处理
通过转换数据格式,将配对的_res和_det列聚合处理,再转回原格式:
library(tidyverse) df %>% # 拆分列名,将同组的_res和_det转为长格式 pivot_longer( cols = everything(), names_to = c("group", ".value"), names_pattern = "(V\\d+)_(res|det)" ) %>% # 统一判断替换:det为N时res设为NA mutate(res = if_else(det == "N", NA_real_, res)) %>% # 转回原始宽格式 pivot_wider( names_from = group, values_from = c(res, det), names_sep = "_" )
逻辑说明
pivot_longer用正则表达式拆分列名,把V1_res和V1_det这类配对列合并到同一行,生成group(对应V1/V2等分组)、res、det三列,简化批量判断逻辑。mutate统一处理所有res列:只要对应det值为"N",就替换为NA(NA_real_适配数值类型,字符串列可改用NA_character_)。pivot_wider将数据转回原始的宽格式,保留原有列名结构。
方案二:直接批量遍历列(无需转格式)
如果不想改变数据格式,可利用across结合列名匹配直接处理:
library(tidyverse) df %>% mutate( across(ends_with("_res"), ~ if_else(get(str_replace(cur_column(), "_res", "_det")) == "N", NA_real_, .x) ) )
逻辑说明
across(ends_with("_res")):自动选中所有以_res结尾的列。str_replace(cur_column(), "_res", "_det"):根据当前_res列名,生成对应的_det列名。get(...):提取对应_det列的数值,判断是否为"N",是则将当前_res列值替换为NA。
内容的提问来源于stack exchange,提问作者Curdz Coder
相关产品推荐
相关产品推荐

