data.table
Voegt toe en voegt samen
Zoeken…
Invoering
?`[.data.table`
voor de officiële documenten.
Syntaxis
- x [i, aan, j]
# join: data.table x & data.table of lijst i - x [! i, on, j]
# anti-join
Opmerkingen
Werken met sleuteltabellen
Als x
& i
een sleutel hebben of x
is ingetoetst om overeen te komen met de eerste paar kolommen van i
, dan kan de on
worden overgeslagen zoals x[i]
.
Duidelijke gemeenschappelijke kolomnamen
In j
van x[i, on, j]
kunnen kolommen van i
worden aangeduid met i.*
-Voorvoegsels.
Groeperen op subsets
In j
van x[i, on, j, by=.EACHI]
, wordt j
berekend voor elke rij van i
.
Dit is de enige waarde van de by
waard om te gebruiken. Voor elke andere waarde zijn kolommen van i
niet beschikbaar.
Werk waarden bij in een join
Wanneer gegevens "netjes" zijn , zijn ze vaak georganiseerd in verschillende tabellen. Om de gegevens voor analyse te combineren, moeten we de ene tabel "bijwerken" met waarden uit een andere.
We hebben bijvoorbeeld verkoopgegevens voor uitvoeringen, waarbij kenmerken van de uitvoerder (hun budget) en van de locatie (de populatie) worden opgeslagen in afzonderlijke tabellen:
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
Wanneer we klaar zijn om wat analyses te doen, moeten we variabelen uit deze andere tabellen pakken:
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
Er wordt een copy
gemaakt om te voorkomen dat de onbewerkte gegevens worden besmet, maar we kunnen in plaats daarvan rechtstreeks aan mainDT
.
Voordelen van het gebruik van afzonderlijke tabellen
De voordelen van deze structuur worden behandeld in het artikel over opgeruimde gegevens, maar in deze context:
Ontbrekende gegevens traceren. Alleen rijen die overeenkomen in de samenvoeging ontvangen een opdracht. We hebben geen gegevens voor
geo_id == "MO"
hierboven, dus de variabelen zijnNA
in onze laatste tabel. Als we dit soort ontbrekende gegevens onverwacht zien, kunnen we het herleiden tot de ontbrekende waarneming in degeoDT
tabel en onderzoeken we of we een gegevensprobleem hebben dat kan worden verholpen.Begrijpelijkheid. Bij het bouwen van ons statistisch model kan het belangrijk zijn om in gedachten te houden dat het
budget
constant is voor elke uitvoerder. Over het algemeen levert het begrijpen van de structuur van de gegevens winst op.Geheugen grootte. Er kan een groot aantal uitvoerder- en locatiekenmerken zijn die niet in het statistische model terechtkomen. Op deze manier hoeven we ze niet op te nemen in de (mogelijk massieve) tabel die wordt gebruikt voor analyse.
Programmatisch bepalende kolommen
Als er veel kolommen in pDT
, maar we er slechts een paar willen selecteren, kunnen we gebruiken
p_cols = "budget"
DT[pDT, on=.(p_id = id), (p_cols) := mget(sprintf("i.%s", p_cols))]
De haakjes rondom (p_cols) :=
zijn essentieel, zoals vermeld in het document over het maken van kolommen .
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
Intuïtie
Zie x[i]
als het selecteren van een subset van x
voor elke rij van i
. Deze syntaxis weerspiegelt matrixsubsetting in basis R en is consistent met het eerste argument dat "waar" betekent, in DT[where, select|update|do, by]
.
Je kunt je afvragen waarom deze nieuwe syntaxis het leren waard is, omdat merge(x,i)
nog steeds werkt met data.tables. Het korte antwoord is dat we het meestal willen samenvoegen en dan iets verder willen doen. De syntaxis x[i]
legt dit gebruikspatroon bondig vast en maakt ook een efficiëntere berekening mogelijk. Lees FAQs 1.12 en 2.14 voor een meer gedetailleerde uitleg.
Meerdere overeenkomende rijen verwerken
Standaard wordt elke rij van a
bijpassende rij van b
geretourneerd:
a[b, on="id"]
# id x y
# 1: 1 11 -1
# 2: 1 12 -1
# 3: 2 13 -2
Dit kan worden aangepast met mult
:
a[b, on="id", mult="first"]
# id x y
# 1: 1 11 -1
# 2: 2 13 -2
Ongeëvenaarde rijen verwerken
Standaard worden niet-overeenkomende rijen van a
nog steeds weergegeven in het resultaat:
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
Gebruik nomatch
om deze te verbergen:
b[a, on="id", nomatch=0]
# id y x
# 1: 1 -1 11
# 2: 1 -1 12
# 3: 2 -2 13
Merk op dat x[i]
zal proberen NA's in i
te matchen.
Wedstrijden tellen terug
Gebruik .N
en by=.EACHI
om het aantal overeenkomsten voor elke rij van i
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