如何用across、starts_with和ifelse批量处理两组关联变量?
批量处理关联对应va_变量的jk_列
原始数据
library(dplyr) data_test = data.frame(va_te=c("yes", "", "no", "yes"), va_ti=c("no", "", "yes", "no"), va_ze=c("", "no", "yes", "no"), jk_te=c(NA, 545, 876, 987), jk_ti=c(876, 567, 908, 432), jk_ze=c(987, 988, NA, 234), loc=c(345, 898, 444, 321)) data_test # va_te va_ti va_ze jk_te jk_ti jk_ze loc # 1 yes no NA 876 987 345 # 2 no 545 567 988 898 # 3 no yes yes 876 908 NA 444 # 4 yes no no 987 432 234 321
需求说明
需要对前6个变量分两组处理:
- va_开头的变量:已用
across+starts_with+ifelse将空字符串转为NA; - jk_开头的变量:每个jk_变量需关联对应后缀的va_变量做判断(如jk_te对应va_te),规则为:
- 若对应va_变量不等于"yes",则jk_变量设为NA;
- 若对应va_变量等于"yes"且jk_变量本身是NA,用
loc列的值填充; - 其他情况保留jk_变量原值。
目前只能逐个编写mutate语句,希望实现批量处理。
解决方案
利用across结合cur_column()提取jk_变量的后缀,匹配对应的va_变量,即可实现批量处理:
data_test_2 = data_test %>% # 处理va_开头的变量,空字符串转NA mutate(across(starts_with("va_"), ~ ifelse(.x == "", NA, .x))) %>% # 批量处理jk_开头的变量 mutate(across(starts_with("jk_"), ~ { # 获取当前jk列对应的va列名称 va_col = paste0("va_", stringr::str_remove(cur_column(), "jk_")) va_val = get(va_col) # 应用判断逻辑 ifelse(va_val != "yes", NA, ifelse(va_val == "yes" & is.na(.x), loc, .x)) }, .names = "{col}")) data_test_2 # va_te va_ti va_ze jk_te jk_ti jk_ze loc # 1 yes no <NA> 345 NA NA 345 # 2 <NA> <NA> no NA NA NA 898 # 3 no yes yes NA 908 444 444 # 4 yes no no 987 NA NA 321
思路解释
cur_column()获取当前正在处理的jk_列名称;stringr::str_remove去掉前缀"jk_",拼接得到对应的va_列名称;get()获取对应va_列的数值,实现两列的关联判断;- 将原逐个编写的ifelse逻辑嵌入
across的处理函数中,完成所有jk_列的批量处理。
内容的提问来源于stack exchange,提问作者Av65
相关产品推荐
相关产品推荐

