R dplyr滚动总和

use*_*116 17 r dplyr

我正在通过dplyr实现滚动和计算,但是在我的数据库中,我有许多变量只有一个或只有几个观察值,导致(k小于n)错误.我试图在这个带有过滤器和合并的例子中解决这个问题,但是想知道是否有办法在dplyr中更优雅和自动地做到这一点.请看下面的例子

    #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) 
Run Code Online (Sandbox Code Playgroud)

如果我将运行下面的代码,因为我只有一行"cat",一个得到(错误:k <= n不是真的)错误

#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))
Run Code Online (Sandbox Code Playgroud)

我试图通过使用以下代码解决这个问题,该代码过滤掉"cat"值并进行后续合并,但我想知道是否可以直接在dplyr中执行此操作,尤其是在此解决方案中,必须指定/事先知道每个变量的唯一行数,如果改变滚动总和的范围等,则手动调整.

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
Run Code Online (Sandbox Code Playgroud)

非常感谢 - W

Kha*_*haa 33

RcppRoll::roll_sum如果样本size(n)小于窗口大小(k),则可以使用返回NA .

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
Run Code Online (Sandbox Code Playgroud)


小智 14

来自RcppRoll的roll_Sum将返回一个NA来代替错误,只要数据点的数量小于窗口大小.

但是,如果要返回存在的数据点数之和 - 即使小于窗口大小,也可以使用动物园中的rollapplyr函数.

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) )
Run Code Online (Sandbox Code Playgroud)

Rollapply_sum将返回原始值或存在的数据点总和,即使它小于窗口大小而不是返回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
Run Code Online (Sandbox Code Playgroud)