在R tidyverse中处理列名:移除第一组数字并保留指定内容
解决Tidyverse中列名的数字提取与重命名问题
要实现将var1_1975这类列名转换为var_75的需求,无需分两次调用rename_with,用一次正则替换就能高效完成,同时避免原代码中出现的拼接错误。
问题分析
原代码的问题在于第二次rename_with中使用了全局的cols向量,导致每个列名会拼接所有年份后缀(比如var_1975会变成var_1975_75_76),不符合预期。
正确实现代码
library(tidyverse) # 创建示例数据框 df <- data.frame("var1_1975" = c(1:5), "var1_1976" = c(3,2,1,1,1), "age" = c(25,41,39,60,36) , "satisfaction" = c(5,3,2,5,4) ) # 一次性完成列名修改 df <- df %>% rename_with( # 正则捕获需要保留的部分,替换掉冗余数字 .fn = ~ gsub("(var)\\d+_19(\\d{2})", "\\1_\\2", .x), # 只处理以var开头的列 .cols = starts_with("var") )
正则说明
(var):捕获要保留的基础字符前缀(如果前缀不是固定var,可以改成([a-zA-Z]+)匹配任意字母组合)\\d+:匹配并移除前缀后的多余数字(比如var1中的1)_19(\\d{2}):匹配年份的前两位19,并捕获后两位数字(比如1975中的75)\\1_\\2:将捕获的前缀和年份后两位拼接成新列名
扩展通用场景
如果你的列名前缀不固定(比如abc2_2023要转成abc_23),只需调整正则即可:
df <- df %>% rename_with( .fn = ~ gsub("([a-zA-Z]+)\\d+_\\d{2}(\\d{2})", "\\1_\\2", .x), .cols = matches("[a-zA-Z]+\\d+_\\d{4}") )
内容的提问来源于stack exchange,提问作者saddas
相关产品推荐
相关产品推荐

