使用正则表达式修改DataFrame指定列名失败问题求助
问题:DataFrame第10列到倒数第二列重命名失效
问题说明
尝试重命名DataFrame中第10列到倒数第二列的列名,但执行现有代码后列名完全未修改。
现有代码
all.lesions <- data.frame(t(apply(all.lesions, 1, unlist)), check.names = FALSE) colnames(all.lesions[10:ncol(all.lesions)-1]) <- sub('^([^.]+.[^.]+.[^.]+.[^.]+).*', '\1', colnames(all.lesions[10:ncol(all.lesions)-1])) colnames(all.lesions[10:ncol(all.lesions)-1]) <- substring(colnames(all.lesions[10:ncol(all.lesions)-1]), 1, nchar(colnames(all.lesions[10:ncol(all.lesions)-1]))-1)
输入数据
数据片段
> dput(all.lesions[1:2,c(9:16,length(colnames(all.lesions)))]) structure(list(Amplitude.Threshold = c("0: t<0.1; 1: 0.1<t< 0.9; 2: t>0.9", "0: t<0.1; 1: 0.1<t< 0.9; 2: t>0.9"), TCGA.2K.A9WE.01A.11D.A381.01 = c(0, 0), TCGA.2Z.A9J1.01A.11D.A381.01 = c(0, 0), TCGA.2Z.A9J2.01A.11D.A381.01 = c(0, 0), TCGA.2Z.A9J3.01A.12D.A381.01 = c(0, 0), TCGA.2Z.A9J5.01A.21D.A381.01 = c(1, 1), TCGA.2Z.A9J6.01A.11D.A381.01 = c(0, 0), TCGA.2Z.A9J7.01A.11D.A381.01 = c(0, 0), X = c(NA, NA)), row.names = 1:2, class = "data.frame")
目标列范围的列名(第10列到最后一列)
> dput(names(all.lesions)[10:ncol(all.lesions)]) c("TCGA.2K.A9WE.01A.11D.A381.01", "TCGA.2Z.A9J1.01A.11D.A381.01", "TCGA.2Z.A9J2.01A.11D.A381.01", "TCGA.2Z.A9J3.01A.12D.A381.01", "TCGA.2Z.A9J5.01A.21D.A381.01", "TCGA.2Z.A9J6.01A.11D.A381.01", "X")
对象类型
> class(all.lesions) [1] "data.frame" > typeof(all.lesions) [1] "list"
预期输出
重命名后的目标列名:
[1] "TCGA.2K.A9WE.01" "TCGA.2Z.A9J1.01" "TCGA.2Z.A9J2.01" [4] "TCGA.2Z.A9J3.01" "TCGA.2Z.A9J5.01" "TCGA.2Z.A9J6.01"
错误原因
- 索引运算优先级错误:
10:ncol(all.lesions)-1会先生成10到总列数的序列,再对每个元素减1,导致索引范围完全偏离预期。正确写法是用括号明确优先级:10:(ncol(all.lesions)-1),先计算倒数第二列的位置,再生成目标列序列。 - 正则捕获组转义错误:
sub函数中的\1未正确转义,R中需要写成\\1才能引用正则捕获组,否则无法提取目标子串。
修正后的代码
# 保留原数据转换逻辑 all.lesions <- data.frame(t(apply(all.lesions, 1, unlist)), check.names = FALSE) # 定义目标列范围:第10列到倒数第二列 target_cols <- 10:(ncol(all.lesions)-1) # 提取列名中前四个部分的前两位数字(如TCGA.2K.A9WE.01) colnames(all.lesions)[target_cols] <- sub('^([^.]+\\.[^.]+\\.[^.]+\\.[0-9]{2}).*', '\\1', colnames(all.lesions)[target_cols])
或者结合原代码的两步逻辑,修正后:
all.lesions <- data.frame(t(apply(all.lesions, 1, unlist)), check.names = FALSE) target_cols <- 10:(ncol(all.lesions)-1) # 第一步:提取前四个以点分隔的片段 temp_names <- sub('^([^.]+\\.[^.]+\\.[^.]+\\.[^.]+).*', '\\1', colnames(all.lesions)[target_cols]) # 第二步:去掉片段的最后一个字符(如01A→01) colnames(all.lesions)[target_cols] <- substring(temp_names, 1, nchar(temp_names)-1)
内容的提问来源于stack exchange,提问作者Anon
相关产品推荐
相关产品推荐

