这里有一些选择。我们删除第 k 个冒号及其后的所有内容。问题中的示例对应于 k = 2。在下面的示例中,我们使用 k = 3。
1) read.table 将数据读取到 data.frame 中,挑选出所需的列并将其重新粘贴在一起:
k <- 3 # keep first 3 fields only
do.call(paste, c(read.table(text = myvec, sep = ":")[1:k], sep = ":"))
给予:
[1] "chr2:213403244:213403244" "chr7:55240586:55240586"
[3] "chr7:55241607:55241607"
2) sprintf/sub 构造适当的正则表达式(在下面的 k 等于 3 的情况下,它将是 ^((.*?:){2}.*?):.* )并将其与 sub 一起使用:
k <- 3
sub(sprintf("^((.*?:){%d}.*?):.*", k-1), "\\1", myvec)
给予:
[1] "chr2:213403244:213403244" "chr7:55240586:55240586"
[3] "chr7:55241607:55241607"
注 1: 对于 k=1,可以进一步简化为 sub(":.*", "", myvec),对于 k=n-1,可以进一步简化为 sub(":[^:]*$", "", myvec)
注2:这是k等于3的正则表达式的可视化:
^((.*?:){2}.*?):.*
Debuggex Demo
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)
如果我们想自动设置 n,我们可以选择将上面的硬编码行设置 n 替换为:
n <- count.fields(textConnection(myvec[1]), sep = ":")
4) 定位第 k 个冒号的位置 使用gregexpr 定位冒号的位置,然后提取第 k 个的位置减去一个,因为我们不想要尾随冒号。使用substr 从相应的字符串中提取那么多字符。
k <- 3
substr(myvec, 1, sapply(gregexpr(":", myvec), "[", k) - 1)
给予:
[1] "chr2:213403244:213403244" "chr7:55240586:55240586"
[3] "chr7:55241607:55241607"
注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]
给予:
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
使用 sprintf 和 sub 的解决方案是最快的,尽管它确实使用了复杂的正则表达式,而其他解决方案使用更简单的正则表达式或不使用正则表达式,并且出于简单的原因可能更受欢迎。
添加添加了额外的解决方案和额外的注释。