2017-09-21 234 views
0

我有一个数据框有两列,它们是人的名字。生成表下面的代码:字符串匹配

names.1=c('Ron ven goh','Phil Mick' , 'Rohan Aggarwal','John Deo Lin') 
names.2=c('Rob ven goh','kitty Mol','Tejas Aggarwal','Jorge Mol Lin') 
df=data.table(names.1,names.2) 

我的任务是再添变数是二进制(是,否) - 如果整个字符串在列中的任何字1场比赛第2栏的整个字符串的任何词然后是“是”,否则“否” - 只要找到匹配,就可以给出肯定结果。

我有下面这段代码:

for(i in 1:nrow(df)){ 
    var_customername <- strsplit(as.character(df$names.1[i]),"\\s+") 
    var_relationshipname <- strsplit(as.character(df$names.2[i]),"\\s+")         
    df$NAMEMATCH[i] <- ifelse(any(unlist(var_customername) %in% unlist(var_relationshipname)),'YES','NO') 
    rm(var_customername,var_relationshipname) 
} 

我总体的数据帧700万行,因此它通过我的计算将采取405小时由于如有循环 - 这是如何能提出的任何建议更快或优化?

+0

首先,它给了错误'错误strsplit(filtered_household_results $ CUSTOMERNAME,“\\ s +”): 非字符参数',然后我在前面的两个名字前面加了'as.character'并试过 - 它没有给出正确的输出 - 给所有人一个是! – Pb89

回答

1

我一直在使用这里显示更快的方法 '申请':

你的方法:

> start.time <- Sys.time() 
> for(i in 1:nrow(df)){ 
+ var_customername <- strsplit(as.character(df$names.1[i]),"\\s+") 
+ var_relationshipname <- strsplit(as.character(df$names.2[i]),"\\s+")         

+ df$NAMEMATCH[i] <- ifelse(any(unlist(var_customername) %in% 
unlist(var_relationshipname)),'YES','NO') 
+ rm(var_customername,var_relationshipname) 
+ } 
> end.time <- Sys.time() 
> time.taken <- end.time - start.time 
> time.taken 
Time difference of 0.03119993 secs 

我的方法:

> start.time <- Sys.time() 
> apply(df, 1, function(x) 
ifelse(any(unlist(strsplit(as.character(x[1]),"\\s+")) %in% 
unlist(strsplit(as.character(x[2]),"\\s+"))),'YES','NO')) 
[1] "YES" "NO" "YES" "YES" 
> end.time <- Sys.time() 
> time.taken <- end.time - start.time 
> time.taken 
Time difference of 0 secs 
+0

出于某种原因,它使用您的应用方法给我所有'是'。 – Pb89

+0

明白了。这很棒 !时间从我的数据框的100行减少30秒到0.3秒! R中使用apply函数的矢量化操作是我猜测的关键 – Pb89