部分字符串与新列中的匹配正则表达式匹配 - R

问题描述:

我想用正则表达式字符串部分匹配数据集中列的内容。然后我想要匹配的行在新列中返回特定匹配的正则表达式。我的实际数据集很大(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

基本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的做事方式!出于兴趣,每个人都跑了一段时间 - 请参阅下面的答案 –

我想这会做什么?

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能够理解汇总字符串,即模式

+0

很高兴听到。作为未来的一个提示,如果您将几行最终结果作为示例输出结果,您的问题就会变得更加清晰。当我发布这个答案时,我已经读了三次你的问题,我只有大约70%确定这是你想要的。 – Gregor

+0

感谢指针,发布堆栈溢出以及关于数据处理主题的新内容,以便了解将使事情变得更清楚的内容。另外还有一点需要注意的是,这个解决方案对于我的实际数据集完全适用......由于提取第一个匹配(如您所注意的),必须适应一些reg ex的更具体的内容,但这很容易,可能真的使复杂的进一步分析。再次感谢! –

运行时间比较扩大到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行)上尝试一下,看看它是否继续击败软件包版本。干杯!