Recherche…


Introduction

Une jointure combine deux tables contenant des colonnes associées. Le terme couvre un large éventail d'opérations, essentiellement tout sauf les deux tableaux . "Fusionner" est un synonyme. Tapez ?`[.data.table` pour les documents officiels.

Syntaxe

  • x [i, on, j]
    # join: data.table x & data.table ou list i
  • x [! i, on, j]
    # anti-jointure

Remarques

Travailler avec des tables à clés

Si x et i ont une clé ou que x est associé aux premières colonnes de i , alors on peut ignorer la fonction x[i] .

Désactiver les noms de colonnes en commun

En j de x[i, on, j] , les colonnes de i peuvent être référencées avec les préfixes i.* .

Regroupement sur des sous-ensembles

En j de x[i, on, j, by=.EACHI] , j est calculé pour chaque ligne de i .

C'est la seule valeur de by vaut la peine. Pour toute autre valeur, les colonnes de i ne sont pas disponibles.

Mettre à jour les valeurs dans une jointure

Lorsque les données sont "rangées", elles sont souvent organisées en plusieurs tables. Pour combiner les données à analyser, nous devons "mettre à jour" une table avec les valeurs d'une autre.

Par exemple, nous pouvons avoir des données de vente pour les performances, où les attributs de l'exécutant (leur budget) et de l'emplacement (sa population) sont stockés dans des tables séparées:

set.seed(1)
mainDT = data.table(
  p_id = rep(LETTERS[1:2], c(2,4)), 
  geo_id = sample(rep(state.abb[c(1,25,50)], 3:1)), 
  sales = sample(100, 6)
)
pDT   = data.table(id = LETTERS[1:2], budget = c(60, 75))
geoDT = data.table(id = state.abb[c(1,50)], pop = c(100, 200))

mainDT # sales data
#    p_id geo_id sales
# 1:    A     AL    95
# 2:    A     WY    66
# 3:    B     AL    62
# 4:    B     MO     6
# 5:    B     AL    20
# 6:    B     MO    17


pDT # performer attributes
#    id budget
# 1:  A     60
# 2:  B     75

geoDT # location attributes
#    id pop
# 1: AL 100
# 2: WY 200

Lorsque nous sommes prêts à faire des analyses, nous devons récupérer les variables de ces autres tables:

DT = copy(mainDT)

DT[pDT, on=.(p_id = id), budget := i.budget]
DT[geoDT, on=.(geo_id = id), pop := i.pop]

#    p_id geo_id sales budget pop
# 1:    A     AL    95     60 100
# 2:    A     WY    66     60 200
# 3:    B     AL    62     75 100
# 4:    B     MO     6     75  NA
# 5:    B     AL    20     75 100
# 6:    B     MO    17     75  NA

Une copy est prise pour éviter de contaminer les données brutes, mais nous pourrions travailler directement sur mainDT place.

Avantages de l'utilisation de tables séparées

Les avantages de cette structure sont traités dans le document sur les données bien rangées, mais dans ce contexte:

  1. Traçage des données manquantes Seules les lignes correspondant à la fusion reçoivent une affectation. Nous n'avons pas de données pour geo_id == "MO" ci-dessus, donc ses variables sont NA dans notre table finale. Si nous voyons des données manquantes comme celle-ci de manière inattendue, nous pouvons remonter à l'observation manquante dans le tableau geoDT et rechercher à partir de là si nous avons un problème de données qui peut être résolu.

  2. Compréhensibilité. En construisant notre modèle statistique, il peut être important de garder à l’esprit que le budget est constant pour chaque interprète. En général, la compréhension de la structure des données porte ses fruits.

  3. Taille mémoire. Il peut y avoir un grand nombre d'attributs interprètes et localisés qui ne se retrouvent pas dans le modèle statistique. De cette façon, nous n'avons pas besoin de les inclure dans la table (éventuellement massive) utilisée pour l'analyse.

Détermination par programme des colonnes

S'il y a beaucoup de colonnes dans pDT , mais que nous voulons seulement en sélectionner quelques-unes, nous pouvons utiliser

p_cols = "budget"
DT[pDT, on=.(p_id = id), (p_cols) := mget(sprintf("i.%s", p_cols))]

Les parenthèses autour de (p_cols) := sont essentielles, comme indiqué dans la documentation sur la création de colonnes .

Equi-join

# example data
a = data.table(id = c(1L, 1L, 2L, 3L, NA_integer_), x = 11:15)
#    id  x
# 1:  1 11
# 2:  1 12
# 3:  2 13
# 4:  3 14
# 5: NA 15

b = data.table(id = 1:2, y = -(1:2))
#    id  y
# 1:  1 -1
# 2:  2 -2

Intuition

Pensez à x[i] en sélectionnant un sous-ensemble de x pour chaque ligne de i . Cette syntaxe reflète la matrice subsing dans la base R et est cohérente avec le premier argument signifiant "où", dans DT[where, select|update|do, by] .

On peut se demander pourquoi cette nouvelle syntaxe mérite d’être apprise, puisque la merge(x,i) fonctionne toujours avec data.tables. La réponse courte est que nous voulons généralement fusionner et ensuite faire quelque chose de plus. La syntaxe x[i] capture de manière concise ce modèle d'utilisation et permet également un calcul plus efficace. Pour une explication plus détaillée, lisez la FAQ 1.12 et 2.14 .

Gestion des lignes à plusieurs correspondances

Par défaut, chaque ligne d' a correspondant de chaque ligne b est renvoyée:

a[b, on="id"]
#    id  x  y
# 1:  1 11 -1
# 2:  1 12 -1
# 3:  2 13 -2

Cela peut être modifié avec mult :

a[b, on="id", mult="first"]
#    id  x  y
# 1:  1 11 -1
# 2:  2 13 -2

Gestion des lignes sans correspondance

Par défaut, les lignes non appariées d' a apparaissent dans le résultat:

b[a, on="id"]
#    id  y  x
# 1:  1 -1 11
# 2:  1 -1 12
# 3:  2 -2 13
# 4:  3 NA 14
# 5: NA NA 15

Pour les masquer, utilisez nomatch :

b[a, on="id", nomatch=0]
#    id  y  x
# 1:  1 -1 11
# 2:  1 -1 12
# 3:  2 -2 13

Notez que x[i] tentera de faire correspondre les NA dans i .

Comptage des correspondances renvoyées

Pour compter le nombre de correspondances pour chaque ligne de i , utilisez .N et by=.EACHI .

b[a, on="id", .N, by=.EACHI]
#    id N
# 1:  1 1
# 2:  1 1
# 3:  2 1
# 4:  3 0
# 5: NA 0


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow