これは、data.table結合構文についての哲学的な質問です。data.tablesの用途はますます増えていますが、まだ学習中です...
X[Y]
data.tables の結合フォーマットは非常に簡潔で、便利で効率的ですが、私が知る限り、内部結合と右外部結合のみをサポートしています。左または完全な外部結合を取得するには、以下を使用する必要がありますmerge
。
X[Y, nomatch = NA]
-Yのすべての行-右外部結合(デフォルト)X[Y, nomatch = 0]
-XとYの両方に一致する行のみ-内部結合merge(X, Y, all = TRUE)
-XとYの両方からのすべての行-完全外部結合merge(X, Y, all.x = TRUE)
-Xのすべての行-左外部結合
X[Y]
結合フォーマットが4種類の結合すべてをサポートしていると便利だと思います。2種類の結合のみがサポートされる理由はありますか?
私にとって、nomatch = 0
およびnomatch = NA
パラメータの値は、実行されるアクションのための非常に直感的ではありません。merge
構文を理解して覚える方が簡単です:all = TRUE
、all.x = TRUE
およびall.y = TRUE
。X[Y]
操作はにmerge
非常に似ているので、関数のパラメーターではなく結合match
のmerge
構文を使用してみませんか?match
nomatch
4つの結合タイプのコード例を以下に示します。
# sample X and Y data.tables
library(data.table)
X <- data.table(t = 1:4, a = (1:4)^2)
setkey(X, t)
X
# t a
# 1: 1 1
# 2: 2 4
# 3: 3 9
# 4: 4 16
Y <- data.table(t = 3:6, b = (3:6)^2)
setkey(Y, t)
Y
# t b
# 1: 3 9
# 2: 4 16
# 3: 5 25
# 4: 6 36
# all rows from Y - right outer join
X[Y] # default
# t a b
# 1: 3 9 9
# 2: 4 16 16
# 3: 5 NA 25
# 4: 6 NA 36
X[Y, nomatch = NA] # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
# 3: 5 NA 25
# 4: 6 NA 36
merge(X, Y, by = "t", all.y = TRUE) # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
# 3: 5 NA 25
# 4: 6 NA 36
identical(X[Y], merge(X, Y, by = "t", all.y = TRUE))
# [1] TRUE
# only rows in both X and Y - inner join
X[Y, nomatch = 0]
# t a b
# 1: 3 9 9
# 2: 4 16 16
merge(X, Y, by = "t") # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
merge(X, Y, by = "t", all = FALSE) # same as above
# t a b
# 1: 3 9 9
# 2: 4 16 16
identical( X[Y, nomatch = 0], merge(X, Y, by = "t", all = FALSE) )
# [1] TRUE
# all rows from X - left outer join
merge(X, Y, by = "t", all.x = TRUE)
# t a b
# 1: 1 1 NA
# 2: 2 4 NA
# 3: 3 9 9
# 4: 4 16 16
# all rows from both X and Y - full outer join
merge(X, Y, by = "t", all = TRUE)
# t a b
# 1: 1 1 NA
# 2: 2 4 NA
# 3: 3 9 9
# 4: 4 16 16
# 5: 5 NA 25
# 6: 6 NA 36
更新:data.table v1.9.6にon=
構文が導入されました。これにより、主キー以外のフィールドでのアドホック結合が可能になります。jangoreckiの質問への回答データフレームを結合(マージ)する方法(内側、外側、左、右)?は、data.tableが処理できる追加の結合タイプの例をいくつか示しています。
unique()
れるため、完全な結合については、以下のアプローチがに望ましいとrbind(Y[X],X[Y])
思います。そうですか?
unique(c(unique(X[,t]), unique(Y[,t]))
、XとYの行数以下になる2つのリストを組み合わせるだけなので、これはよりメモリ効率が良いはずです) 。
Y[X]
、いつでも呼び出すことができますX[Y]
rbind(Y[X],X[Y])