Gestern habe ich diese Antwort gegeben: Matching Data Tables by five columns to change a value in another column.Ist es möglich, das data.table index-join-assignment-Idiom zu verwenden, um einen linken Join auszuführen und NAs in den nicht übereinstimmenden Zeilen von i an x zuzuweisen?
In den Kommentaren fragte das OP, ob wir effektiv einen linken Join der beiden Tabellen erreichen und dadurch die NAs erhalten könnten, die dazu führen würden, dass die rechte Tabelle der linken Tabelle zugewiesen würde. Es scheint mir, dass data.table keine Möglichkeit bietet, dies zu tun.
Hier ist das Beispiel Fall, dass ich in dieser Frage verwendet:
set.seed(1L);
dt1 <- data.table(id=1:12,expand.grid(V1=1:3,V2=1:4),blah1=rnorm(12L));
dt2 <- data.table(id=13:18,expand.grid(V1=1:2,V2=1:3),blah2=rnorm(6L));
dt1;
## id V1 V2 blah1
## 1: 1 1 1 -0.6264538
## 2: 2 2 1 0.1836433
## 3: 3 3 1 -0.8356286
## 4: 4 1 2 1.5952808
## 5: 5 2 2 0.3295078
## 6: 6 3 2 -0.8204684
## 7: 7 1 3 0.4874291
## 8: 8 2 3 0.7383247
## 9: 9 3 3 0.5757814
## 10: 10 1 4 -0.3053884
## 11: 11 2 4 1.5117812
## 12: 12 3 4 0.3898432
dt2;
## id V1 V2 blah2
## 1: 13 1 1 -0.62124058
## 2: 14 2 1 -2.21469989
## 3: 15 1 2 1.12493092
## 4: 16 2 2 -0.04493361
## 5: 17 1 3 -0.01619026
## 6: 18 2 3 0.94383621
key <- paste0('V',1:2);
Und hier ist die Lösung, die ich gab die nicht NAs bekommt für nicht-passende Zeilen:
dt1[dt2,on=key,id:=i.id];
dt1;
## id V1 V2 blah1
## 1: 13 1 1 -0.6264538
## 2: 14 2 1 0.1836433
## 3: 3 3 1 -0.8356286
## 4: 15 1 2 1.5952808
## 5: 16 2 2 0.3295078
## 6: 6 3 2 -0.8204684
## 7: 17 1 3 0.4874291
## 8: 18 2 3 0.7383247
## 9: 9 3 3 0.5757814
## 10: 10 1 4 -0.3053884
## 11: 11 2 4 1.5117812
## 12: 12 3 4 0.3898432
Was wir brauchen, ist für die id
Werte 12 und darunter, die in dt1
bleiben, ersetzt durch NA (nicht weil sie 12 und darunter sind, und nicht weil diese ID-Werte werden aus dt2
fehlen, sondern weil die auf den key
Spalten verbinden, nämlich V1
und V2
, führt nicht für die Zeilen in dt1
gegen dt2
in einem Spiel).
Wie ich in den Kommentaren zu dieser Frage sagte, ist eine Problemumgehung, dt1$id
allen NAs vorherzuassignieren und dann die Index-Join-Zuweisung auszuführen. Daher ist dies die erwartete Ausgabe:
dt1$id <- NA;
dt1[dt2,on=key,id:=i.id];
dt1;
## id V1 V2 blah1
## 1: 13 1 1 -0.6264538
## 2: 14 2 1 0.1836433
## 3: NA 3 1 -0.8356286
## 4: 15 1 2 1.5952808
## 5: 16 2 2 0.3295078
## 6: NA 3 2 -0.8204684
## 7: 17 1 3 0.4874291
## 8: 18 2 3 0.7383247
## 9: NA 3 3 0.5757814
## 10: NA 1 4 -0.3053884
## 11: NA 2 4 1.5117812
## 12: NA 3 4 0.3898432
Ich denke, das Problem zu umgehen ist ok, aber ich bin nicht sicher, warum data.table nicht mit einem in einem Schuss der Lage, diese Funktionalität zu sein scheint Index-Join -Betrieb zuweisen. Im Folgenden sind drei Sackgassen Ich erforschte:
1:nomatch
data.table ein nomatch
Argument liefert, die wie die all
, all.x
und all.y
Argumente von merge()
ein wenig aussieht. Dies ist eigentlich ein sehr begrenztes Argument; es erlaubt nur den Wechsel von einem rechten Join (nomatch=NA
, der Standard) zu einem inneren Join (nomatch=0
). Wir können keine linke Verbindung damit erreichen.
2: Flip dt1
und dt2
Seit dt1[dt2]
ist ein Recht kommen, wir können es nur umdrehen, was bedeutet, dt2[dt1]
, an den entsprechenden linken zu erreichen.
Das wird nicht funktionieren, weil wir brauchen die :=
in-Place-Zuordnung Syntax im j
Argumente verwenden, um in dt1
zuweisen und unter dem blätterte Anruf, werden wir stattdessen dt2
werden zuweisen. Ich versuchte, i.id
unter dem umgedrehten Befehl zuzuweisen, aber es beeinflusste nicht das ursprüngliche dt1
.
3: Verwendung merge.data.table()
Wir merge.data.table()
mit dem all.x=T
Argument nennen kann mitmachen links zu erreichen. Das Problem ist jetzt, dass merge.data.table()
kein j
Argument hat, und es bietet einfach keine Möglichkeit, eine Spalte der linken (oder rechten) Tabelle in-place zuzuordnen.
Also, ist es möglich, diese Operation überhaupt mit data.table durchzuführen? Und wenn ja, wie kann man das am besten machen?
Minor: Wenn Sie die Reihenfolge der Spalte beibehalten möchten ved, benutze 'id: = NA' anstelle von 'id: = NULL'. – Arun
Ausgezeichnete Antwort. Es ist mir nie in den Sinn gekommen, dass die ursprüngliche "id" -Spalte in "dt1" für die Konstruktion der neuen "id" -Spalte irrelevant ist. Ich nehme an, dass es keinen Vorteil für die Verwendung eines linken Joins mit dem Index-Join-Zuweisungs-Idiom geben kann, da nicht übereinstimmende Zeilen entweder alleine gelassen werden sollten (erreichbar mit einem inneren/rechten Join) oder ihre Ersatzwerte sein können unabhängig von den vorherigen Werten bestimmt, was durch vollständiges Wiederherstellen der Spalte (was zu NAs führt) oder Zuweisen des gewünschten Ersatzwerts vor der Index-Join-Zuweisungsoperation erreichbar ist. – bgoldst