2016-05-18 37 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)