我有這個矢量myvec
。我想在秒後刪除所有內容:'並獲得結果。如何在nth':'後刪除字符串?如何刪除R中第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
。我想在秒後刪除所有內容:'並獲得結果。如何在nth':'後刪除字符串?如何刪除R中第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
我們可以使用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 <- 3
,並重復同樣的步驟
sub(pat, '\\1', myvec)
#[1] "chr2:213403244:213403244" "chr7:55240586:55240586"
#[3] "chr7:55241607:55241607"
或者另一種選擇被拆分爲:
,然後再將paste
這n個組件組合在一起。
n <- 2
vapply(strsplit(myvec, ':'), function(x)
paste(x[seq.int(n)], collapse=':'), character(1L))
#[1] "chr2:213403244" "chr7:55240586" "chr7:55241607"
以下是幾種選擇。在我們刪除第k個冒號後面的所有內容。問題中的示例將對應於k = 2。在下面的示例中,我們使用k = 3。
1)read.table將數據讀入數據。幀,挑出所需的列和它一起再次粘貼回:
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 /子構建在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:這裏是一個可視化
^((.*?:){2}.*?):.*
:正規正則表達式
k
等於3的
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和子的解決方案是最快的,雖然它使用一個複雜的正則表達式,而其他人使用簡單或沒有正則表達式,並可能因簡單性而被優選。
ADDED增加了額外的解決方案和附加註釋。
謝謝,你能解釋一下在這裏做什麼。我們如何使用這個nth':'? – MAPK
沒有意識到你有我發佈的解決方案,所以我刪除它。 – hwnd