【问题标题】:Get all possible combinations in a time-series data with variable daily readings获取具有可变每日读数的时间序列数据中的所有可能组合
【发布时间】:2021-10-30 11:43:37
【问题描述】:

我有一个每日消费的时间序列数据集,如下所示:

consumption <- data.frame(
  date = as.Date(c('2020-06-01','2020-06-02','2020-06-03','2020-06-03',
                   '2020-06-03','2020-06-04','2020-06-05','2020-06-05')),
  val = c(10,20,31,32,33,40,51,52)
)

consumption <- consumption %>%
  group_by(date) %>%
  mutate(n = n(), record = row_number()) %>%
  ungroup()

consumption

# A tibble: 8 × 4
  date         val     n record
  <date>     <dbl> <int>  <int>
1 2020-06-01    10     1      1
2 2020-06-02    20     1      1
3 2020-06-03    31     3      1
4 2020-06-03    32     3      2
5 2020-06-03    33     3      3
6 2020-06-04    40     1      1
7 2020-06-05    51     2      1
8 2020-06-05    52     2      2

有些日子在数据集中有不止一行。我想将其转换为具有所有可能组合的拆分组,例如:

第 1 组:

        date val record
1 2020-06-01  10      1
2 2020-06-02  20      1
3 2020-06-03  31      1
4 2020-06-04  40      1
5 2020-06-05  51      1

第 2 组:

        date val record
1 2020-06-01  10      1
2 2020-06-02  20      1
3 2020-06-03  31      1
4 2020-06-04  40      1
5 2020-06-05  52      2

第 3 组:

        date val record
1 2020-06-01  10      1
2 2020-06-02  20      1
3 2020-06-03  32      2
4 2020-06-04  40      1
5 2020-06-05  51      1

第 4 组:

        date val record
1 2020-06-01  10      1
2 2020-06-02  20      1
3 2020-06-03  32      2
4 2020-06-04  40      1
5 2020-06-05  52      2

第 5 组:

        date val record
1 2020-06-01  10      1
2 2020-06-02  20      1
3 2020-06-03  33      3
4 2020-06-04  40      1
5 2020-06-05  51      1

第 6 组:

        date val record
1 2020-06-01  10      1
2 2020-06-02  20      1
3 2020-06-03  33      3
4 2020-06-04  40      1
5 2020-06-05  52      2

我尝试了以下解决方案,但没有产生预期的结果。

library(dplyr)
library(purrr)
out <- consumption %>% 
   filter(n > 1) %>%
    group_split(date, rn = row_number()) %>% 
    map(~ bind_rows(consumption %>%
          filter(n == 1), .x %>%
             select(-rn)) %>% 
         arrange(date))

非常感谢您帮助解决这个问题。

非常感谢,

【问题讨论】:

    标签: r dplyr purrr


    【解决方案1】:

    这是一种使用一些基本dplyrtidyr 函数的方法。

    首先,完成每个日期/副本组合的数据。然后用先前的值填充缺失的值,并重新整形。

    library(tidyverse)
    consumption %>%
       complete(date, record) %>%
       group_by(date) %>% fill(val) %>% ungroup() %>%
       pivot_wider(-n, names_from = record, values_from = val)
    
    # A tibble: 5 x 4
      date         `1`   `2`   `3`
      <date>     <dbl> <dbl> <dbl>
    1 2020-06-01    10    10    10
    2 2020-06-02    20    20    20
    3 2020-06-03    31    32    33
    4 2020-06-04    40    40    40
    5 2020-06-05    51    52    52
    

    【讨论】:

      【解决方案2】:

      我们可以filter 'record' 大于 1,group_split 通过 'row_number' 和 'date',然后将行与 filtered 数据绑定,其中 'record' 为 1

      library(dplyr)
      library(purrr)
      out <- consumption %>% 
         filter(n > 1) %>%
          group_split(date, rn = row_number()) %>% 
          map(~ bind_rows(consumption %>%
                filter(n == 1), .x %>%
                   select(-rn)) %>% 
               arrange(date))
      

      -输出

      > out
      [[1]]
      # A tibble: 4 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    31     3      1
      4 2020-06-04    40     1      1
      
      [[2]]
      # A tibble: 4 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    32     3      2
      4 2020-06-04    40     1      1
      
      [[3]]
      # A tibble: 4 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    33     3      3
      4 2020-06-04    40     1      1
      

      使用更新后的数据,我们创建row_number(),然后按“日期”列创建split(如在@ThomasIsCoding 解决方案中),使用crossing(来自purrr)扩展数据,然后循环在pmap的行上,slice基于行索引的原始数据的行

      library(tidyr)
      library(tibble)
      consumption %>%
           transmute(date, rn = row_number()) %>%
           deframe %>%
           split(names(.)) %>%
           invoke(crossing, .) %>%
           pmap(~ consumption %>% 
              slice(c(...))) %>%
           unname
      

      -输出

      [[1]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    31     3      1
      4 2020-06-04    40     1      1
      5 2020-06-05    51     2      1
      
      [[2]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    31     3      1
      4 2020-06-04    40     1      1
      5 2020-06-05    52     2      2
      
      [[3]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    32     3      2
      4 2020-06-04    40     1      1
      5 2020-06-05    51     2      1
      
      [[4]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    32     3      2
      4 2020-06-04    40     1      1
      5 2020-06-05    52     2      2
      
      [[5]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    33     3      3
      4 2020-06-04    40     1      1
      5 2020-06-05    51     2      1
      
      [[6]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    33     3      3
      4 2020-06-04    40     1      1
      5 2020-06-05    52     2      2
      

      【讨论】:

      • 这太完美了……你是明星!!!拯救了我的一天......谢谢堆!天哪,我需要对 purrr 库进行培训。
      • 当多天由于某种原因有多个读数时,此解决方案会失效:(即 2020-06-03 的三行和 2020-06-05 的两行。
      【解决方案3】:

      也许你可以试试下面的代码

      with(
        consumption,
        apply(
          expand.grid(
            split(seq_along(date), date)
          ),
          1,
          function(k) consumption[k, ]
        )
      )
      

      给了

      [[1]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    31     3      1
      4 2020-06-04    40     1      1
      5 2020-06-05    51     2      1
      
      [[2]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    32     3      2
      4 2020-06-04    40     1      1
      5 2020-06-05    51     2      1
      
      [[3]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    33     3      3
      4 2020-06-04    40     1      1
      5 2020-06-05    51     2      1
      
      [[4]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    31     3      1
      4 2020-06-04    40     1      1
      5 2020-06-05    52     2      2
      
      [[5]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    32     3      2
      4 2020-06-04    40     1      1
      5 2020-06-05    52     2      2
      
      [[6]]
      # A tibble: 5 x 4
        date         val     n record
        <date>     <dbl> <int>  <int>
      1 2020-06-01    10     1      1
      2 2020-06-02    20     1      1
      3 2020-06-03    33     3      3
      4 2020-06-04    40     1      1
      5 2020-06-05    52     2      2
      

      【讨论】:

      • 这是一个很好的解决方案。我真的希望可以选择将赏金授予多个人。
      • 别担心,我的朋友。我很高兴你的问题得到了解决。 @M.Qasim
      猜你喜欢
      • 2021-06-05
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-20
      相关资源
      最近更新 更多