2016-09-22 148 views
3

我正在處理兩個基於閾值合併的不同數據集。比方說,兩個dataframes是這樣的:如何在R中使用fuzzyjoin :: difference_ *執行模糊連接

library(dplyr) 
library(fuzzyjoin) 
library(lubridate) 

df1 = data_frame(Item=1:5, 
       DateTime=c("2015-01-01 11:12:14", "2015-01-02 09:15:23", 
          "2015-01-02 15:46:11", "2015-04-19 22:11:33", 
          "2015-06-10 07:00:00"), 
       Count=c(1, 6, 11, 15, 9), 
       Name="Sterling", 
       Friend=c("Pam", "Cyril", "Cheryl", "Mallory", "Lana")) 
df1$DateTime = ymd_hms(df1$DateTime) 

df2 = data_frame(Item=21:25, 
       DateTime=c("2015-01-01 11:12:15", "2015-01-02 19:15:23", 
          "2015-01-02 15:46:11", "2015-05-19 22:11:33", 
          "2015-06-10 07:00:02"), 
       Count=c(3, 7, 11, 15, 8), 
       Name="Sterling", 
       Friend=c("Pam", "Kreger", "Woodhouse", "Gillete", "Lana")) 
df2$DateTime = ymd_hms(df2$DateTime) 

我現在想什麼,是能夠基於對DateTime模糊匹配和Count是各自的價值在兩秒鐘內左連接df2df1,而除Item以外的所有其他值都相同。我以爲我可以用下面的路線:

df1 %>% 
    difference_left_join(df2, by=c("DateTime", "Count"), max_dist=2) 

但是,這給了我下面的輸出:

# A tibble: 8 × 10 
    Item.x   DateTime.x Count.x Name.x Friend.x Item.y   DateTime.y Count.y Name.y Friend.y 
    <int>    <dttm> <dbl> <chr> <chr> <int>    <dttm> <dbl> <chr>  <chr> 
1  1 2015-01-01 11:12:14  1 Sterling  Pam  21 2015-01-01 11:12:15  3 Sterling  Pam 
2  1 2015-01-01 11:12:14  1 Sterling  Pam  21 2015-01-01 11:12:15  3 Sterling  Pam 
3  2 2015-01-02 09:15:23  6 Sterling Cyril  NA    <NA>  NA  <NA>  <NA> 
4  3 2015-01-02 15:46:11  11 Sterling Cheryl  23 2015-01-02 15:46:11  11 Sterling Woodhouse 
5  3 2015-01-02 15:46:11  11 Sterling Cheryl  23 2015-01-02 15:46:11  11 Sterling Woodhouse 
6  4 2015-04-19 22:11:33  15 Sterling Mallory  NA    <NA>  NA  <NA>  <NA> 
7  5 2015-06-10 07:00:00  9 Sterling  Lana  25 2015-06-10 07:00:02  8 Sterling  Lana 
8  5 2015-06-10 07:00:00  9 Sterling  Lana  25 2015-06-10 07:00:02  8 Sterling  Lana 

這是接近,除了第3行不應該合併,因爲名稱不同(並且我希望第2行在給定閾值的情況下合併,即使我不希望它)。

如何結束以下數據框?請注意,儘管DateTimeCount滿足閾值限制,但df2的第二行和第三行未合併。這是因爲其他列(Item除外)不相同。

desired_output 
# Item   DateTime Count  Name Friend 
# 1 3 2015-01-02 15:46:11 11 Sterling Cheryl 
# 2 2 2015-01-02 09:15:23  6 Sterling Cyril 
# 3 5 2015-06-10 07:00:00  9 Sterling Lana 
# 4 25 2015-06-10 07:00:02  8 Sterling Lana 
# 5 4 2015-04-19 22:11:33 15 Sterling Mallory 
# 6 1 2015-01-01 11:12:14  1 Sterling  Pam 
# 7 21 2015-01-01 11:12:15  3 Sterling  Pam 
+0

我認爲如果您在連接之前不對數據使用'lubridate',它會給您提到的錯誤。否則,如果給你一個不同的信息。 BTW對不起,如果我錯過了明顯的東西,但「持續時間」從哪裏來? –

+1

啊,對不起!我弄糟了數據來掩蓋它的真實含義,但是保留了真正的變量名稱。我會把它清理乾淨。 – brittenb

+0

鑑於您指出爲什麼會發生錯誤,並且更新了調用該行代碼的結果,還刪除了對錯誤的引用。 – brittenb

回答

3

好的,所以,你得到的消息是因爲模糊匹配無法在非數字列上計算。

要做的事情是將其轉換爲數字。由於您的卡鉗是在幾秒鐘內我把它轉換成秒,然後讓他們的數字:

library(dplyr) 
library(fuzzyjoin) 
library(lubridate) 

df1 = data_frame(Item=1:5, 
       DateTime=c("2015-01-01 11:12:14", "2015-01-02 09:15:23", 
          "2015-01-02 15:46:11", "2015-04-19 22:11:33", 
          "2015-06-10 07:00:00"), 
       Count=c(1, 6, 11, 15, 9), 
       Name="Sterling", 
       Friend=c("Pam", "Cyril", "Cheryl", "Mallory", "Lana")) 
df1$DateTime1 = as.numeric(seconds(ymd_hms(df1$DateTime))) 

df2 = data_frame(Item=21:25, 
       DateTime=c("2015-01-01 11:12:15", "2015-01-02 19:25:56", 
          "2015-01-02 15:46:11", "2015-05-19 22:11:33", 
          "2015-06-10 07:00:02"), 
       Count=c(3, 6, 11, 15, 8), 
       Name="Sterling", 
       Friend=c("Pam", "Kreger", "Woodhouse", "Gillete", "Lana")) 
df2$DateTime1 = as.numeric(seconds(ymd_hms(df2$DateTime))) 

df1 %>% 
    difference_left_join(y=df2, by=c("DateTime1", "Count"), max_dist=2) 
基於我們在評論一個簡單的調整,以子集這對其他字符列的情況下討論

匹配將是:

df1[df2$Friend == df1$Friend,] %>% 
    difference_left_join(y=df2[df2$Friend == df1$Friend,], by=c("DateTime1", "Count"), max_dist=2) 

該示例僅適用於Friend,但當然,您可以使用&對多列進行此操作。

+0

是否可以指定所有字符變量必須完全匹配?我認爲只要從'difference_left_join'獲取輸出,然後過濾掉其中的記錄,例如'Name.x!= Name.y',會更容易。 – brittenb

+0

@brittenb我以爲你只希望他們在2秒內匹配? –

+0

無可否認,在重新閱讀我的問題和標題後,我並不十分清楚。我希望他們在兩秒鐘內相互匹配,但只有當每一列(除了「Item」)匹配時才匹配。 – brittenb