【问题标题】:Dplyr window function over time frame Instead of the amount of rowsDplyr 窗口函数随时间范围而不是行数
【发布时间】:2020-08-21 17:26:00
【问题描述】:

我有一个 R tibble,它的时间列采用以下格式:“2020-08-19 07:59:05 IDT” 我想创建一个额外的列,它可以产生一些聚合功能,但在时间范围内,例如我有一个额外的列 Amount 并且我想创建一个附加列,为每一行汇总前 10 秒的所有金额.

                 Time          Amount.  SumOverTime(10 sec)
1   2020-08-19 07:57:18             0.  0
2   2020-08-19 07:57:19             1.  1
3   2020-08-19 07:57:19             1.  2
4   2020-08-19 07:57:20             0.  2
5   2020-08-19 07:57:20             2.  4
6   2020-08-19 07:57:20             0.  4
7   2020-08-19 07:57:21             0.  4
8   2020-08-19 07:57:22             0.  4
9   2020-08-19 07:57:23             1.  5
10  2020-08-19 07:57:28             0.  5
11  2020-08-19 07:57:30             0.  3
12  2020-08-19 07:57:31             0.  1
13  2020-08-19 07:57:32             0.  1

感谢您的帮助!

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    使用{slider}

    library(dplyr)
    library(slider)
    
    df %>% 
      count(Time, wt = Amount, name = "Amount") %>% 
      mutate(SumOverTime = slide_period_dbl(.x = df$Amount, .i = df$Time, 
                                            .period = "second", .before = 10,
                                            .f = sum, 
                                            .complete = FALSE))
    
    #>                   Time Amount SumOverTime
    #> 1  2020-08-19 07:57:18      0           0
    #> 2  2020-08-19 07:57:19      2           2
    #> 3  2020-08-19 07:57:20      2           4
    #> 4  2020-08-19 07:57:21      0           4
    #> 5  2020-08-19 07:57:22      0           4
    #> 6  2020-08-19 07:57:23      1           5
    #> 7  2020-08-19 07:57:28      0           5
    #> 8  2020-08-19 07:57:30      0           3
    #> 9  2020-08-19 07:57:31      0           1
    #> 10 2020-08-19 07:57:32      0           1
    

    请注意,我们会随着时间的推移与 count 进行预聚合,因为多个事件在同一秒内发生,否则问题似乎定义不明确,因此这与预期的输出不同。

    【讨论】:

    • 我收到以下错误:错误:mutate() 输入问题SumOverTime。 x .i 必须按升序排列。 ℹ 在 533521 位置没有升序。 ℹ 输入SumOverTimeslide_period_dbl(...)
    【解决方案2】:

    这里模拟一些数据:

    library(dplyr)
    library(purrr)
    
    df <- tibble(
          time = seq(lubridate::now()-10, lubridate::now(), length.out = 100) + runif(100,-10,10),
          Amount = runif(100, 0, 5)
        ) %>%
        arrange(time)
    

    然后,您可以使用 purrr:map 并提供完整的 df 作为额外参数。这使您可以轻松过滤它并提取Amount 列的总和。 可能不是超级性能,但它可以完成工作:)

    df.2 <- df %>%
        mutate(
          SumOverTime = map_dbl(time, ., .f = ~{
            .y %>% filter(time >= .x-10, time <=.x) %>% pull(Amount) %>% sum(na.rm=T)
          })
        )
    

    【讨论】:

    • 谢谢!处理整个文档需要很长时间,但它确实有效。
    • 是的,我确信在性能方面,Aurèle 提出的非天真的解决方案会更好。但很高兴听到它可以让你到达你需要的地方:)
    • 目前我收到 Aurele 解决方案的以下错误:错误:mutate() 输入问题SumOverTime。 x .i 必须按升序排列。 ℹ 533521 位置不升。 ℹ 输入SumOverTimeslide_period_dbl(...)
    • 您是否尝试通过在 count 和 mutate 行之间显式插入 arrange(Time) %&gt;% 来解决这个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-15
    • 2021-05-03
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    相关资源
    最近更新 更多