2016-07-09 8 views
7

Dies ist, was meine Datentabelle wie folgt aussieht:Holen Sie sich das letzte Zeile einer vorherigen Gruppe in data.table

library(data.table) 
dt <- fread(' 
    Product Group LastProductOfPriorGroup 
    A   1   NA 
    B   1   NA 
    C   2   B 
    D   2   B 
    E   2   B 
    F   3   E 
    G   3   E 
') 

Die LastProductOfPriorGroup Spalte ist meine gewünschte Spalte. Ich versuche, das Produkt aus der letzten Reihe der vorherigen Gruppe zu holen. In den ersten beiden Zeilen gibt es also keine vorherigen Gruppen und daher ist es NA. In der dritten Zeile ist das Produkt in der letzten Zeile der vorherigen Gruppe 1 B. Ich versuche, dies zu erreichen, indem

dt[,LastGroupProduct:= shift(Product,1), by=shift(Group,1)] 

vergeblich.

Antwort

14

Sie könnten

dt[, newcol := shift(dt[, last(Product), by = Group]$V1)[.GRP], by = Group] 

tun Daraus ergibt sich die dt aktualisiert Folgendes ein, wobei newcol Ihre gewünschte Spalte mit der unnötig langen Namen übereinstimmt. ;)

Product Group LastProductOfPriorGroup newcol 
1:  A  1      NA  NA 
2:  B  1      NA  NA 
3:  C  2      B  B 
4:  D  2      B  B 
5:  E  2      B  B 
6:  F  3      E  E 
7:  G  3      E  E 

Lassen Sie uns den Code von innen nach außen brechen. Ich werde ... verwenden, um die akkumulierte Code zu bezeichnen:

  • dt[, last(Product), by = Group]$V1 wird die letzten Werte aus jeder Gruppe als ein Zeichen Vektor bekommen.
  • shift(...) verschiebt den Zeichenvektor im vorherigen Aufruf
  • dt[, newcol := ...[.GRP], by = Group] Gruppen von Group und verwendet die internen .GRP Werte für die Indizierung

Update: Frank über die Berechnung die Verschiebung einen guten Punkt, um meinen Code bringt für jede Gruppe immer und immer wieder. Um dies zu vermeiden, können wir entweder

verwenden, so dass wir die Verschiebung nicht für jede Gruppe berechnen. Oder wir können Franks netten Vorschlag in den Kommentaren nehmen und folgendes tun.

+0

Sie verwenden by = Gruppe 2 mal. Was macht der 1. gegen den 2.? und was ist die Bedeutung von $ V1? – gibbz00

+1

@ gibbz00 - Ich habe eine Erklärung hinzugefügt. Ich hoffe es hilft. –

+1

Sie berechnen 'shift (dt [, last (Product), by = Gruppe] $ V1)' immer wieder für jede Gruppe. Ich würde wahrscheinlich 'dt [dt [, last (Produkt), by = Gruppe] [, v: = shift (V1)], on =" Gruppe ", newcol: = iv]' – Frank

7

Eine andere Möglichkeit besteht darin, den Wert der letzten Gruppe in einer Variablen zu speichern.

this = NA_character_ # initialize 
dt[, LastProductOfPriorGroup:={ last<-this; this<-last(Product); last }, by=Group] 
dt 
    Product Group LastProductOfPriorGroup 
1:  A  1      NA 
2:  B  1      NA 
3:  C  2      B 
4:  D  2      B 
5:  E  2      B 
6:  F  3      E 
7:  G  3      E 

NB: last() ist eine data.table Funktion, die das letzte Element eines Vektors (der Produktsäule in diesem Fall) zurückgibt.

Dies sollte auch schnell sein, da keine Logik aufgerufen wird, um den Wert der letzten Gruppe abzurufen; es hängt nur von den Gruppen ab, die in Reihenfolge laufen (was sie tun).

Verwandte Themen