如何基于对应列特定值批量替换指定模式列的内容?
问题描述
现有两个数据框:
第一个数据框构建代码:
`1_X94` <- c("apple", "lemon", "orange") `2_X94` <- c("apple", "strawberry", "lemon") `1_X09` <- c(1, 2, 3) `2_X09` <- c(4, 5, 6) `1_X38` <- c("red", "yellow", "orange") `2_X38` <- c("red", "red", "yellow") df <- data.frame(`1_X94`, `2_X94`, `1_X09`, `2_X09`, `1_X38`, `2_X38`)
第二个数据框:
fruit_list <- data.frame(fruit = c("apple", "watermelon"))
需求:当列名匹配正则模式^\d+_X94的列中存在与fruit_list匹配的值时,将列名匹配正则模式^\d+_X38的对应序号列值替换为"green"。
现有代码需要手动指定水果和逐个列编写mutate,无法自动化,需要改进。
自动化解决方案
使用tidyverse中的across函数结合字符串匹配,实现批量处理:
library(tidyverse) # 构建数据框(若已存在可省略) `1_X94` <- c("apple", "lemon", "orange") `2_X94` <- c("apple", "strawberry", "lemon") `1_X09` <- c(1, 2, 3) `2_X09` <- c(4, 5, 6) `1_X38` <- c("red", "yellow", "orange") `2_X38` <- c("red", "red", "yellow") df <- data.frame(`1_X94`, `2_X94`, `1_X09`, `2_X09`, `1_X38`, `2_X38`) fruit_list <- data.frame(fruit = c("apple", "watermelon")) # 自动化处理逻辑 df_processed <- df %>% mutate( # 批量选中所有符合X38模式的列 across(matches("^\\d+_X38"), ~ { # 提取当前列的数字前缀(如从"1_X38"中提取"1") col_num <- str_extract(cur_column(), "^\\d+") # 拼接对应X94列的列名 target_col <- paste0(col_num, "_X94") # 判断对应X94列的值是否在fruit_list中,是则替换为"green",否则保留原值 case_when( .data[[target_col]] %in% fruit_list$fruit ~ "green", TRUE ~ .x ) }) ) # 查看处理结果 print(df_processed)
代码说明
across(matches("^\\d+_X38")):批量选中所有列名匹配^\d+_X38的列,无需逐个列手动指定str_extract(cur_column(), "^\\d+"):动态提取当前处理列的数字前缀,用于匹配对应的X94列.data[[target_col]]:通过动态生成的列名获取对应X94列的值%in% fruit_list$fruit:直接匹配fruit_list中的水果值,无需手动拼接正则表达式
运行后输出结果:
1_X94 2_X94 1_X09 2_X09 1_X38 2_X38 1 apple apple 1 4 green green 2 lemon strawberry 2 5 yellow red 3 orange lemon 3 6 orange yellow
内容的提问来源于stack exchange,提问作者hy9fesh
相关产品推荐
相关产品推荐

