2017-12-07 9 views
1

Ich habe eine einfache data.frame, wo ich einige zusammenfassende Statistiken auf einer rollenden Basis berechnen möchte. Zum Beispiel kann ein Roll Median über ein Fenster von fünf Beobachtungen (2 Lags, aktuelle und 2 voraus) vonbenutze rollaply ohne aktuelle Zeile

library(dplyr) 
x <- data.frame("vals" = rnorm(3e04)) 
y <- x %>% 
     mutate(med5 = rollapply(data = vals, 
       width = 5, 
       FUN = median, 
       align = "center", 
       fill = NA, 
       na.rm = TRUE)) 

jedoch erreicht wird, würde Ich mag die aktuelle Zeile aus dieser Berechnung auszuschließen. Ich fand den folgenden Ansatz:

z <- x %>% 
     mutate(N=1:n()) %>% 
     do(data.frame(., prmed = sapply(.$N, function(i) median(.$vals[.$N %in% c((i - 2):(i - 1), (i + 1):(i + 2))])))) 

Das tut, was ich will, wenn ich später die ersten beiden Werte NA gesetzt.

So weit so gut, das einzige Problem ist, dass der letztere Ansatz schrecklich langsam im Vergleich zu Rollapply ist.

Gibt es einen Weg, um das Ergebnis des letzteren mit der Geschwindigkeit des ersteren zu erreichen?

Antwort

1

Eine Lösung basierend auf dem Ausschließen der dritten Zahl der fünf, die die aktuelle Zeile der Berechnung ist.

library(dplyr) 
library(zoo) 

set.seed(124) 

x <- data.frame("vals" = rnorm(3e04)) 
y <- x %>% 
    mutate(med5 = rollapply(data = vals, 
          width = 5, 
          FUN = function(x) median(x[-3], na.rm = TRUE), 
          align = "center", 
          fill = NA)) 

head(y) 
#   vals  med5 
# 1 -1.38507062  NA 
# 2 0.03832318  NA 
# 3 -0.76303016 0.1253147 
# 4 0.21230614 0.3914015 
# 5 1.42553797 0.4562678 
# 6 0.74447982 0.4562678 
+1

Funktioniert wie ein Charme, danke! Elegant, unkompliziert und leicht verallgemeinerbar für andere Funktionen als den Median. – Akkariz

2

width= Das Argument von rollapply kann eine Liste ein Element sein, um einen Vektor von Offsets enthält.

y <- x %>% 
    mutate(med5 = rollapply(data = vals, 
          width = list(c(-2, -1, 1, 2)), 
          FUN = median, 
          na.rm = TRUE, 
          fill = NA)) 

Beachten Sie, dass align = "center" der Standard ist und so muss nicht festgelegt. Wenn wir Offsets verwenden, wird align= ignoriert. Zur Sicherheit sollte TRUE vollständig ausgeschrieben werden, da T auch ein Variablenname sein kann.

Verwandte Themen