我有一个名为 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中实现这个吗?
答案 0 :(得分:8)
正则表达式" ["运算符定义了一个字符类,在字符类中定义了" ^"第一个位置的算子做否定;
?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"
答案 1 :(得分:5)
如果尺寸变化/不能保证nchar
,您可以使用str_split_fixed()
中的stringr
。
stringr
解决方案:library(stringr)
name <- 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")
apply(str_split_fixed(name,"-",5)[,1:4],1,paste0,collapse="-")
会给你什么:
## "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"
str_split_fixed(name,"-",5)
根据name
5
的每个向量元素拆分为-
个部分
[,1:4]
保留每个name
元素的前4个部分(结果矩阵的列)
apply(...,1,paste0,collapse="-")
将它们粘贴在一起使用"-"
折叠以恢复名称(按行)
我在这里将stringr
+ apply()
方法与@BondedDust grep
方法和基本strsplit
方法进行比较。
首先,让我们将它提升到一万个名字:
name <- rep(name,3.334e3)
然后是一个微基准:
microbenchmark(
stringr_apply = apply(str_split_fixed(name,"-",5)[,1:4],1,paste0,collapse="-"),
grep_ninja = sub("^([^-]*[-][^-]*[-][^-]*[-][^-]*)([-].*$)", "\\1", name),
strsplit = sapply( lapply( strsplit(name, "\\-"), "[", 1:4), paste, collapse="-"),
times=25)
并获得:
# 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倍。
答案 2 :(得分:2)
我想你可能想要substr
:
names <- substr(names,start=1,stop=16)
colnames(myDF) <- names
这将使用您指定的子字符串覆盖原始names
。 names
是您的名称变量,start
是第一个字符,stop
是最后一个字符。然后,您可以使用names
覆盖data.frame或其他任何内容的名称。
答案 3 :(得分:1)
stringr
包的另一个选项(虽然比@ BondedDust的答案慢得多):
library('stringr')
str_match(name, "^([^-]*[-][^-]*[-][^-]*[-][^-]*)")[, 1]
答案 4 :(得分:1)
如果所有第五组字母数字以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"
或者相同的块始终以1
开头,但不会以R
结尾。
> gsub("-[1-9]{2}[A-Z]{1}.*", "", txt)
你也可以在strsplit
中使用正则表达式,我在其他回复中没有看到太多。
> unlist(strsplit(txt, "-[1-9]{2}[A-Z].*"))
# [1] "TCGA-OL-A66N-01A" "TCGA-OL-A66O-01A" "TCGA-OL-A66P-01A"
我寻找一个好的模式,以避免写一个过长,混乱的正则表达式。