2016-09-22 4 views
3

私はしきい値に基づいてマージしたい2つの異なるデータセットを扱っています。 2つのデータフレームは次のようになりましょう:私は今、希望は何fuzzyjoin :: difference_ *でファジー結合を実行する方法R

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) 

は、それぞれの値の2秒以内であることファジーDateTimeの試合とCountに基づいてdf1df2に参加残さできるようにすることです、 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の2行目と3行目がマージされていないことに注意してください。これは、他の列(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'を使わないと、あなたが言ったエラーを与えると思います。それ以外の場合は、別のメッセージが表示されます。ところで申し訳ありませんが、私は何かが明らかではないが、 "Duration"はどこから来たのですか? –

+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

私の質問とタイトルを再読した後、私はあまり明確ではありませんでした。お互いに2秒以内に一致させたいのですが、他のすべての列( 'Item'を除く)が一致する場合にのみ、一致させてください。 – brittenb

関連する問題