R - 使用正则表达式查找与查找字段匹配的字符串中的名称

时间:2016-05-18 02:52:13

标签: sql regex r gsub stringr

我有一个宠物广告列表的数据框:

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中使用通用名称(即ball 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%。如果有一种使用正则表达式的方法/功能,我认为这会有所帮助。

3 个答案:

答案 0 :(得分:1)

另一个答案很好地概括了一般逻辑,所以这里有一些关于简单(虽然没有优化!!)方法的想法:

首先,你需要制作一个大表,所有'常用名'的两列(每个名称都有自己的行)和它的拉丁名称。你也可以在这里制作一本字典,但我喜欢桌子。

function onLoad() {
  google.script.run
    .withSuccessHandler(processNum)
    .runHandler("getSomeNum");
}

function processNum(num) {
  var event = {
    num : num
  };

  google.script.run
    .withSuccessHandler( function(retNum) { alert(retNum); } )
    .runHandler("doSomething", event);
}

从这里开始,只需遍历“ad_title”的每个元素(使用apply()或for循环,具体取决于您的偏好)。现在使用这样的东西:

    reference_table <- data.frame(common = c("cat", "kitty", "dog"), technical = c("feline", "feline", "canine"))

  common technical
1    cat    feline
2  kitty    feline
3    dog    canine

要插入新字符串,请使用常规正则表达式工具。或者,使用strsplit(ad_title,X $ common)。您将能够使用paste()以及构成strsplit的部件重建ad_title。

同样,这不是最好的方法,但希望逻辑很简单。

答案 1 :(得分: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)

答案 2 :(得分:0)

显然你需要一个循环结构用于所有常用名称查找表,另一个循环在逗号上分割这个复合字段,然后再进行简单的正则表达式。没有理智的正则表达式可以做到这一切。 将来避免使用需要包装和拆包的包装/复合结构。它看起来很适合人类消费,但在语义和计算机程序消费方面,你有多个数据值打包在单个字段中,即它不是“通用名称”它是由逗号分隔的“常用名”,你有。

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