Regex 如何在R中编辑colnames?

Regex 如何在R中编辑colnames?,regex,r,Regex,R,我有一个名为name的变量,我想将它设置为矩阵的列名,但在执行此操作之前,我需要编辑名为name的变量内部的名称 >name [722] "TCGA-OL-A66N-01A-12R-A31S-13.isoform.quantification.txt" [723] "TCGA-OL-A66O-01A-11R-A31S-13.isoform.quantification.txt" [724] "TCGA-OL-A66P-01A-11R-A31S-13.isoform.quantificati

我有一个名为name的变量,我想将它设置为矩阵的列名,但在执行此操作之前,我需要编辑名为name的变量内部的名称

>name
[722] "TCGA-OL-A66N-01A-12R-A31S-13.isoform.quantification.txt"
[723] "TCGA-OL-A66O-01A-11R-A31S-13.isoform.quantification.txt"
[724] "TCGA-OL-A66P-01A-11R-A31S-13.isoform.quantification.txt"
我只想把这些字母放在第四个
-

预期产出:

  >name
    [722] "TCGA-OL-A66N-01A"
    [723] "TCGA-OL-A66O-01A"
    [724] "TCGA-OL-A66P-01A"

有人能帮我在R中实现这个吗

我想您可能需要
substr

names <- substr(names,start=1,stop=16)
colnames(myDF) <- names

names如果大小不同/不保证
nchar
您可以使用
str\u split\u fixed()
from
stringr

stringr
解决方案: 说明:
  • str\u split\u fixed(名称“-”,5)
根据
-

  • [,1:4]
为每个
name
元素保留前4个部分(生成矩阵的列)

  • apply(…,1,paste0,collapse=“-”)
使用
“-”
来恢复名称(按行)将它们粘贴在一起


但是如果我有很多名字呢? 这里,我将我的
stringr
+
apply()
方法与@bondedust
grep
方法和基本
strsplit
方法进行比较

首先,让我们把它增加到一万个名字:

name <- rep(name,3.334e3)
并获得:

#  Unit: milliseconds
#  expr             min       lq    median        uq       max    neval
# stringr_apply 845.44542 874.5674 899.27849 941.22628 976.88903    25
# grep_ninja     25.51796  25.7066  25.85404  25.95922  27.89165    25
# strsplit      115.10626 123.2645 126.45171 130.10334 147.39517    25
似乎
base
模式匹配/替换可以更好地扩展…在这里大约一秒钟,或者比最慢的方式快30倍。

正则表达式“[”操作符定义一个字符类,在字符类中,第一个位置的“^”操作符进行反运算

?regex
?sub

sub("^([^-]*[-][^-]*[-][^-]*[-][^-]*)([-].*$)", "\\1", name)
[1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"
这将比str_split方法更简单(IMO)

 sapply( lapply( strsplit(name, "\\-"), "[", 1:4),   
                # extracted the first 4 elements from each list element returned by strsplit
         paste, collapse="-")  # 'collapse' needed rather than 'sep'

#[1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"

另一个带有
stringr
包的选项(尽管仍然比@bondedust的答案慢得多):


如果所有第五组字母数字都以
R
结尾

> txt <- c("TCGA-OL-A66N-01A-12R-A31S-13.isoform.quantification.txt",
           "TCGA-OL-A66O-01A-11R-A31S-13.isoform.quantification.txt",
           "TCGA-OL-A66P-01A-11R-A31S-13.isoform.quantification.txt")

> gsub("-[0-9]{2}R.*", "", txt)
# [1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"
您还可以在
strsplit
中使用正则表达式,这在其他响应中我没有看到太多

> unlist(strsplit(txt, "-[1-9]{2}[A-Z].*"))
# [1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"

我在寻找一个好的模式,以避免编写过长、混乱的正则表达式。

什么是myname?您能提供更多的说明吗?看起来非常慢和复杂,需要额外的包。
strsplit
如果您不想使用正则表达式方法,可能更容易说明。@BondedDest见到您后我非常同意r答案(因此向上投票)。我想看看它是否缩放——编辑答案以添加一个小基准。它和怀疑的完全一样。谢谢你的启发。谢谢。
strsplit
方法也比
str_split
方法快了5.Nice。另外,你可以使用
([^-]*[-]){3}
表示该子模式的三个重复,如:
sub(^([^-]*[-]){3}[^-]*)([-].$),“\\1”,name)
strsplit
是我的方式。有时速度不如准确性重要,但这两者都有。
 sapply( lapply( strsplit(name, "\\-"), "[", 1:4),   
                # extracted the first 4 elements from each list element returned by strsplit
         paste, collapse="-")  # 'collapse' needed rather than 'sep'

#[1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"
library('stringr')
str_match(name, "^([^-]*[-][^-]*[-][^-]*[-][^-]*)")[, 1]
> txt <- c("TCGA-OL-A66N-01A-12R-A31S-13.isoform.quantification.txt",
           "TCGA-OL-A66O-01A-11R-A31S-13.isoform.quantification.txt",
           "TCGA-OL-A66P-01A-11R-A31S-13.isoform.quantification.txt")

> gsub("-[0-9]{2}R.*", "", txt)
# [1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"
> gsub("-[1-9]{2}[A-Z]{1}.*", "", txt)
> unlist(strsplit(txt, "-[1-9]{2}[A-Z].*"))
# [1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"