R语言 滚动和

q3qa4bjr  于 11个月前  发布在  其他
关注(0)|答案(3)|浏览(158)

我正在通过dqr实现滚动求和计算,但在我的数据库中,我有许多变量只有一个或几个观测值,导致(k小于n)错误。我试图在thisj示例中使用filter和merge解决此问题,但想知道是否有一种方法可以在dqr中更优雅地自动完成此操作。请参见下面的示例

#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)

字符串
如果我运行下面的代码,因为我只有一行带有“cat”,所以会得到(Error:k <= n is not true)错误

#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))


我尝试使用下面的代码来解决这个问题,它过滤掉“cat”值并进行后续的合并,但我想知道是否可以直接在dqr中这样做,特别是在这个解决方案中,必须预先指定/知道每个变量的唯一行的数量,并手动调整是否要改变滚动和的范围等。

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


非常感谢- W

ipakzgxi

ipakzgxi1#

您可以使用RcppRoll::roll_sum,如果样本大小(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

字符串

zhte4eai

zhte4eai2#

来自RcppRoll的roll_Sum将返回NA,而不是错误,只要数据点的数量小于窗口大小。
但是,如果您想返回当前数据点的数量之和-即使小于窗口大小,您可以使用zoo中的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) )

字符串
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

yvt65v4c

yvt65v4c3#

由于rollsum本质上是“两次cumsum”之间的差异,我们可以在R中编写自己的roll_sum版本。该函数只有两行长,并且是矢量化的,所以它应该相当快。

roll_sum <- function(x) {
  y <- cumsum(x)
  y - c(NA_integer_, 0L, head(y, -2L))
}

dg %>%
  arrange(site,year,animal) %>%
  group_by(site, animal) %>%
  mutate(roll_sum = if (n() > 1L) roll_sum(count) else NA_integer_) 

# A tibble: 10 × 5
# Groups:   site, animal [3]
   site      year animal count roll_sum
   <fct>    <int> <fct>  <dbl>    <dbl>
 1 Boston    2000 dog        5       NA
 2 Boston    2001 dog        6       11
 3 Boston    2002 dog        3        9
 4 Boston    2003 dog        3        6
 5 Boston    2004 dog        3        6
 6 New York  2000 dog        6       NA
 7 New York  2001 dog        5       11
 8 New York  2002 dog        8       13
 9 New York  2003 dog       12       20
10 New York  2004 cat        3       NA

字符串
这个函数可以很容易地推广到任意滚动窗口n

roll_sum <- function(x, n) {
  y <- cumsum(x)
  y - c(rep.int(NA_integer_, n - 1L), 0L, head(y, -n))
}


这种方法的优点是,它允许轻松修改函数,以满足可能因情况而异的不同标准。

相关问题