2017-12-19 4 views
2

Ich habe die folgende Funktion in R geschrieben, um die zweitägigen mittleren VARs für jedes Datum und jeden vorherigen Tag für einen Datenrahmen mit den Spaltennamen DATE (YYYY-MM-DD), ID, VAR1 und VAR2. Es gibt keine fehlenden Daten.Durchschnittliche Zeile und ihre vorherige Zeile in einem dat.frame

df <- data.frame 

TWODAY <- function(df){ 

df$TWODAY_VAR1 <- NA 
for(j in 2:length(df$VAR1)){ 
df$TWODAY_VAR1[j] <- mean(df$VAR1[j:(j-1)]) 
} 

df$TWODAY_VAR2 <- NA 
for(j in 2:length(df$VAR2)){ 
df$TWODAY_VAR2[j] <- mean(df$VAR2[j:(j-1)]) 
} 

return(df) 
} 

Ich bewerben ich dann diese Funktion meines Datenrahmen mit ddply:

df <- ddply(df, "ID", TWODAY) 

jedoch mein Datenrahmen besteht aus mehr als 13 Millionen Beobachtungen, und dies sehr langsam läuft. Hat jemand irgendwelche Empfehlungen, wie ich meinen Code bearbeiten könnte, um ihn effizienter zu machen?

Jeder Rat würde sehr geschätzt werden!

+2

ich denke, der geeignete Ort für diese Frage ist [Code Review Stapel Tausch] (https://codereview.stackexchange.com/). – andrewnagyeb

+0

sollten Sie ein reproduzierbares Beispiel geben https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-beispiel – minem

Antwort

3

Eine manuelle Vektorisierung:

FOO <- function(x){ 
    c(NA, (x[2:length(x)]+x[1:(length(x)-1)])/2) 
} 

Beispiel:

set.seed(123) 
df <- data.frame(VAR1 = rnorm(10000), VAR2 = runif(10000)) 

> head(df) 
     VAR1  VAR2 
1 -0.56047565 0.9911234 
2 -0.23017749 0.3022307 
3 1.55870831 0.4337590 
4 0.07050839 0.1605209 
5 0.12928774 0.8230267 
6 1.71506499 0.2080906 

df$TWODAY_VAR1 <- FOO(df$VAR1) 
df$TWODAY_VAR2 <- FOO(df$VAR2) 

> head(df) 
     VAR1  VAR2 TWODAY_VAR1 TWODAY_VAR2 
1 -0.56047565 0.9911234   NA   NA 
2 -0.23017749 0.3022307 -0.39532657 0.6466770 
3 1.55870831 0.4337590 0.66426541 0.3679948 
4 0.07050839 0.1605209 0.81460835 0.2971400 
5 0.12928774 0.8230267 0.09989806 0.4917738 
6 1.71506499 0.2080906 0.92217636 0.5155586 

Dies sollte ziemlich schnell sein, sogar mit 13 Millionen Zeilen. Eine Million Zeilen dauert einen Bruch von einer Sekunde für mich.


Benchmark für eine einzelne Variable mit 13.000.000 Zeilen:

> b 
Unit: seconds 
          expr  min  lq  mean median  uq  max neval 
df$TWODAY_VAR1 <- FOO(df$VAR1) 0.182657 0.209106 0.2308234 0.2175971 0.2239455 0.3119504 10 
2

rowMeans Lösung unter Verwendung von:

nRow <- 13e6 
df <- data.frame(VAR1 = rnorm(nRow), 
       VAR2 = rnorm(nRow)) 
df$TWODAY_VAR1 <- rowMeans(cbind(df$VAR1, c(NA, df$VAR1[-nrow(df)]))) 
df$TWODAY_VAR2 <- rowMeans(cbind(df$VAR2, c(NA, df$VAR2[-nrow(df)]))) 

cbind zwei Vektoren cbind(df$VAR1, c(df$VAR1[-1], NA) (NA zur letzten Reihe) und gelten rowMeans.

+0

'NA' sollte nicht vorne sein? – minem

Verwandte Themen