2015-05-10 23 views
12

Ich implementiere eine rollende Summenberechnung durch dplyr, aber in meiner Datenbank habe ich eine Anzahl von Variablen, die nur eine oder nur wenige Beobachtungen haben, was einen (k ist kleiner als n) Fehler verursacht. Ich habe versucht, dies in diesem Beispiel mit Filter und Zusammenführen zu lösen, aber frage mich, ob es eine Möglichkeit gibt, dies eleganter und automatischer innerhalb von dplyr zu tun. bitte das folgende BeispielR dplyr rollende Summe

#create data 
    dg = expand.grid(site = c("Boston","New York"), 
        year = 2000:2004) 
    dg$animal="dog" 
    dg$animal[10]="cat";dg$animal=as.factor(dg$animal) 
    dg$count = rpois(dim(dg)[1], 5) 

sehen, ob ich den Code unten laufen würde, weil ich mit „cat“ nur eine Zeile haben, so erhält man die (Fehler: < k = n ist nicht wahr) Fehler

#running average 
dg2 = dg %>% 
    arrange(site,year,animal) %>% 
    group_by(site,animal) %>% 
# filter(animal=="dog") %>% 
    mutate(roll_sum = rollsum(x = count, 2, align = "right", fill = NA)) 

Ich habe versucht, dies zu lösen, indem Sie den folgenden Code verwenden, der den "cat" -Wert herausfiltert und eine anschließende Zusammenführung, aber ich frage mich, ob man dies direkt in dplyr tun kann, vor allem wie in dieser Lösung hätte um die Anzahl eindeutiger Zeilen für jede Variable im Voraus anzugeben/zu kennen und manuell anzupassen, wenn man den Bereich der rollenden Summe usw. ändern würde.

dg2 = dg %>% 
    arrange(site,year,animal) %>% 
    group_by(site,animal) %>% 
    filter(animal=="dog") %>% 
    mutate(roll_sum = rollsum(x = count, 2, align = "right", fill = NA)) 

merge(dg,dg2,c("site", "year","animal","count"),all.x=TRUE) 

     site year animal count roll_sum 
1 Boston 2000 dog  5  NA 
2 Boston 2001 dog  6  11 
3 Boston 2002 dog  6  12 
4 Boston 2003 dog  5  11 
5 Boston 2004 dog  3  8 
6 New York 2000 dog  8  NA 
7 New York 2001 dog  3  11 
8 New York 2002 dog 12  15 
9 New York 2003 dog  3  15 
10 New York 2004 cat  3  NA 

Vielen Dank - W

Antwort

19

können Sie stattdessen RcppRoll::roll_sum verwenden, die NA zurückgibt, wenn die Stichprobengröße (n) kleiner ist als die Fenstergröße (k).

set.seed(1) 
dg$count = rpois(dim(dg)[1], 5) 
library(RcppRoll) 
library(dplyr) 
dg %>% 
    arrange(site,year,animal) %>% 
    group_by(site, animal) %>% 
    mutate(roll_sum = roll_sum(count, 2, align = "right", fill = NA))  
#  site year animal count roll_sum 
#1 Boston 2000 dog  4  NA 
#2 Boston 2001 dog  5  9 
#3 Boston 2002 dog  3  8 
#4 Boston 2003 dog  9  12 
#5 Boston 2004 dog  6  15 
#6 New York 2000 dog  4  NA 
#7 New York 2001 dog  8  12 
#8 New York 2002 dog  8  16 
#9 New York 2003 dog  6  14 
#10 New York 2004 cat  2  NA 
-3
library(dplyr) 
dg %>% 
    arrange(site,year,animal) %>% 
    group_by(site,animal) %>% 
    mutate(rollsum=cumsum(count)) 
+0

Dies bietet keine Antwort auf die Frage –

5

roll_Sum von RcppRoll wird eine NA anstelle von einem Fehler zurück, wo die Anzahl der Datenpunkte, die kleiner als die Fenstergröße ist.

Wenn Sie jedoch die Summe der Anzahl der vorhandenen Datenpunkte zurückgeben möchten - auch wenn kleiner als das Fenster die Größe, können Sie die Rollapplyr-Funktion von Zoo verwenden.

library(zoo) 
library(dplyr) 

    dg %>% 
     arrange(site,year,animal) %>% 
     group_by(site, animal) %>% 
     mutate(roll_sum = roll_sum(count, 2, align = "right", fill = NA)) %>% 
     mutate(rollapply_sum =rollapplyr(count, 2, sum, partial = TRUE)) 

Rollapply_sum wird den ursprünglichen Wert oder die Summe der Datenpunkte vorhanden, zurück, auch wenn sein kleiner als die Fenstergröße statt Rückkehr NA.

 site year animal count roll_sum rollapply_sum 
    (fctr) (int) (fctr) (int) (dbl)   (int) 
1 Boston 2000 dog  4  NA    4 
2 Boston 2001 dog  5  9    9 
3 Boston 2002 dog  3  8    8 
4 Boston 2003 dog  9  12   12 
5 Boston 2004 dog  6  15   15 
6 New York 2000 dog  4  NA    4 
7 New York 2001 dog  8  12   12 
8 New York 2002 dog  8  16   16 
9 New York 2003 dog  6  14   14 
10 New York 2004 cat  2  NA    2