如何在R语言中对数据框多列批量使用substr函数?
批量移除DataFrame多列字符串中的年份后缀
问题场景
假设我们有如下结构的DataFrame:
Column1, Column2, Column3 a_2019 b_2020 c_2021 d_2019 e_2020 f_2021 a_2019 b_2020 c_2021 d_2019 e_2020 f_2021
需要移除各列字符串中的_2019、_2020、_2021这类年份后缀。单独处理某一列时可以用:
df$Column1 <- substr(df$Column1, 1, nchar(df$Column1)-5)
但面对包含大量列的DataFrame时,直接调用df[,3:10]或lapply没生效,需要更优雅的批量处理方案。
解决方案
方法1:Base R 结合 lapply 批量处理
之前用lapply没生效,大概率是没把处理结果赋值回原DataFrame的对应列。只要完成赋值,就能轻松批量处理:
# 处理指定列(比如第3到10列) df[, 3:10] <- lapply(df[, 3:10], function(x) substr(x, 1, nchar(x)-5)) # 自动识别所有字符型列并处理 char_cols <- sapply(df, is.character) df[char_cols] <- lapply(df[char_cols], function(x) substr(x, 1, nchar(x)-5))
方法2:正则表达式灵活匹配(推荐)
如果年份后缀是_20xx格式,用正则表达式能匹配任意四位年份,比固定截取长度更鲁棒(比如避免遇到不符合长度的字符串出错):
# 处理指定列 df[, 3:10] <- lapply(df[, 3:10], function(x) sub("_20\\d{2}$", "", x)) # 处理所有字符型列 char_cols <- sapply(df, is.character) df[char_cols] <- lapply(df[char_cols], function(x) sub("_20\\d{2}$", "", x))
这里_20\\d{2}$表示匹配字符串结尾的_20加两位数字,sub函数会把匹配到的部分替换为空字符串,精准移除年份后缀。
方法3:tidyverse 管道风格处理
如果习惯用dplyr这类tidyverse工具,可以用管道语法批量处理,代码更易读:
library(dplyr) # 处理指定列 df <- df %>% mutate(across(3:10, ~sub("_20\\d{2}$", "", .x))) # 处理所有字符型列 df <- df %>% mutate(across(where(is.character), ~sub("_20\\d{2}$", "", .x)))
across是dplyr 1.0.0版本之后的推荐写法,替代了旧版的mutate_at,逻辑更清晰。
内容的提问来源于stack exchange,提问作者René Martínez
相关产品推荐
相关产品推荐

