2013-08-26 18 views
2

我正在處理一個專門的文本文件,它基本上是一長串名稱和與每個名稱關聯的字母的隨機序列。我試圖提取我感興趣的特定共識序列。序列是,可以說「STXDXIK」,其中X是任何字母。我將該文本文件轉換爲R並將其命名爲「TEXT」。如何提取與正則表達式(regexpr)索引有關的文本R

然後我使用正則表達式來隔離包含序列的條目列表,將其稱爲「ylist」。

ylist<- TEXT[grep("ST[A-Z]D[A-Z]IK", TEXT, value=FALSE, perl=FALSE)] 

然後我用regexpr函數找到我感興趣的序列的位置,稱之爲「r」。

r<- regexpr("ST[A-Z]D[A-Z]IK", ylist) 

現在的問題是,我得到的位置的索引,該序列在於,與起始位置和匹配的數量。不過,我有興趣提取完整的序列,而不是從「ylist」的索引,因爲它對我來說很重要,全長序列是什麼。誰能幫忙?

我已經在R中嘗試了substr和regmatches函數,但substr必須應用於每個匹配,這對我來說並不實用,因爲我有許多與此序列匹配的匹配,並且regmatches似乎無法工作,讓它工作,也許是因爲我輸入了錯誤的命令。

+0

爲什麼你創建'ylist'?是不是'r < - regexpr(「ST [A-z] D [A-z] IK」,TEXT)'夠了? – sgibb

回答

1

使用一個for循環:

TEXT <- c("tedSTXDXIKsslker","janetlkajsdfSTXDXIKalkse","maggiesdfes","sdfjkSTXDXIKryan") 
ylist<- grep("ST[A-Z]D[A-Z]IK", TEXT, value=TRUE, perl=FALSE) 

r<- regexpr("ST[A-Z]D[A-Z]IK", ylist) 

strings <- character() 
for(i in seq_along(ylist)){strings <- c(strings,substr(ylist[i],start=r[i],stop=r[i]+6))} 

> strings 
[1] "STXDXIK" "STXDXIK" "STXDXIK" 

或者在使用stringr包一行。

require(stringr) 
> str_extract(string=TEXT,pattern="ST[A-Z]D[A-Z]IK") 
[1] "STXDXIK" "STXDXIK" NA  "STXDXIK" 

strings2 <- str_extract(string=TEXT,pattern="ST[A-Z]D[A-Z]IK") 
strings2 <- strings2[!is.na(strings2)] 
> strings2 
[1] "STXDXIK" "STXDXIK" "STXDXIK" 
+0

非常感謝,它的作品!另外for循環可以讓我通過簡單地將正數或負數添加到substr部分來查看我序列周圍的側面序列。 – Bez

3

您可以結合regexprsubstr

TEXT <- c("tedSTXDXIKsslker","janetlkajsdfSTXDXIKalkse","maggiesdfes","sdfjkSTXDXIKryan") 
r <- regexpr("ST[A-z]D[A-z]IK", TEXT) 
s <- substr(TEXT, r, r+attr(r, "match.length")-1) 
s 
# [1] "STXDXIK" "STXDXIK" ""  "STXDXIK" 

如果你要過濾的""您可以使用:

s <- s[nchar(s)>0] 
# [1] "STXDXIK" "STXDXIK" "STXDXIK" 

編輯:添加gregexpr例如

TEXT <- c("tedSTXDXIKsslker","janetlkajsdfSTXDXIKalkse","maggiesdfes","sdfjkSTXDXIKryan", 
     "sdfjkSTXDXIKryansdfjkSTXDXIKryan") 
## use gregexpr instead of regexpr 
r <- gregexpr("ST[A-z]D[A-z]IK", TEXT) 
## because gregexpr returns a list, we have to use mapply (or a for loop) 
## please note: I use substring instead of substr here because substr returns only a vector of the same size as the input vector. 
mapply(FUN=function(str, rx)substring(str, rx, rx+attr(rx, "match.length")-1), str=TEXT, rx=r) 

# $tedSTXDXIKsslker 
# [1] "STXDXIK" 
# 
# $janetlkajsdfSTXDXIKalkse 
# [1] "STXDXIK" 
# 
# $maggiesdfes 
# [1] "" 
# 
# $sdfjkSTXDXIKryan 
# [1] "STXDXIK" 
# 
# $sdfjkSTXDXIKryansdfjkSTXDXIKryan 
# [1] "STXDXIK" "STXDXIK" 
+0

不錯。我最初認爲'regexpr'返回了一個列表,所以當我嘗試將它傳遞給'substr'時,我試圖將列表的位置和長度作爲列表的元素進行索引 - 顯然這不起作用。我很高興看到如何更高效地使用它! – dayne

+0

@sgibb非常感謝這一點,它的工作原理!這也是一個很好的將substr和regexpr結合起來的方式!想知道如何修改上面的腳本來解釋單個條目中的多個序列匹配?我在上面的「r」參數中嘗試了gregexpr,它給了我多個序列匹配的正確索引,但「s」參數不起作用! – Bez

+0

@Bez:'gregexpr'返回一個列表。這就是爲什麼我們必須使用for循環或「mapply」。請參閱我的編輯。 – sgibb