Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何删除第n个分隔符后的所有内容?_R_Regex - Fatal编程技术网

R 如何删除第n个分隔符后的所有内容?

R 如何删除第n个分隔符后的所有内容?,r,regex,R,Regex,我有这个向量myvec。我想删除第二个“:”之后的所有内容并获得结果。如何删除第n个“:”之后的字符串 myvec<- c("chr2:213403244:213403244:G:T:snp","chr7:55240586:55240586:T:G:snp" ,"chr7:55241607:55241607:C:G:snp") result chr2:213403244 chr7:55240586 chr7:55241607 myvec我们可以使用sub。我们匹配一个或多个非:,

我有这个向量
myvec
。我想删除第二个“:”之后的所有内容并获得结果。如何删除第n个“:”之后的字符串

myvec<- c("chr2:213403244:213403244:G:T:snp","chr7:55240586:55240586:T:G:snp" ,"chr7:55241607:55241607:C:G:snp")

result
chr2:213403244   
chr7:55240586
chr7:55241607

myvec我们可以使用
sub
。我们匹配一个或多个非
,从字符串(
^([^::+
)开始,后跟一个
,后跟一个非
[^:::::+
)的字符,将其放在捕获组中,即括号内。我们在替换中用捕获组(
\\1
)替换

sub('^([^:]+:[^:]+).*', '\\1', myvec)
#[1] "chr2:213403244" "chr7:55240586"  "chr7:55241607" 
以上内容适用于发布的示例。对于第n个分隔符之后要删除的一般情况

n <- 2
pat <- paste0('^([^:]+(?::[^:]+){',n-1,'}).*')
sub(pat, '\\1', myvec)
#[1] "chr2:213403244" "chr7:55240586"  "chr7:55241607" 

或者另一个选项是按
拆分,然后
将n个组件粘贴在一起

n <- 2
vapply(strsplit(myvec, ':'), function(x)
            paste(x[seq.int(n)], collapse=':'), character(1L))
#[1] "chr2:213403244" "chr7:55240586"  "chr7:55241607" 

n这里有几个备选方案。我们删除第k个冒号及其后的所有内容。问题中的示例对应于k=2。在下面的示例中,我们使用k=3

1)读取.表格将数据读取到data.frame中,选择所需的列并再次将其粘贴在一起:

k <- 3 # keep first 3 fields only
do.call(paste, c(read.table(text = myvec, sep = ":")[1:k], sep = ":"))
2)sprintf/sub构造适当的正则表达式(在下面k等于3的情况下,它将是
^((.*?:){2}.*?:..*
)并与
sub一起使用:

k <- 3
sub(sprintf("^((.*?:){%d}.*?):.*", k-1), "\\1", myvec)
注1:对于k=1,可以进一步简化为
sub(“:*”,“”,myvec)
对于k=n-1,可以进一步简化为
sub(“:[^::*”,“”,myvec)

注2:这里是
k
等于3的正则表达式的可视化:

^((.*?:){2}.*?):.*

3)迭代删除最后一个字段我们可以使用上面注释1中的最后一个正则表达式多次删除最后一个字段
n-k
,如下所示:

n <- 6 # number of fields
k < - 3 # number of fields to retain
out <- myvec
for(i in seq_len(n-k)) out <- sub(":[^:]*$", "", out)
给予:

[1] "chr2:213403244:213403244" "chr7:55240586:55240586"  
[3] "chr7:55241607:55241607"  
[1] "chr2:213403244:213403244" "chr7:55240586:55240586"  
[3] "chr7:55241607:55241607"  
[1] "chr2:213403244:213403244" "chr7:55240586:55240586"  
[3] "chr7:55241607:55241607"  
          test replications elapsed relative
2 .sprintf.sub         1000    0.11    1.000
4    .gregexpr         1000    0.14    1.273
3         .for         1000    0.15    1.364
1  .read.table         1000    2.16   19.636
注3:假设有n个字段。问题要求删除第k个分隔符之后的所有内容,以便解决方案适用于k=1,2,…,n-1。它不需要为k=n工作,因为没有n个分隔符;然而,如果我们将k定义为要返回的字段数,那么k=n是有意义的,事实上,(1)和(3)在这种情况下也起作用。(2) (4)不适用于此扩展,但我们可以使用
paste0(myvec,“:”)
作为输入,而不是
myvec
,轻松地让它们工作

注4:我们比较性能:

library(rbenchmark)
benchmark(
 .read.table = do.call(paste, c(read.table(text = myvec, sep = ":")[1:k], sep = ":")),
 .sprintf.sub = sub(sprintf("^((.*?:){%d}.*?):.*", k-1), "\\1", myvec),
 .for = { out <- myvec; for(i in seq_len(n-k)) out <- sub(":[^:]*$", "", out)},
 .gregexpr = substr(myvec, 1, sapply(gregexpr(":", myvec), "[", k) - 1),
  order = "elapsed", replications = 1000)[1:4]
使用sprintf和sub的解决方案是最快的,尽管它确实使用了复杂的正则表达式,而其他解决方案则使用更简单或没有正则表达式,并且出于简单性的考虑,可能是首选方案

添加了添加了附加解决方案和附加注释

k <- 3
substr(myvec, 1, sapply(gregexpr(":", myvec), "[", k) - 1)
[1] "chr2:213403244:213403244" "chr7:55240586:55240586"  
[3] "chr7:55241607:55241607"  
library(rbenchmark)
benchmark(
 .read.table = do.call(paste, c(read.table(text = myvec, sep = ":")[1:k], sep = ":")),
 .sprintf.sub = sub(sprintf("^((.*?:){%d}.*?):.*", k-1), "\\1", myvec),
 .for = { out <- myvec; for(i in seq_len(n-k)) out <- sub(":[^:]*$", "", out)},
 .gregexpr = substr(myvec, 1, sapply(gregexpr(":", myvec), "[", k) - 1),
  order = "elapsed", replications = 1000)[1:4]
          test replications elapsed relative
2 .sprintf.sub         1000    0.11    1.000
4    .gregexpr         1000    0.14    1.273
3         .for         1000    0.15    1.364
1  .read.table         1000    2.16   19.636