如何在mutate(across())中通过字符串引用列实现ifelse条件判断
批量根据对应Direction列修改数值列
示例数据
library(tidyverse) colNames <- c('A', 'B') df <- tibble(A = sample(1:1000, 20), A_Direction = 'Decreasing', B = sample(1:1000, 20), B_Direction = 'Increasing')
需求
批量修改colNames指定的列(如A、B):当对应X_Direction列值为Decreasing时,将X列设为0;值为Increasing时设为1。
原代码问题
你之前的代码中,paste0(cur_column(), '_Direction')仅生成了列名字符串,没有实际引用对应列的数值,导致判断条件始终是字符串对比(比如"A_Direction" == "Decreasing"),结果全为FALSE,所以所有列都被设为1。
解决方案
方法1:使用.data代词(推荐)
通过.data[[字符串]]的方式引用对应列,实现正确的条件判断:
dfNew <- df %>% mutate(across(all_of(colNames), ~ifelse(.data[[paste0(cur_column(), "_Direction")]] == "Decreasing", 0, 1)))
方法2:用case_when增强可读性
如果需要扩展更多判断规则,case_when会更清晰:
dfNew <- df %>% mutate(across(all_of(colNames), ~case_when( .data[[paste0(cur_column(), "_Direction")]] == "Decreasing" ~ 0, .data[[paste0(cur_column(), "_Direction")]] == "Increasing" ~ 1 )))
方法3:宽转长处理(适合大量列场景)
当需要处理的列数量极多时,先转成long格式统一处理,再转回wide格式:
dfNew <- df %>% # 把目标数值列转成长格式 pivot_longer(cols = all_of(colNames), names_to = "col", values_to = "val") %>% # 把Direction列也转成长格式,并去掉后缀 left_join(df %>% pivot_longer(cols = ends_with("_Direction"), names_to = "col", values_to = "direction", names_transform = ~str_remove(., "_Direction")), by = "col") %>% # 批量修改值 mutate(val = ifelse(direction == "Decreasing", 0, 1)) %>% # 转回宽格式 pivot_wider(names_from = "col", values_from = "val") %>% # 保持原数据的列顺序 select(all_of(names(df)))
内容的提问来源于stack exchange,提问作者ksinva
相关产品推荐
相关产品推荐

