少し前に改訂新版が出ましたね、前処理大全。
7-5「不等式条件での結合」は、旧版から変わっていないトピックですが、実は dplyr はこの数年の間に進化しています。 当時は非等価結合ができなかったんですが、バージョン1.1.0(2023年1月リリース)からできるようになっています。
具体的には、join_*()
に join_by()
という指定ができるようになっていて、これを使うと全組み合わせのうち条件を満たすものだけを残して join してくれます。
例題では、reservation
にある reserved_at
列が campaign
の starts_at
列と ends_at
列の期間に含まれていればいいので、以下のような書き方になります。
reservation |> left_join( campaign, join_by(between(reserved_at, starts_at, ends_at)) )
今回は、
- 区間
- ある値
を比較するパターンでしたが、区間と区間を比較するような条件も書けます。
あとは、難しい概念として rolling join というのもあります。説明は省略しますが、ユーザーの行動ログの分析をしたりするときはわりとよく使う気がしますね。
こんな感じで柔軟な join_by()
ですが、任意の条件を指定できるわけではありません。
たとえば、以下のように正規表現で join したくなるようなときがあったりするかもしれませんが、そういうことはできないみたいです。
dplyr 以外のやり方については、以下の記事にまとまっています(今書くならここに duckdb が入ってきそう)。 data.table ではもっと前からできたみたいです。さすがですね。
余談
Polars の場合は、issue としてはあるのでサポートしようという意志はあるみたいです。 このへんはまあ duckdb の方が小回りが利くなという印象。