2017-08-09 1 views
3

Sagen sie, ich habe folgende data.tablegeben Sie das Datum mit vorherigem Wert von Gruppe fehlt

library(data.table) 
set.seed(123) 
df <- as.data.table(data.frame(date = c("2017-01-01", "2017-01-05", "2017-01-08", "2017-01-01", "2017-01-05", "2017-01-08"), 
       value = rnorm(6), 
       mygroup = rep(LETTERS[1:2], each = 3))) 

ich die fehlenden Daten mit dem ‚letzten‘ Wert von Gruppe füllen will. Der nächste, den ich gefunden habe, war this question, der zeigt, wie es ohne Gruppierung geht.

all_dates <- seq(from = as.Date("2017-01-01"), 
        to = as.Date("2017-01-08"), 
        by = "days") 

df[J(all_dates), roll=Inf] 

Ich brauche aber diese von der Gruppe zu tun und die by führt zu einem Fehler mit

Fehler in [.data.table (df, J (all_dates), Rolle = Inf, durch = mygroup): ‚von‘ oder ‚keyby‘ ​​geliefert wird, aber nicht j

+0

Bitte 'df [, Datum: = as.Date (Datum)]' eher als verlangen, dass as.Date unzählige Male eingegeben wird. Wie auch immer, ich denke 'df [df [,. (Date = seq (erstes (Datum), letztes (Datum), von =" Tag ")), von = mygroup], an =. (Mygroup, Datum), roll = -Inf] 'könnte es tun ..? – Frank

+0

Soll jede Gruppe einen anderen Datumsbereich haben oder wird es für jeden gleich sein (1.-8. Januar für dieses Beispiel)? Im letzteren Fall gibt es einige Fast-Duples mit CJ, wie https://stackoverflow.com/a/10473931/ – Frank

+0

@Frank jede Gruppe könnte verschiedene Bereiche haben. Ihr anfänglicher Vorschlag führt derzeit zu einem Fehler "Ein" Argument sollte eine benannte atomare Vektor-Spalte sein, die angibt, welche Spalten in 'i' mit welchen Spalten in 'x' verbunden werden sollen. – cdeterman

Antwort

3

Wir mygroup als eine weitere Säule in der Walz hinzufügen können beitreten:

df[, date := as.Date(date)] 

df[ 
    df[, .(date = seq(first(date), last(date), by="day")), by=mygroup], 
    on=.(mygroup, date), 
    roll=TRUE] 

      date  value mygroup 
1: 2017-01-01 -0.56047565  A 
2: 2017-01-02 -0.56047565  A 
3: 2017-01-03 -0.56047565  A 
4: 2017-01-04 -0.56047565  A 
5: 2017-01-05 -0.23017749  A 
6: 2017-01-06 -0.23017749  A 
7: 2017-01-07 -0.23017749  A 
8: 2017-01-08 1.55870831  A 
9: 2017-01-01 0.07050839  B 
10: 2017-01-02 0.07050839  B 
11: 2017-01-03 0.07050839  B 
12: 2017-01-04 0.07050839  B 
13: 2017-01-05 0.12928774  B 
14: 2017-01-06 0.12928774  B 
15: 2017-01-07 0.12928774  B 
16: 2017-01-08 1.71506499  B 

Das "Rollen" findet immer in der letzten Spalte in on= statt.


Wenn die Tabelle mehr Spalten hatten und wir wollten nur einige von ihnen füllen zurück ...

# extend example 
set.seed(1) 
df[, y := rpois(.N, 1)] 

# build new table 
newDT = df[, .(date = seq(first(date), last(date), by="day")), by=mygroup] 

roll_cols = "value" 
newDT[, (roll_cols) := 
    df[newDT, on=.(mygroup, date), roll=TRUE, mget(paste0("x.", roll_cols))]] 

noroll_cols = "y" 
newDT[df, on=.(mygroup, date), (noroll_cols) := mget(paste0("i.", noroll_cols)) ] 

    mygroup  date  value y 
1:  A 2017-01-01 -0.56047565 0 
2:  A 2017-01-02 -0.56047565 NA 
3:  A 2017-01-03 -0.56047565 NA 
4:  A 2017-01-04 -0.56047565 NA 
5:  A 2017-01-05 -0.23017749 1 
6:  A 2017-01-06 -0.23017749 NA 
7:  A 2017-01-07 -0.23017749 NA 
8:  A 2017-01-08 1.55870831 1 
9:  B 2017-01-01 0.07050839 2 
10:  B 2017-01-02 0.07050839 NA 
11:  B 2017-01-03 0.07050839 NA 
12:  B 2017-01-04 0.07050839 NA 
13:  B 2017-01-05 0.12928774 0 
14:  B 2017-01-06 0.12928774 NA 
15:  B 2017-01-07 0.12928774 NA 
16:  B 2017-01-08 1.71506499 2 
+0

Das ist sehr schließen, aber ich möchte es aus dem vorherigen Wert füllen (z. B. sollte der '2017-01-02' Wert' -0.56047565' sein, – cdeterman

+0

Ah doh, ich habe es falsch gelesen. Das Umschalten auf 'roll = TRUE' sollte das tun Ich repariere das. Hilft, die gewünschte Ausgabe allgemein zu sehen, fyi. – Frank