示例载体(基因转录本ID):
a <- c('MSTRG.7176.1', 'MSTRG.7176.2', 'AT2G26340.2', 'AT2G26355.1')
这是一个长向量的子集,如何删除以“ MS”开头的项目,然后切除剩余项目的末2位数字?
答案 0 :(得分:7)
如果我们要像@sindri_baldur所提到的那样完全避免正则表达式,可以使用
string <- a[!startsWith(a, "MS")]
substr(string, 1, nchar(string) - 2)
或者使用grep
和substr
string <- grep('^MS',a, invert = TRUE, value = TRUE)
substr(string, 1, nchar(string) - 2)
#[1] "AT2G26340" "AT2G26355"
由于我们有很多新的答案添加基准,包括所有长度为400k的向量。
a <- c('MSTRG.7176.1', 'MSTRG.7176.2', 'AT2G26340.2', 'AT2G26355.1')
a <- rep(a, 100000)
library(microbenchmark)
microbenchmark(
ronak1 = {string <- a[!startsWith(a, "MS")];substr(string, 1, nchar(string) - 2)},
ronak2 = {string <- grep('^MS',a, invert = TRUE, value = TRUE);substr(string, 1, nchar(string) - 2)},
sotos = {word(a[!str_detect(a, '^MS')], 1, sep = fixed('.'))},
thothal = {b1 <- a[!grepl("^MS", a)];gsub("\\.[0-9]$", "", b1)},
zx8754 = tools::file_path_sans_ext(a[ !grepl("^MS", a) ]),
tmfmnk = dirname(chartr(".", "/", a[!grepl("^MS", a)])),
NelSonGon = {b<-stringi::stri_replace_all(stringi::stri_sub(a,1,-3),regex="^M.*","");b[grepl('\\w+',b)]}
)
#Unit: milliseconds
# expr min lq mean median uq max neval
# ronak1 34.75928 38.58217 45.63393 40.32845 44.24355 225.2581 100
# ronak2 94.10687 96.72758 110.83819 99.26914 105.98822 938.2969 100
# sotos 1926.21112 2500.27209 2852.43240 2861.61699 3173.10420 4478.7890 100
# thothal 155.95328 160.62800 169.02275 164.46494 169.32770 218.5033 100
# zx8754 172.96970 179.03618 186.12374 183.96887 188.06251 234.1895 100
# tmfmnk 189.29085 195.14593 208.89245 199.47172 204.40604 547.7497 100
# NelSonGon 186.54426 198.29856 226.19221 206.54542 217.92970 948.2535 100
答案 1 :(得分:5)
这里也是stringr
一线,
library(stringr)
word(a[!str_detect(a, '^MS')], 1, sep = fixed('.'))
#[1] "AT2G26340" "AT2G26355"
答案 2 :(得分:3)
代码
a <- a[!grepl("^MS", a)]
gsub("\\.[0-9]$", "", a)
# [1] "AT2G26340" "AT2G26355"
说明
regex
过滤掉所有以MS
开头的元素regex
替换其余元素中的点和最后一位数字答案 3 :(得分:2)
由于人类大约有20万笔成绩单,因此这是基准:
a <- c('MSTRG.7176.1', 'MSTRG.7176.2', 'AT2G26340.2', 'AT2G26355.1')
a <- rep(a, 25000)
library(stringr)
bench::mark(
x1 = {
string <- grep('^MS',a, invert = TRUE, value = TRUE)
substr(string, 1, nchar(string) - 2) },
x2 = {
string <- a[!startsWith(a, "MS")]
substr(string, 1, nchar(string) - 2)},
x3 = {
word(a[!str_detect(a, '^MS')], 1, sep = fixed('.'))
},
x4 = {
gsub("\\.[0-9]$", "", a[ !grepl("^MS", a) ])},
x5 = {
tools::file_path_sans_ext(a[ !grepl("^MS", a) ])
}
)
# A tibble: 5 x 14
# expression min mean median max `itr/sec` mem_alloc n_gc n_itr total_time result memory time gc
# <chr> <bch:tm> <bch:tm> <bch:t> <bch:t> <dbl> <bch:byt> <dbl> <int> <bch:tm> <list> <list> <lis> <lis>
# x1 20.3ms 21.3ms 21ms 28.1ms 46.9 1.91MB 1 24 512ms <chr ~ <Rprof~ <bch~ <tib~
# x2 11.7ms 12.6ms 12.3ms 17.8ms 79.3 2.86MB 3 40 505ms <chr ~ <Rprof~ <bch~ <tib~
# x3 668.5ms 668.5ms 668.5ms 668.5ms 1.50 10.54MB 9 1 668ms <chr ~ <Rprof~ <bch~ <tib~
# x4 23.8ms 24.6ms 24.1ms 32.2ms 40.7 2.1MB 1 21 516ms <chr ~ <Rprof~ <bch~ <tib~
# x5 33.8ms 35.2ms 34.7ms 40.9ms 28.4 2.1MB 1 15 528ms <chr ~ <Rprof~ <bch~ <tib~
答案 4 :(得分:1)
将它们视为文件名并删除扩展名:
tools::file_path_sans_ext(a[ !grepl("^MS", a) ])
# [1] "AT2G26340" "AT2G26355"
答案 5 :(得分:0)
您也可以尝试:
dirname(chartr(".", "/", a[!grepl("^MS", a)]))
[1] "AT2G26340" "AT2G26355"
首先,使用grepl()
标识以MS
开头的案例。其次,它使用.
将/
替换为chartr()
。最后,dirname()
返回直到最后一个/
的部分字符串。
考虑到可能有些元素不是以MS
开头,而是包含两个或多个小数,可以使用:
chartr("/", ".", dirname(chartr(".", "/", a[!grepl("^MS", a)])))
与第一种可能性相同,但是它将其余的/
替换回.
。
或者用chartr()
替换gsub()
的第二种可能性:
gsub("/", ".", dirname(gsub(".", "/", a[!grepl("^MS", a)], fixed = TRUE)),
fixed = TRUE)
答案 6 :(得分:0)
提供stringi
的可能性:我更喜欢一种衬板,但也许两行解决方案就足够了。
b<-stringi::stri_replace_all(stringi::stri_sub(a,1,-3),regex="^M.*","")
b[grepl('\\w+',b)]
#[1] "AT2G26340" "AT2G26355"
答案 7 :(得分:0)
我看不到sub()
和startsWith()
的组合,所以
sub(".{2}$", "", a[!startsWith(a, "MS")])
# [1] "AT2G26340" "AT2G26355"