【问题标题】:Reshape dataframe in R, different dates在 R 中重塑数据框,不同的日期
【发布时间】:2021-07-07 15:47:15
【问题描述】:

我的数据如下所示:

ID Name Role Status Date
1 John GM Current 12.04.2021
1 Ann GM Previous 10.07.2020
1 Mary GM Previous 24.01.2017
2 Ann GM Current 12.04.2021
2 Josef GM Previous 02.07.2015
3 Sophie GM Current 12.04.2021
4 Ben GM Current 12.04.2021
4 Lucas GM Previous 30.07.2018
4 Peter GM Previous 18.04.2017
4 Susan GM Previous 16.09.2015

每个“企业”的 ID 都是唯一的。首先,我希望每个 ID 有 1 行,然后每个日期需要生成一个新列。每个 ID 中的第一个日期必须在“Date1”,第二个“Date2”等。值得一提的是,我的数据集可以为每个 ID 采用不同数量的行。

我将使用此分析来查看每个业务的总经理 (GM) 的变化,因此只对 ID 和日期感兴趣。

我的最终数据集如下表所示:

ID Date1 Date2 Date3 Date4
1 12.04.2021 10.07.2020 24.01.2017 NA
2 12.04.2021 02.07.2015 NA NA
3 12.04.2021 NA NA NA
4 12.04.2021 30.07.2018 18.04.2017 16.09.2015

我曾尝试在 R studio 中搜索以前使用 reshape 的案例,但没有找到与我相似的案例。有人能帮我吗?非常感谢!

【问题讨论】:

  • 欢迎来到 Stack Overflow。请将您的示例数据作为对象粘贴到问题中:使用 `doput(your_dataframe) 这将使问题可重现并允许测试解决方案。此链接可能对minimal reproducible example 有所帮助

标签: r date reshape transpose


【解决方案1】:

这是一个 tidyverse 解决方案:

library(tidyverse)

df <- data.frame(
  ID = c(1, 1, 1, 2, 2),
  Name = c("John", "Ann", "Mary", "Ann", "Joseph"),
  Role = rep("GM", 5),
  Status = c("Current", "Previous", "Previous", "Current", "Previous"),
  Date = c("12.04.2021", "10.07.2020", "24.01.2017", "12.04.2021", "02.07.2015")
)

df

  ID   Name Role   Status       Date
1  1   John   GM  Current 12.04.2021
2  1    Ann   GM Previous 10.07.2020
3  1   Mary   GM Previous 24.01.2017
4  2    Ann   GM  Current 12.04.2021
5  2 Joseph   GM Previous 02.07.2015


dfnew <- df %>% 
  dplyr::group_by(ID) %>% 
  dplyr::mutate(rownum = row_number()) %>% 
  dplyr::select(ID, rownum, Date) %>% 
  tidyr::pivot_wider(names_from = rownum, values_from = Date, names_glue = "Date{rownum}")

dfnew

# A tibble: 2 x 4
# Groups:   ID [2]
     ID Date1      Date2      Date3     
  <dbl> <chr>      <chr>      <chr>     
1     1 12.04.2021 10.07.2020 24.01.2017
2     2 12.04.2021 02.07.2015 NA   

【讨论】:

    【解决方案2】:

    这是data.table 方法

    library(data.table)
    
    DT <- fread("ID     Name    Role    Status  Date
    1   John    GM  Current     12.04.2021
    1   Ann     GM  Previous    10.07.2020
    1   Mary    GM  Previous    24.01.2017
    2   Ann     GM  Current     12.04.2021
    2   Josef   GM  Previous    02.07.2015
    3   Sophie  GM  Current     12.04.2021
    4   Ben     GM  Current     12.04.2021
    4   Lucas   GM  Previous    30.07.2018
    4   Peter   GM  Previous    18.04.2017
    4   Susan   GM  Previous    16.09.2015")
    
    # summarise dates by id
    ans <- DT[, .(dates = paste0(Date, collapse = "#")), by = ID]
    # now split
    ans[, paste0("Date", 1:length(tstrsplit(ans$dates, "#"))) := 
          tstrsplit( dates, "#")][, dates := NULL][]
    
    #    ID      Date1      Date2      Date3      Date4
    # 1:  1 12.04.2021 10.07.2020 24.01.2017       <NA>
    # 2:  2 12.04.2021 02.07.2015       <NA>       <NA>
    # 3:  3 12.04.2021       <NA>       <NA>       <NA>
    # 4:  4 12.04.2021 30.07.2018 18.04.2017 16.09.2015
    

    【讨论】:

    • 谢谢你,@Wimpel!这就是我要的。可以在数据框中执行此操作。或者,从数据框更改为数据表?
    • setDT() 将 data.frame 更改为 data.table。 setDF() 反之亦然。
    猜你喜欢
    • 1970-01-01
    • 2017-02-11
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    相关资源
    最近更新 更多