【问题标题】:Rolling sum of one variable in data.frame in number of steps defined by another variabledata.frame 中一个变量的滚动总和,以另一个变量定义的步数计算
【发布时间】:2020-12-06 09:06:57
【问题描述】:

我正在尝试以累积的方式总结 data.frame 中的值。

我有这个:

df <- data.frame(
  a = rep(1:2, each = 5),
  b = 1:10,
  step_window = c(2,3,1,2,4, 1,2,3,2,1)
)

我试图在a 组中总结b 的值。诀窍是,我想要b 值的总和对应于step_window 给出的当前行之后的行数。

这是我正在寻找的输出:

data.frame(
    a = rep(1:2, each = 5),
    step_window = c(2,3,1,2,4, 
                    1,2,3,2,1),
    b = 1:10,
    sum_b_step_window = c(3, 9, 3, 9, 5,
                          6, 15, 27, 19, 10)
  ) 

我尝试使用RcppRoll 执行此操作,但收到错误Expecting a single value

df %>% 
  group_by(a) %>% 
  mutate(sum_b_step_window = RcppRoll::roll_sum(x = b, n = step_window))

【问题讨论】:

    标签: r dplyr rolling-computation


    【解决方案1】:

    1) 滚动应用

    rollapply in zoo 支持向量宽度。 partial=TRUE 表示如果宽度超过末尾,则仅使用数据中的值。 (另一种可能性是使用 fill=NA 代替,在这种情况下,如果没有足够的数据,它将填充 NA)。 align="left" 指定每一步的当前值是求和范围的左端。

    library(dplyr)
    library(zoo)
    
    df %>%
      group_by(a) %>%
      mutate(sum = rollapply(b, step_window, sum, partial = TRUE, align = "left")) %>%
      ungroup
    

    2) SQL

    这也可以在 SQL 中通过在指定条件下将 df 与自身连接起来,然后将每一行与条件匹配的所有行相加来完成。

    library(sqldf)
    
    sqldf("select A.*, sum(B.b) as sum
      from df A 
      left join df B on B.rowid between A.rowid and A.rowid + A.step_window - 1
        and A.a = B.a
      group by A.rowid")
    

    【讨论】:

      【解决方案2】:

      data.table 使用累积和的解决方案

      setDT(df)
      df[, sum_b_step_window := {
        cs <- c(0,cumsum(b))
        cs[pmin(.N+1, 1:.N+step_window)]-cs[pmax(1, (1:.N))]
      },by = a]
      

      【讨论】:

        【解决方案3】:

        这里是slider 包的解决方案。

        library(dplyr)
        library(slider)
        
        df %>%
            group_by(a) %>% 
            mutate(sum_b_step_window = hop_vec(b, row_number(), step_window+row_number()-1, sum)) %>% 
            ungroup() 
        

        它在不同的窗口大小上是灵活的。

        输出:

        # A tibble: 10 x 4
               a     b step_window sum_b_step_window
           <int> <int>       <dbl>             <int>
         1     1     1           2                 3
         2     1     2           3                 9
         3     1     3           1                 3
         4     1     4           2                 9
         5     1     5           4                 5
         6     2     6           1                 6
         7     2     7           2                15
         8     2     8           3                27
         9     2     9           2                19
        10     2    10           1                10
        

        slider 是几个月前的 tidyverse 包,专门用于滑动窗口功能。在这里查看更多信息:pagevignette

        hopslider 的引擎。使用此解决方案,我们将触发不同的 .start.stop 以根据 a 组对 b 的值求和。

        对于_vec,您要求hop 返回一个向量:在这种情况下为双精度数。

        row_number() 是一个dplyr 函数,允许您返回每个组的行号,从而允许您沿行滑动。

        【讨论】:

          【解决方案4】:

          我不确定是否可以在任何滚动功能中使用可变窗口大小。这是使用map2_dbl 的一种方法:

          library(dplyr)
          df %>% 
            group_by(a) %>% 
            mutate(sum_b_step_window = purrr::map2_dbl(row_number(), step_window, 
                                       ~sum(b[.x:(.x + .y - 1)], na.rm = TRUE)))
          
          #      a     b step_window sum_b_step_window
          #   <int> <int>       <dbl>             <dbl>
          # 1     1     1           2                 3
          # 2     1     2           3                 9
          # 3     1     3           1                 3
          # 4     1     4           2                 9
          # 5     1     5           4                 5
          # 6     2     6           1                 6
          # 7     2     7           2                15
          # 8     2     8           3                27
          # 9     2     9           2                19
          #10     2    10           1                10
          

          【讨论】:

            猜你喜欢
            • 2014-08-15
            • 1970-01-01
            • 2013-06-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-02-23
            • 2011-11-14
            相关资源
            最近更新 更多