2015-04-26 50 views
3

我試圖匹配工人年年使用名稱字符串和經驗措施。經驗每年最多隻能增加一次,所以我希望在其他指標失敗時使用它來幫助匹配。「模糊鍵匹配」的data.table合併

例如:

dt1<-data.table(name=c("jane doe","jane doe", 
         "john doe","jane smith"), 
       exp=c(0.,5,1,2),id=1:4,key="name") 
dt2<-data.table(name=c("jane doe","jane doe", 
         "john doe","jane smith"), 
       exp=c(0,30,1.5,2),key="name") 

我想在dt1第一「李四」匹配在dt2第一「李四」。後者「jane doe」不匹配,因爲他們顯然是不同的人(基於極其不同的經驗水平)。

我還想添加一些標誌,以便知道我以後用這種方式匹配這些人。這是我的第一關:

dt2[dt1,`:=`(id=ifelse(exp<=i.exp+1,i.id,NA), 
      flag=ifelse(exp<=i.exp+1,i.id,NA))] 

但是,這是行不通的 - 這裏是什麼給了我:

> dt2 
     name exp id flag 
1: jane doe 0.0 2 2 
2: jane doe 30.0 NA NA 
3: jane smith 2.0 4 4 
4: john doe 1.5 3 3 

它似乎正確地錯過了匹配後者「李四」,但似乎有將第一個「簡恩」與之前的「簡恩」錯誤地匹配。我不太確定這是爲什麼;無論如何,似乎最好有辦法在之前,而不是在加入之後,將匹配結合到exp之前 - 這也將清除定義新變量中的ifelse混亂。有什麼建議麼?


爲了清楚起見,這裏的期望輸出:

> dt2 
     name exp id flag 
1: jane doe 1.0 1 1 
2: jane doe 30.0 NA NA 
3: jane smith 2.0 4 1 
4: john doe 1.5 3 1 
+0

你的問題不太清楚。你想通過'exp'來匹配'name' *和*嗎?換句話說,'df1'中的所有「jane doe」是不同的人? –

+4

無論如何,我不完全確定,但也許你正在尋找'setkey(dt1,name,exp); setkey(dt2,name,exp); dt2 [dt1,id:= i.id,roll = -1L]'? –

+0

完美!從來沒有完全理解'roll'的作用 - 最終找到了一個例子。所以'roll = -2L'可以匹配任何有'exp'的人最多少2; 'roll = 1L'會最多匹配具有'exp'的任何人,以此類推。 'roll = + Inf'表示任何'exp'更大,'roll = -Inf'表示任何'exp'更少。匹配_within_ 1怎麼樣? 'roll = c(-1L,1L)'不起作用,'最近的'不一定有效。 – MichaelChirico

回答

5

在你的情況下,連接是不是真正的 「模糊」。你所要做的就是加入name,exp,同時允許每場比賽有1年的距離。這是軋製加入-1L規範很好的使用。

首先,我們將正確的密鑰對數據集

setkey(dt1, name, exp) 
setkey(dt2, name, exp) 

然後,我們將進行滾動加盟,同時通過-1L作爲其值

dt2[dt1, `:=`(id = i.id, flag = 1L), roll = -1L] 
df2 
#   name exp id flag 
# 1: jane doe 0.0 1 1 
# 2: jane doe 30.0 NA NA 
# 3: jane smith 2.0 4 1 
# 4: john doe 1.5 3 1 

在未來,如果你「」您需要進行間隔連接,例如c(1L, -1L),您可以看一下here以獲取foverlaps函數的一些示例。