2016-05-18 13 views
0

我的广告列表宠物数据帧查找字段:的R - 字符串中找到名称匹配使用正则表达式

ID Ad_title 
1  1 year old ball python 
2  Young red Blood python. - For Sale 
3  1 Year Old Male Bearded Dragon - For Sale 

我想在Ad_listing(即球pyton)采取共同的名字和用物种的拉丁文名称创建一个新字段。为了提供帮助,我还有另一个数据框,它具有拉丁名和通用名:

ID Latin_name   Common_name 
1  Python regius  E: Ball Python, Royal Python G: Königspython 
2  Python brongersmai E: Red Blood Python, Malaysian Blood Python 
3  Pogona barbata  E: Eastern Bearded Dragon, Bearded Dragon 

我该如何去做这件事?棘手的部分是常用名称隐藏在广告列表和Common_name中的文字之间。如果不是这种情况,我可以使用%in%。如果有一种方法/函数使用正则表达式,我认为这会有所帮助。

+0

你的输入文件都是字符串,对吗?您是否尝试修改第二个数据框,以便它成为所有常用名称的列表/矢量? – zyurnaidi

回答

0

显然你需要一个循环结构为所有的通用名称查找表和另一个循环,在做简单的正则表达式之前在逗号分隔这个复合字段。没有一个合理的正则表达式可以完成这一切。将来避免使用需要打包和拆包的打包/复合结构。它对于人类消费来说看起来很好,但是在语义上和计算机程序消耗方面,你有多个数据值打包在单个字段中,即它不是“通用名称”,而是你通过逗号分隔的“通用名称”。

对不起,如果我还没有提供R或任何具体的答案。我是一名技术老手,根据问题和可用资源使用多种语言/技术。你将需要遍历拉丁名称查找表的每个记录,在这个记录中,你将需要迭代逗号分隔的“通用名称”压缩字段,所以你一次只能使用一个通用名称。在整个输入文件中,您使用正则表达式或任何可用的方法搜索/替换该单一常用名称。这很简单明了,你需要从这一端开始,即查找表。你需要通过它来循环/循环。迭代/循环应该很熟悉,因为它是任何程序/脚本的基本构建块。这种程序逻辑不是正则表达式本身的能力(或期望的功能)的一部分。我假设你知道如何在R中创建一个迭代构造,或者你正在为此使用什么。

+0

你能详细说明你的循环结构是什么意思吗?另外,我希望我的数据结构更好 - 这不是选择这种方式。 –

1

对方回答做了很好的工作,概述了一般的逻辑,所以这里是一个简单的一些想法(虽然不是最优化!!)的方式来做到这一点:

首先,你要做出大表中,所有'通用名称'的两列(每个名称都有自己的一行)以及它的拉丁名字。你也可以在这里制作字典,但我喜欢桌子。从这里开始,循环遍历“ad_title”的每个元素(根据您的喜好使用apply()或for循环)。现在使用这样的东西:

apply(reference_table,1, function(X) { 
if (length(grep(X$common, ad_title)) > 0){ #If the common name was found in the ad_title 
[code to replace the string]}) 

为了插入新的字符串,玩你的常规正则表达式工具。另外,玩strsplit(ad_title,X $ common)。您将能够使用paste()和构成strsplit的部分来重建ad_title。

再一次,这不是最好的方法,但希望逻辑很简单。

+0

逻辑帮了我很多,谢谢。我的问题是,虽然有时广告列表中的通用名称拼写与查找表中的略有不同,因此grep不计算它。例如,在广告中它可能是“大胡子龙”,但它没有被grep拾起,因为在查找中它是“胡子龙”。我担心我可能需要为这些情况构建自定义正则表达式。 –

1

那么,我试图为您的需求创建一个可行的解决方案。不过,可能有更好的方法来执行它,可能使用的软件包如data.table和/或stringr。无论如何,这个片段可能是一个工作的起点。哦,我修改了Ad_title数据,以便物种名称在标题中。

# Re-create data 
Ad_title <- c("1 year old Ball Python", "Young Red Blood Python. - For Sale", 
       "1 Year Old Male Bearded Dragon - For Sale") 
df2 <- data.frame(Latin_name = c("Python regius", "Python brongersmai", "Pogona barbata"), 
        Common_name = c("E: Ball Python, Royal Python G: Königspython", 
            "E: Red Blood Python, Malaysian Blood Python", 
            "E: Eastern Bearded Dragon, Bearded Dragon"), 
        stringsAsFactors = F) 

# Aggregate common names 
Common_name <- paste(df2$Common_name, collapse = ", ") 
Common_name <- unlist(strsplit(Common_name, "(E:)|(G:)|(,)")) 
Common_name <- Common_name[Common_name != ""] 

# Data frame latin names vs common names 
df3 <- data.frame(Common_name, Latin_name = sapply(Common_name, grep, df2$Common_name), 
        row.names = NULL, stringsAsFactors = F) 
df3$Latin_name <- df2$Latin_name[df3$Latin_name] 

# Data frame Ad vs common names 
Ad_Common_name <- unlist(sapply(Common_name, grep, Ad_title)) 
df4 <- data.frame(Ad_title, Common_name = sapply(1:3, function(i) names(Ad_Common_name[Ad_Common_name==i])), 
        stringsAsFactors = F) 
相关问题