Sök…


Introduktion

En koppling kombinerar två tabeller som innehåller relaterade kolumner. Termen täcker ett brett spektrum av operationer, i huvudsak allt utom att lägga till de två tabellerna . "Sammanfoga" är en synonym. Skriv ?`[.data.table` för de officiella dokumenten.

Syntax

  • x [i, på, j]
    # gå med: data.table x & data.table eller lista i
  • x [! i, på, j]
    # anti-join

Anmärkningar

Arbeta med tangentbord

Om x och i har en nyckel eller x är låst för att matcha i första några kolumner, då on kan hoppas över som x[i] .

Gemensamma kolumnnamn

I j av x[i, on, j] kan kolumner av i hänvisas till i.* Prefix.

Gruppera på undergrupper

I j av x[i, on, j, by=.EACHI] beräknas j för varje rad i .

Detta är det enda värdet by värda att använda. För något annat värde är kolumner i inte tillgängliga.

Uppdatera värden i en sammanfogning

När data är "snyggt", organiseras de ofta i flera tabeller. För att kombinera data för analys måste vi "uppdatera" en tabell med värden från en annan.

Vi kan till exempel ha försäljningsdata för föreställningar, där attributen för utövaren (deras budget) och för platsen (dess befolkning) lagras i separata tabeller:

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

När vi är redo att göra en analys måste vi ta variabler från dessa andra tabeller:

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

En copy tas för att undvika förorening av rådata, men vi kan arbeta direkt på mainDT istället.

Fördelar med att använda separata tabeller

Fördelarna med denna struktur behandlas i tidningen om städad information, men i detta sammanhang:

  1. Spåra saknade data. Endast rader som matchar i sammanslagningen får ett uppdrag. Vi har inga data för geo_id == "MO" ovan, så dess variabler är NA i vår sista tabell. Om vi oväntat ser saknade data så kan vi spåra dem tillbaka till den saknade observationen i geoDT tabellen och därifrån undersöka om vi har ett dataproblem som kan åtgärdas.

  2. Begriplighet. När vi bygger vår statistiska modell kan det vara viktigt att komma ihåg att budget är konstant för varje aktör. I allmänhet betalar utdelning för att förstå strukturen för uppgifterna.

  3. Minnesstorlek. Det kan finnas ett stort antal artister och platsattribut som inte hamnar i den statistiska modellen. På detta sätt behöver vi inte inkludera dem i tabellen (kanske massiv) som används för analys.

Programmatisk bestämning av kolumner

Om det finns många kolumner i pDT , men vi bara vill välja några, kan vi använda

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

Parenteserna runt (p_cols) := är (p_cols) := , som anges i dokumentet för att skapa kolumner .

Equi-gå

# 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

Tänk på x[i] som att välja en delmängd av x för varje rad i . Denna syntax speglar matrisuppsättning i bas R och överensstämmer med det första argumentet som betyder "var", i DT[where, select|update|do, by] .

Man kan undra varför denna nya syntax är värd att lära sig, eftersom merge(x,i) fortfarande fungerar med data.tables. Det korta svaret är att vi vanligtvis vill slå samman och sedan göra något vidare. Syntaxen x[i] fångar kortfattat detta användningsmönster och möjliggör också mer effektiv beräkning. För en mer detaljerad förklaring, läs FAQs 1.12 och 2.14 .

Hantera flera matchade rader

Som standard returneras varje rad i a matchande varje rad med b :

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

Detta kan justeras med mult :

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

Hantera oöverträffade rader

Som standard visas oöverträffade rader av a stillbild i resultatet:

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

För att dölja dessa, använd nomatch :

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

Observera att x[i] kommer att försöka matcha NA: er i i .

Räkna matcher tillbaka

För att räkna antalet matchningar för varje rad i , använd .N och 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow