R语言dataframe批量删除列名中_S*后缀的实现方法
原代码未达预期的核心原因
- 正则匹配范围错误:原代码使用的
\\_S*表达式,仅能匹配「1个下划线 + 0个或多个S」的片段。对MMR42_L_2_S52_L001_R1_001这类列名,该正则只会定位到_S这两个字符完成替换,根本不会清除后续的52_L001_R1_001内容,最终得到的列名是MMR42_L_252_L001_R1_001,和预期偏差极大。 - 函数传参逻辑错误:
rename_all、rename_with这类列名处理函数,会自动将每个列名逐一代入指定的处理规则,原代码手动将names(df1)整个列名向量传入sub,完全违背了函数逐值处理的运行逻辑。
正确实现方案
核心匹配规则调整
要实现“从_S起始位置删除到字符串末尾”的效果,需要将正则调整为_S.*$:
- 用
_S锁定测序样本后缀段的起始位置 - 用
.*匹配后缀段后续所有任意长度的字符 - 用
$锚定字符串末尾,确保清除从_S开始的全部内容
如果需要更严谨的匹配(避免列名前半段本身包含
_S字符导致的误删),可将正则调整为_S[0-9].*$,专门匹配_S后紧跟数字的测序样本后缀段,完全适配常规测序数据的列名格式。
可直接运行的代码
新版dplyr(1.0.0及以上版本,官方推荐写法)
library(dplyr) df1 %>% rename_with(~ sub("_S.*$", "", .x))
代码运行后得到的列名完全符合预期:
MMR42_L_2 MMR42_LN_2 MMR43_N_1 MMR48_N_1 MMR612 MMR658
旧版dplyr兼容写法
如果仍使用旧版dplyr的rename_all接口,可按如下方式修正原代码的错误:
df1 %>% rename_all(.funs = ~ sub("_S.*$", "", .))
内容的提问来源于stack exchange,提问作者Khaned
相关产品推荐
相关产品推荐

