Abbiamo creato nuovo (e più completo) HTML vignettes per alcuni dei concetti data.table. Date un'occhiata allo here per le altre vignette su cui stiamo lavorando. Sto lavorando a delle vignette per i join, che una volta terminate, si spera che chiariscano meglio questo tipo di problemi.
L'idea è di primo setkey()
sul DT1
sulla colonna tract
.
setkey(DT1, tract)
In data.tables, un join della forma x[i]
richiede chiave per x
, ma non necessariamente per i
. Ciò si traduce in due scenari:
Se i
ha anche set di chiavi - la prima colonna chiave di i
è confrontato prima colonna chiave di x
, secondo contro la seconda e così via ..
Se i
non dispone del set di chiavi - la prima colonna di i
viene confrontato con il primo chiave colonna x
, seconda colonna della i
contro la seconda chiave colonna x
e così via ..
In questo caso, poiché la vostra prima colonna i
è anche tract
, faremo saltare l'impostazione della chiave i
.
Quindi, eseguiamo un join del modulo x[i]
. In questo modo, per ogni i
vengono calcolati gli indici di riga corrispondenti in x
e quindi il risultato del join viene materializzato. Tuttavia, non vogliamo che l'intero risultato del join sia un nuovo data.table. Piuttosto, vogliamo aggiornare DT1
's CreditScore
colonna con DT2
' s su tali righe corrispondenti ..
In data.tables, possiamo eseguire tale operazione mentre unione, fornendo l'espressione in j
, come segue:
DT1[DT2, CreditScore := i.CreditScore]
# tract CreditScore
# 1: 36067013000 777
# 2: 36083052304 663
# 3: 36083052403 650
# 4: 36091062602 335
# 5: 36107020401 635
DT1[DT2
parte rileva le righe corrispondenti in DT1
per ogni riga DT2
. E se c'è una corrispondenza, vogliamo che il valore di DT2
sia aggiornato in DT1
.Lo realizziamo usando i.CreditScore
- si riferisce alla colonna DT2
CreditScore
(i.
è un prefisso utilizzato per distinguere le colonne con nomi identici tra x
e i
data.tables).
Aggiornamento: Come sottolineato in commenti, la soluzione di cui sopra potrebbe anche aggiornare i valori non-NA in DT1
. Quindi il modo per farlo sarebbe:
DT1[is.na(CreditScore), CreditScore := DT2[.(.SD), CreditScore]]
Per questi righe dove CreditScore
da DT1
è NA
, sostituire CreditScore
da DT1
con i valori da CreditScore
ottenuta dal punto di giunzione di DT2[.(.SD)]
, dove .SD
corrisponde al sottoinsieme dei dati .table che contiene tutte le righe in cui CreditScore
è NA
.
HTH
Se si utilizza il pacchetto 'data.table', è necessario chiarirlo nella domanda. Non mi è chiaro se intendi una struttura dati specifica per 'data.table' o la struttura di base' data.frame'. C'è un motivo (come problemi di dimensioni/memoria) non puoi semplicemente unire le due tabelle e usare 'ifelse()' per creare una nuova colonna che abbia il valore appropriato? –
@Alex, sì, c'è. Poteva anche caricare i dati in Excel e fare un 'vlookup', vero? In particolare, 'data.table' può eseguire un join * binary * e aggiornare le colonne * per riferimento durante l'unione *. Ciò sarebbe più efficiente di "unire" + "ifelse" da diversi fattori su un grande insieme di dati. –
Grazie per i vostri commenti. Sì, il motivo principale per cui scelgo di utilizzare il pacchetto data.table è la sua efficienza complessiva. Non volevo aggiungere un'altra colonna a DT1 se non ne avessi avuto bisogno. Proverò la risposta qui sotto e vedrò come funziona ..... grazie e grazie! – user3067851