簡體   English   中英

R:使用 agrep 和 data.table 進行模糊合並

[英]R: Fuzzy merge using agrep and data.table

我嘗試合並兩個 data.tables,但由於股票名稱的不同拼寫,我丟失了大量數據點。 因此,我正在研究模糊合並,而不是完全匹配。

library("data.table")
dt1 = data.table(Name = c("ASML HOLDING","ABN AMRO GROUP"), A = c(1,2))
dt2 = data.table(Name = c("ASML HOLDING NV", "ABN AMRO GROUP"), B = c("p", "q"))

在“Name”上合並 dt1 和 dt2 時,ASML HOLDING 會因添加“NV”而被排除,而實際數據將是准確的。

首選的最終數據輸出看起來像:

              Name A B
1:  ABN AMRO GROUP 2 q
2: ASML HOLDING NV 1 p

我接下來嘗試的是以下內容:

dt1 = dt1[, dt2_NAME := agrep(dt1$Name, dt2$Name, ignore.case = TRUE, value = TRUE, max.distance = 0.05, useBytes = TRUE)]

但是,我收到以下錯誤,

參數 'pattern' 的長度 > 1,並且只會使用第一個元素

該錯誤是有道理的,因為 dt1$Name 長於 1,但我相信如果它會在行到行的基礎上考慮 dt1$Name,這將是一個可能的解決方案。

這可能是一個愚蠢的錯誤,但出於某種原因,我無法理解它。 此外,我更喜歡使用 data.table,因為我的數據集相當大,而且到目前為止它工作得非常好。 此外,我是堆棧溢出的新手,如果我的問題有點不對,我很抱歉。

最后,我找到了一段可以完成這項工作的代碼,但對於實際使用來說太慢了。 R中的模糊合並

dt1$Name_dt2 <- "" # Creating an empty column
for(i in 1:dim(dt1)[1]) {
  x <- agrep(dt1$Name[i], dt2$Name,
             ignore.case=TRUE, value=TRUE,
             max.distance = 0.05, useBytes = TRUE)
  x <- paste0(x,"")
  dt1$Name_dt2[i] <- x
}

使用“fuzzyjoin”的可能解決方案:

library(fuzzyjoin)
f <- Vectorize(function(x,y) agrepl(x, y,
                                   ignore.case=TRUE,
                                   max.distance = 0.05, useBytes = TRUE))

dt1 %>% fuzzy_inner_join(dt2, by="Name", match_fun=f)
#          Name.x A          Name.y B
#1   ASML HOLDING 1 ASML HOLDING NV p
#2 ABN AMRO GROUP 2  ABN AMRO GROUP q

注意:您也遇到的主要問題是agrepagrepl似乎不希望第一個參數是向量。 這就是為什么我用Vectorize包裝電話的原因。

此方法可以與 equi-join 一起使用(注意by的列順序!):

dt1 = data.frame(Name = c("ASML HOLDING","ABN AMRO GROUP"), A = c(1,2),Date=c(1,2))
dt2 = data.frame(Name = c("ASML HOLDING NV", "ABN AMRO GROUP", "ABN AMRO GROUP"), B = c("p", "q","r"),Date=c(1,2,3))

dt1 %>% fuzzy_inner_join(dt2, by=c("Date","Name"), match_fun=f) %>% filter(Date.x==Date.y)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM