【问题标题】:Summary of N recent valuesN 个最近值的汇总
【发布时间】:2019-01-17 20:22:34
【问题描述】:

我正在尝试获取最近 N 个值的汇总统计信息(此处为总和和最大值)。

起始数据:

dt = data.table(id = c('a','a','a','a','b','b','b','b'),
                week = c(1,2,3,4,1,2,3,4),
                value = c(2, 3, 1, 0, 5, 7,3,2))

期望的结果:

dt = data.table(id = c('a','a','a','a','b','b','b','b'),
                    week = c(1,2,3,4,1,2,3,4),
                    value = c(2, 3, 1, 0, 5, 7,3,2),
                    sum_recent2week = c(NA, NA, 5, 4, NA, NA, 12, 10),
                    max_recent2week = c(NA, NA, 3, 3, NA, NA, 7, 7))

对于这些数据,我希望按 id 为每行获取 2 个 (N=2) 最近值的总和和最大值。第 4(sum_recent2week)和第 5(max_recent2week)列是我想要的列

【问题讨论】:

标签: r dplyr tibble


【解决方案1】:

您可以使用zoo 包中的rollsumrollmax

dt[, `:=`(sum_recent2week = 
            shift(rollsum(value, 2, align = 'left', fill = NA), 2),
          max_recent2week = 
            shift(rollmax(value, 2, align = 'left', fill = NA), 2))
   , id]

总而言之,如果您使用的数据表版本 >= 1.12,则可以使用data.table::frollmeanfrollmean 的默认值为fill = NA,因此在这种情况下无需指定。

dt[, `:=`(sum_recent2week = 
            shift(frollmean(value, 2, align = 'left')*2, 2),
          max_recent2week = 
            shift(rollmax(value, 2, align = 'left', fill = NA), 2))
   , id]

【讨论】:

    【解决方案2】:

    我确信它可以以更优雅的方式完成,但这里有一个tidyverse 的可能性:

    dt %>%
     group_by(id) %>%
     mutate(sum_recent2week = lag(value + lead(value), n = 2),
            max_recent2week = pmax(lag(value, n = 2), lag(value, n = 1))) %>%
     rowid_to_column() %>%
     select(-week, -value) %>%
     top_n(-2) %>%
     right_join(dt %>%
                rowid_to_column(), by = c("rowid" = "rowid",
                                          "id" = "id")) %>%
     select(-rowid)
    
      id    sum_recent2week max_recent2week  week value
      <chr>           <dbl>           <dbl> <dbl> <dbl>
    1 a                 NA              NA     1.    2.
    2 a                 NA              NA     2.    3.
    3 a                  5.              3.    3.    1.
    4 a                  4.              3.    4.    0.
    5 b                 NA              NA     1.    5.
    6 b                 NA              NA     2.    7.
    7 b                 12.              7.    3.    3.
    8 b                 10.              7.    4.    2.
    

    首先,它计算每组的“sum_recent2week”和“max_recent2week”。其次,它选择每组的最后两行。最后,将其与原始数据合并。

    或者,如果您想为所有行计算它,而不仅仅是每组的最后两行:

    dt %>%
     group_by(id) %>%
     mutate(sum_recent2week = lag(value + lead(value), n = 2),
            max_recent2week = pmax(lag(value, n = 2), lag(value, n = 1)))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多