C'est un peu une question philosophique sur la syntaxe de jointure data.table. Je trouve de plus en plus d'utilisations pour les data.tables, mais j'apprends toujours ...
Le format X[Y]
de jointure pour data.tables est très concis, pratique et efficace, mais pour autant que je sache, il ne prend en charge que les jointures internes et les jointures externes droites. Pour obtenir une jointure externe gauche ou complète, je dois utiliser merge
:
X[Y, nomatch = NA]
- toutes les lignes en Y - jointure externe droite (par défaut)X[Y, nomatch = 0]
- uniquement les lignes avec des correspondances en X et en Y - jointure internemerge(X, Y, all = TRUE)
- toutes les lignes de X et Y - jointure externe complètemerge(X, Y, all.x = TRUE)
- toutes les lignes en X - jointure externe gauche
Il me semble qu'il serait utile que le X[Y]
format de jointure prenne en charge les 4 types de jointures. Y a-t-il une raison pour laquelle seuls deux types de jointures sont pris en charge?
Pour moi, les valeurs des paramètres nomatch = 0
et nomatch = NA
ne sont pas très intuitives pour les actions effectuées. Il me est plus facile à comprendre et à mémoriser la merge
syntaxe: all = TRUE
, all.x = TRUE
et all.y = TRUE
. Puisque l' X[Y]
opération ressemble merge
beaucoup plus à match
, pourquoi ne pas utiliser la merge
syntaxe des jointures plutôt que le paramètre de la match
fonction nomatch
?
Voici des exemples de code des 4 types de jointure:
# 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
Mise à jour: data.table v1.9.6 a introduit la on=
syntaxe, qui permet des jointures ad hoc sur des champs autres que la clé primaire. réponse de jangorecki à la question Comment joindre (fusionner) des trames de données (interne, externe, gauche, droite)? fournit quelques exemples de types de jointures supplémentaires que data.table peut gérer.
unique()
approche ci-dessous pour la jointure complète est préférable rbind(Y[X],X[Y])
, car la rbind impliquerait de copier la table. Est-ce correct?
unique(c(unique(X[,t]), unique(Y[,t]))
, cela devrait être plus efficace en mémoire car il ne combine que deux listes qui vont être inférieures ou égales au nombre de lignes dans X et Y .
Y[X]
si vous voulez la jointure externe gauche deX[Y]
etrbind(Y[X],X[Y])
si vous voulez une jointure externe complète