代码之家  ›  专栏  ›  技术社区  ›  James Rider

时间序列长宽格式R?

  •  0
  • James Rider  · 技术社区  · 2 年前

    在R中,我有一个时间序列 ts_big 以如下所示的长格式,带有类型A和类型B的观测结果:

    ts1<-tibble(dates=c("2023-01-01","2023-02-01","2023-03-01",
                        "2023-04-01"), 
                numbers_1=c(1.0, 2.8, 2.9, 2.0), 
                numbers_2=c(3.0, 5.0, 7.9, 0.9),
                types=replicate(4, "A"))
    
    ts2<-tibble(dates=c("2023-01-01","2023-02-01"), 
                numbers_1=c(0.3, 0.9),
                numbers_2=c(3.0, 5.0),
                types=replicate(2, "B"))
    
    ts_big<-rbind(ts1, ts2)
    

    A型有4次观测结果(“2023-01-01”、“2023-02-01”和“2023-03-01”),而B型只有2次观测结果。有没有办法改变这个tibble ts_big 变成 宽格式 具有5列: 一个单独的日期列 一列用于 A类编号_1 ,一列用于 A类编号_2 ,和一列用于 B类编号_1 ,和一列用于 B类编号_2 (可能在类型B没有给定日期的观测值的行中使用NA值)?

    我知道这可以通过创建一堆向量,然后将它们编译成tibble/dataframe来手动完成,但我想知道是否有一个函数或简单的过程可以用于比我在这里提供的小规模示例更大/更复杂的示例。

    注:这是我之前一篇措辞不当的帖子的转发版本。

    3 回复  |  直到 2 年前
        1
  •  1
  •   r2evans    2 年前

    双枢轴:

    library(dplyr) # mostly just for %>%, though it's very useful with tidyr
    library(tidyr)
    ts_big %>%
      pivot_longer(cols = -c(dates, types)) %>%
      pivot_wider(id_cols = dates, names_from = c(types, name), values_from = value)
    # # A tibble: 4 × 5
    #   dates      A_numbers_1 A_numbers_2 B_numbers_1 B_numbers_2
    #   <chr>            <dbl>       <dbl>       <dbl>       <dbl>
    # 1 2023-01-01         1           3           0.3           3
    # 2 2023-02-01         2.8         5           0.9           5
    # 3 2023-03-01         2.9         7.9        NA            NA
    # 4 2023-04-01         2           0.9        NA            NA
    
        2
  •  1
  •   Dave2e    2 年前

    这是另一个不需要更长时间枢轴转动的选项:

    library(tidyr)
    pivot_wider(ts_big, values_from = starts_with("numbers"), 
                names_from = "types", 
                names_glue = "{types}_{.value}" )
    
    
    # A tibble: 4 × 5
      dates      A_numbers_1 B_numbers_1 A_numbers_2 B_numbers_2
      <chr>            <dbl>       <dbl>       <dbl>       <dbl>
    1 2023-01-01         1           0.3         3             3
    2 2023-02-01         2.8         0.9         5             5
    3 2023-03-01         2.9        NA           7.9          NA
    4 2023-04-01         2          NA           0.9          NA
    
        3
  •  1
  •   G. Grothendieck    2 年前

    read.zoo split= 论证可以做到这一点。这个 fortify.zoo 行将zoo输出转换为data.frame,如果结果是zoo对象,则可以省略该行。这个 setNames 行是为了使列名更好一点,如果表单的名称 numbers_1.A 都还好。

    library(dplyr, exclude = c("filter", "lag"))
    library(zoo)
    
    ts_big %>%
      read.zoo(split = "types") %>%
      fortify.zoo(name = "date") %>%
      setNames(sub("numbers_(.*)\\.(.*)", "\\2_\\1", names(.)))
    ##         date A_1 A_2 B_1 B_2
    ## 1 2023-01-01 1.0 3.0 0.3   3
    ## 2 2023-02-01 2.8 5.0 0.9   5
    ## 3 2023-03-01 2.9 7.9  NA  NA
    ## 4 2023-04-01 2.0 0.9  NA  NA