繁体   English   中英

使用grepl在R中使用大模式向量检测多个模式

[英]Detecting multiple patterns using grepl with large pattern vectors in R

catalog是具有不同值的字符向量。 它具有以下结构

value   name    location    companybrand        
1111    ikea    boston      nike
1234    7/11    new york    marlboro
1456    walmart new york    marlboro

列表包含美国的所有城市->芝加哥,波士顿,纽约,洛杉矶,以及包含品牌全名的另一列

Location                    Brand
New York, 5th Avenue        Coca Cola LTD
New York, 51 Str            Nike Corporation 
New York, Broadway          Marlboro Incorporated

if (sum(grepl(paste("\\b", as.character(location), "\\b", sep = ""), catalog$value[i], fixed = FALSE)) > 0 && 
    sum(grepl(paste("\\b", as.character(companybrand), "\\b", sep = ""), catalog$value[i], fixed = FALSE)) > 0){
  subdata <- subset(listing, listing$local == as.character(location[which(grepl(paste("\\b", as.character(location), "\\b", sep = ""), catalog$value[i], fixed = FALSE)]) && listing$commercial == as.character(companybrand[which(grepl(paste("\\b", as.character(companybrand), "\\b", sep = ""), catalog$value[i], fixed = FALSE))]))
}

如您所见,我正在尝试使用多种模式运行grepl函数,该函数返回以下错误:

Warning message:
In grepl(paste("\\b", distmunicipality, "\\b", sep = ""), ctlg$distvalor[i],  :
  argument 'pattern' has length > 1 and only the first element will be used

我在其他帖子中已经读到,对此的适当解决方案是使用管道分隔符将所有要测试的模式折叠为单个字符串,如下所示:

companybrand <- paste(companybrand, collapse = "|")
location <- paste(location, collapse = "|")

可以用于较小的向量,但在我的情况下,我在companybrand中有400万个元素,这导致我的R由于内存不足而终止。 有没有一种可行的方法(也许使用sapply)来运行此匹配,而无需进行计算负担?

我不确定为什么这个问题仍然存在。

似乎问题出在每个品牌和位置都有两个名称,您希望合并品牌和位置上的两个数据集,这样您就可以从这两个数据源获得信息。 听起来像是模糊合并或近似匹配合并

无论如何,试图回答OP,与其说如何创建一个巨大的逻辑门,不如说是如何应用一堆较小的逻辑门。

在您的示例中,您提到了级联管道列表的问题是它的长度为400万个条目。 我建议类似以下内容:

require(data.table)
catalog<- data.table(value=c("1111","1234","1456"),
                     name=c("ikea","7/11","walmart"),
                     location=c("boston","new york","new york"),
                     companybrand=c("nike","marlboro","marlboro"))

listing<-data.table(Location=c("New York, 5th Avenue","New York,51 str","New York, Broadway"),
                    Brand=c("Coca Cola LTD","Nike Corporation","Marlboro Incorporated"))


for(companybrand in unique(catalog$companybrand)){
  listing[grepl(paste0("\\b",companybrand,"\\b"),Brand,ignore.case=TRUE),
          companybrand:=companybrand]
}

for(location in catalog$location){
 listing[grepl(paste0("\\b",location,"\\b"),location,Location,ignore.case=TRUE),
    location:=location]
}

dictionary<-listing[complete.cases(listing)]

注意:如果catalog中的品牌和位置比listing中的要多得多,那么我将反转代码并使for循环遍历较小的listing项。

上面的代码生成了一个字典,您可以使用该字典来查找“位置-品牌”对(或“位置-公司-品牌”对),并且其内存效率更高(我尚未对此进行测试)。

要在这一点上对数据进行子集化,您需要做的就是将字典(可能重命名字典列)与要通过数据集使用的列名进行子集化的任何数据集合并。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM