【问题标题】:Aggregate a tibble based on a consecutive values in a boolean column根据布尔列中的连续值聚合小标题
【发布时间】:2019-03-22 10:12:05
【问题描述】:

我遇到了一个相当直接的问题,但我正在努力寻找一个不需要大量代码和复杂循环的解决方案。

我有一个汇总表 df,用于每小时时间序列数据集,其中每个观察值都属于一个组。 我想根据汇总表中的布尔列合并其中的一些组。 布尔列merge_with_next 指示给定组是否应与下一个组合并(向下一行)。 合并通过更新end,值和删除行有效地发生:

library(dplyr)

# Demo data
df <- tibble(
  group = 1:12,
  start = seq.POSIXt(as.POSIXct("2019-01-01 00:00"), as.POSIXct("2019-01-12 00:00"), by = "1 day"),
  end = seq.POSIXt(as.POSIXct("2019-01-01 23:59"), as.POSIXct("2019-01-12 23:59"), by = "1 day"), 
  merge_with_next = rep(c(TRUE, TRUE, FALSE), 4)
)

df
#> # A tibble: 12 x 4
#>    group start               end                 merge_with_next
#>    <int> <dttm>              <dttm>              <lgl>          
#>  1     1 2019-01-01 00:00:00 2019-01-01 23:59:00 TRUE           
#>  2     2 2019-01-02 00:00:00 2019-01-02 23:59:00 TRUE           
#>  3     3 2019-01-03 00:00:00 2019-01-03 23:59:00 FALSE          
#>  4     4 2019-01-04 00:00:00 2019-01-04 23:59:00 TRUE           
#>  5     5 2019-01-05 00:00:00 2019-01-05 23:59:00 TRUE           
#>  6     6 2019-01-06 00:00:00 2019-01-06 23:59:00 FALSE          
#>  7     7 2019-01-07 00:00:00 2019-01-07 23:59:00 TRUE           
#>  8     8 2019-01-08 00:00:00 2019-01-08 23:59:00 TRUE           
#>  9     9 2019-01-09 00:00:00 2019-01-09 23:59:00 FALSE          
#> 10    10 2019-01-10 00:00:00 2019-01-10 23:59:00 TRUE           
#> 11    11 2019-01-11 00:00:00 2019-01-11 23:59:00 TRUE           
#> 12    12 2019-01-12 00:00:00 2019-01-12 23:59:00 FALSE

# Desired result
desired <- tibble(
  group = c(1, 4, 7, 9),
  start = c("2019-01-01 00:00", "2019-01-04 00:00", "2019-01-07 00:00", "2019-01-10 00:00"),
  end = c("2019-01-03 23:59", "2019-01-06 23:59", "2019-01-09 23:59", "2019-01-12 23:59")
)

desired
#> # A tibble: 4 x 3
#>   group start            end             
#>   <dbl> <chr>            <chr>           
#> 1     1 2019-01-01 00:00 2019-01-03 23:59
#> 2     4 2019-01-04 00:00 2019-01-06 23:59
#> 3     7 2019-01-07 00:00 2019-01-09 23:59
#> 4     9 2019-01-10 00:00 2019-01-12 23:59

由 reprex 包 (v0.2.1) 于 2019-03-22 创建

我正在寻找一种不涉及大量辅助表和循环的简短而清晰的解决方案。 group 列中的最终值并不重要,我只关心结果中的startend 列。

【问题讨论】:

    标签: r dplyr tibble


    【解决方案1】:

    我们可以使用dplyr 并根据merge_with_next 列中出现的每次TRUE 值创建组,并从start 中选择first 值,并从end 列中为每个组选择last 值。

    library(dplyr)
    
    df %>%
      group_by(temp = cumsum(!lag(merge_with_next, default = TRUE))) %>%
      summarise(group = first(group),
                start = first(start), 
                end = last(end)) %>%
      ungroup() %>%
      select(-temp)
    
    #  group start               end     
    #  <int> <dttm>              <dttm>             
    #1     1 2019-01-01 00:00:00 2019-01-03 23:59:00
    #2     4 2019-01-04 00:00:00 2019-01-06 23:59:00
    #3     7 2019-01-07 00:00:00 2019-01-09 23:59:00
    #4    10 2019-01-10 00:00:00 2019-01-12 23:59:00
    

    【讨论】:

    • 完美!非常感谢。
    猜你喜欢
    • 2019-10-13
    • 2020-12-23
    • 2018-03-03
    • 1970-01-01
    • 2021-01-27
    • 2020-04-01
    • 2020-01-05
    • 2018-11-07
    • 1970-01-01
    相关资源
    最近更新 更多