2015-10-06 115 views
2

我想用正則表達式字符串部分匹配數據集中列的內容。然後我想要匹配的行在新列中返回特定匹配的正則表達式。我的實際數據集很大(130萬行),包含300個正則表達式,因此找到一種自動完成此操作的方法非常重要,因此添加新的正則表達式不需要進行代碼調整。部分字符串與新列中的匹配正則表達式匹配 - R

爲了證明:

try.dat<-data.frame(c(1:10),c("hello","goodbye","tidings","partly","totally")) 
names(try.dat)[1]<-"num" 
names(try.dat)[2]<-"words" 
try.dat 

在這種情況下,如果一個正則表達式是「LY」我想在匹配的行(部分,完全)具有與「LY」的列,以及一些「非在其他行中匹配'的術語。我已經成功地使用grepl(subset not based on exact match)成功地對數據進行子集化,這很好地工作,但是這是我真正努力的下一步!

我有一些進步在嘗試這個,主要是基於我已經適應了這樣的代碼的建議(partial string matching R):

pattern<-c("ll|ood") 
matching<-c("ood","ll") 
regexes<-data.frame(pattern,matching) 
output_vector<-character(nrow(try.dat)) 
for(i in seq_along(regexes)){ 
output_vector[grepl(x=try.dat$words,pattern=regexes[[i]][1])] <- regexes [[i]][2]  
} 
try.dat$match<- output_vector 
try.dat 

正如你可以看到這下返回一個「1」匹配的行 - 到達那裏,但我已經用完了想法!我想知道是否有人可以提供任何指針?

謝謝!

+0

不知道你想要輸出什麼。正則表達式匹配嗎?你可以發佈所需的輸出列嗎? –

+0

是的,你是對的@PierreLafortune所以對於單詞'部分'和正則表達式'ly',我想'ly'在匹配列中擴展,我的實際數據集基於醫藥處方的項目代碼,這些醫藥處方在拼寫/商品名稱等方面有所不同 - 我的正則表達式將提供與標準化詞組的鏈接,從而使我能夠將物品代碼與實際產品分配相匹配 - 很難解釋何時數據集太大而無法發佈! –

+0

如果你想知道哪個模式匹配,你需要做兩個'grep'。如果*兩者匹配,您還應該有一個應急計劃。如果你統一你的例子,你的問題會更清楚。你最初談論的是匹配'「ly」',但是當你分享代碼的時候它就是''llod'''。 – Gregor

回答

1

基本R選項。只是因爲。基於數據集兩者的

patt <- c("ll", "ood") 
for (i in 1: length(patt)) { 
    try.dat[grep(patt[i], try.dat$words), "match"] <- patt[i] 
} 
try.dat 
# num words match 
#1 1 hello ll 
#2 2 goodbye ood 
#3 3 tidings <NA> 
#4 4 partly <NA> 
#5 5 totally ll 
#6 6 hello ll 
#7 7 goodbye ood 
#8 8 tidings <NA> 
#9 9 partly <NA> 
#10 10 totally ll 
+0

感謝 - 有趣和總是很高興看到一個基地R的做事方式!出於興趣,每個人都跑了一段時間 - 請參閱下面的答案 –

2

我想這會做什麼?

library(stringr) 
try.dat$match = str_extract(try.dat$words, "ll|ood") 
try.dat 
# num words match 
# 1 1 hello ll 
# 2 2 goodbye ood 
# 3 3 tidings <NA> 
# 4 4 partly <NA> 
# 5 5 totally ll 
# 6 6 hello ll 
# 7 7 goodbye ood 
# 8 8 tidings <NA> 
# 9 9 partly <NA> 
# 10 10 totally ll 

默認行爲是提取第一個匹配項。如果你想獲得所有匹配,你可以使用str_extract_all,但在這種情況下你需要一個非data.frame設置來處理不同數量的匹配。

+0

太棒了,謝謝!適用於我的數據集 - 對您不感興趣,因爲我的實際數據集有許多註冊表項我已經進行了快速檢查,以確保str_extract能夠理解彙總字符串,即模式< - 「ll | ood」,它可以執行此操作。至於第一場比賽,我已經在我的註冊前工作,所以應該只有一場比賽 - 所以希望不會擔心str_extract_all。我將在明天工作的完整數據集中介紹這一點,並讓您知道我如何繼續。 –

+0

很高興聽到。作爲未來的一個提示,如果您將幾行最終結果作爲示例輸出結果,您的問題就會變得更加清晰。當我發佈這個答案時,我已經讀了三次你的問題,我只有大約70%確定這是你想要的。 – Gregor

+0

感謝指針,發佈堆棧溢出以及關於數據處理主題的新內容,以便了解將使事情變得更清楚的內容。另外還有一點需要注意的是,這個解決方案對於我的實際數據集完全適用......由於提取第一個匹配(如您所注意的),必須適應一些reg ex的更具體的內容,但這很容易,可能真的使複雜的進一步分析。再次感謝! –

0

運行時間比較擴大到10M行(的MacBook Pro OS X):

try.dat<-data.frame(c(1:10000000),c("hello","goodbye","tidings","partly","totally")) 
system.time(try.dat[str_extract(try.dat$words,"ll|ood"),"match"]) 

用戶系統經過

5.167 0.208 5.348

system.time(for (i in 1: length(patt)) {try.dat[grep(patt[i], try.dat$words), "match"] <- patt[i]}) 

用戶系統已過去

0.311 0.041 0.377

目前的跡象表明,基礎R版本可顯着提高效率。在我的實際數據集(400 < reg ex的超過2M行)上嘗試一下,看看它是否繼續擊敗軟件包版本。乾杯!