【问题标题】:Create a new list of data frames from an existing list of data frames从现有数据框列表创建新的数据框列表
【发布时间】:2021-06-10 12:43:54
【问题描述】:
d1 <- data.frame(id = c("a", "b", "c"), val = c(111, 444, 777), month = c( "jan", "Jan" , "jan" ))
d2 <- data.frame(id = c("a", "b", "c"), val = c(222, 555, 888), month = c( "feb", "feb" , "feb" ))
d3 <- data.frame(id = c("a", "b", "c"), val = c(333, 666, 999), month = c( "mar", "mar" , "mar" ))

old.list <- list(d1, d2, d3)


s1 <- data.frame(id = c("a", "a", "a"), val = c(111, 222, 333), month = c( "jan", "feb" , "mar" ))
s2 <- data.frame(id = c("b", "b", "b"), val = c(444, 555, 666), month = c( "Jan", "feb" , "mar" ))
s3 <- data.frame(id = c("c", "c", "c"), val = c(777, 888, 999), month = c( "Jan", "feb" , "mar" ))

new.list <- list(s1, s2, s3)

“old.list”中的所有数据框都具有相同的大小和相同的唯一 ID。我正在尝试将“old.list”转换为每个唯一 ID 的时间序列,其中“月”是时间戳,即“new.list”,而不使用 for 循环。

补充说明,'old.list'中每个数据框的第n行组合起来为'new.list'创建新的数据框,提前致谢。

【问题讨论】:

    标签: r list dataframe reshape


    【解决方案1】:

    这是tidyverse 方法:

    d1 <- data.frame(id = c("a", "b", "c"), val = c(111, 444, 777), month = c( "jan", "Jan" , "jan" ))
    d2 <- data.frame(id = c("a", "b", "c"), val = c(222, 555, 888), month = c( "feb", "feb" , "feb" ))
    d3 <- data.frame(id = c("a", "b", "c"), val = c(333, 666, 999), month = c( "mar", "mar" , "mar" ))
    
    old.list <- list(d1, d2, d3)
    
    library(dplyr)
    library(purrr)
    
    old.list %>% 
      reduce(rbind, by = 'id') %>% 
      filter(id != 'id') %>% 
      group_split(id)
    
    
    #> [[1]]
    #> # A tibble: 3 x 3
    #>   id    val   month
    #>   <chr> <chr> <chr>
    #> 1 a     111   jan  
    #> 2 a     222   feb  
    #> 3 a     333   mar  
    #> 
    #> [[2]]
    #> # A tibble: 3 x 3
    #>   id    val   month
    #>   <chr> <chr> <chr>
    #> 1 b     444   Jan  
    #> 2 b     555   feb  
    #> 3 b     666   mar  
    #> 
    #> [[3]]
    #> # A tibble: 3 x 3
    #>   id    val   month
    #>   <chr> <chr> <chr>
    #> 1 c     777   jan  
    #> 2 c     888   feb  
    #> 3 c     999   mar
    

    reprex package (v0.3.0) 于 2021-03-12 创建

    【讨论】:

      【解决方案2】:

      假设您的所有系列都在 1 月开始,这应该可以:

      (如果不查看 ts 的起始参数)

      d1 <- data.frame(id = c("a", "b", "c"), val = c(111, 444, 777), month = c( "jan", "Jan" , "jan" ))
      d2 <- data.frame(id = c("a", "b", "c"), val = c(222, 555, 888), month = c( "feb", "feb" , "feb" ))
      d3 <- data.frame(id = c("a", "b", "c"), val = c(333, 666, 999), month = c( "mar", "mar" , "mar" ))
      
      old.list <- list(d1, d2, d3)
      
      d <- Reduce(rbind,old.list)
      d <- split(d$val, d$id)
      
      lapply(d, ts, frequency = 12)
      #> $a
      #>   Jan Feb Mar
      #> 1 111 222 333
      #> 
      #> $b
      #>   Jan Feb Mar
      #> 1 444 555 666
      #> 
      #> $c
      #>   Jan Feb Mar
      #> 1 777 888 999
      

      reprex package (v0.3.0) 于 2021-03-12 创建

      【讨论】:

      • Aksel Thomsen,谢谢它完美的工作。
      • @DAL - 如果该解决方案适合您,也许您可​​以考虑支持新成员解决方案,即使它不是公认的解决方案。
      • 我尝试为他们投票,但它不会让我,因为我的代表少于 15 次,所有解决方案都有效并受到赞赏。
      【解决方案3】:

      在基础 R 中,您可以 rbind 您的列表元素和 split 通过 id:

      new.list <- do.call(rbind, old.list)
      new.list <- split(new.list, new.list$id)
      

      【讨论】:

      • 完美,谢谢。
      猜你喜欢
      • 1970-01-01
      • 2015-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-29
      • 2020-09-19
      • 2016-02-29
      相关资源
      最近更新 更多