2017-09-21 282 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