【问题标题】:Convert list of effective dates to start and end dates将生效日期列表转换为开始日期和结束日期
【发布时间】:2020-01-20 21:33:49
【问题描述】:

我在 R 中有一个看起来像这样的数据框

EmployeeID Job Title    Effective Date
1          Sales1       1/1/2000
2          Sales1       3/1/2009
1          Sales2       5/2/2010
2          Management   6/1/2011

我想重新格式化为如下所示:

Employee    Job Title   Start Date  End Date
1           Sales1      1/1/2000    5/2/2010
1           Sales2      5/2/2010    
2           Sales1      3/1/2009    6/1/2011
2           Management  6/1/2011    

我的真实数据有更多的员工和头衔,但一致的是,不止一个人可以拥有相同的头衔。 我对使用 base r 或任何其他软件包的答案很好。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们可以通过EmployeeID和Start_date,group_byEmployeeID将日期列转换为实际日期arrange数据,并从Start_date中创建一个新列以获取lead值。

    library(dplyr)
    
    df %>%
      rename(Start_date = Effective_Date) %>%
      mutate(Start_date = as.Date(Start_date, "%d/%m/%Y")) %>%
      arrange(EmployeeID, Start_date) %>%
      group_by(EmployeeID) %>%
      mutate(End_date = lead(Start_date))
    
    #  EmployeeID Job_Title  Start_date End_date  
    #       <int> <fct>      <date>     <date>    
    #1          1 Sales1     2000-01-01 2010-02-05
    #2          1 Sales2     2010-02-05 NA        
    #3          2 Sales1     2009-01-03 2011-01-06
    #4          2 Management 2011-01-06 NA       
    

    数据

    df <- structure(list(EmployeeID = c(1L, 2L, 1L, 2L), Job_Title = structure(c(2L, 
    2L, 3L, 1L), .Label = c("Management", "Sales1", "Sales2"), class = "factor"), 
    Effective_Date = structure(1:4, .Label = c("1/1/2000", "3/1/2009", 
    "5/2/2010", "6/1/2011"), class = "factor")), class = "data.frame", 
    row.names = c(NA, -4L)) 
    

    【讨论】:

      【解决方案2】:

      使用来自dplyr的lead:

      library(dplyr)
       df %>%
         group_by(EmployeeID) %>%
         mutate(EndDate = ifelse(row_number() == 1, lead(as.character(EffectiveDate), 1), NA)) %>%
         arrange(EmployeeID)
      
      # A tibble: 4 x 4
       # Groups:   EmployeeID [2]
       #   EmployeeID JobTitle   EffectiveDate EndDate 
       #<int> <fct>      <fct>         <chr>   
       #1          1 Sales1     1/1/2000      5/2/2010
       #2          1 Sales2     5/2/2010      NA      
       #3          2 Sales1     3/1/2009      6/1/2011
       #4          2 Management 6/1/2011      NA   
      

      数据

       df <- structure(list(EmployeeID = c(1L, 2L, 1L, 2L), JobTitle = structure(c(2L,2L, 3L, 1L), .Label = c("Management", "Sales1", "Sales2"), class = "factor"), EffectiveDate = structure(1:4, .Label = c("1/1/2000", "3/1/2009","5/2/2010", "6/1/2011"), class = "factor")), class = "data.frame", row.names = c(NA, -4L))
      

      【讨论】:

        【解决方案3】:

        这是一个基本的 R 解决方案

        dfout <- do.call(rbind,
                c(make.row.names = F,
                  lapply(split(df,df$EmployeeID), function(v) cbind(v, End.Date = c(v[-1,3],NA)))))
        

        这样

        > dfout
          EmployeeID  Job.Title Effective.Date End.Date
        1          1     Sales1       1/1/2000 5/2/2010
        2          1     Sales2       5/2/2010     <NA>
        3          2     Sales1       3/1/2009 6/1/2011
        4          2 Management       6/1/2011     <NA>
        

        数据

        df <- structure(list(EmployeeID = c(1L, 2L, 1L, 2L), Job.Title = c("Sales1", 
        "Sales1", "Sales2", "Management"), Effective.Date = c("1/1/2000", 
        "3/1/2009", "5/2/2010", "6/1/2011")), class = "data.frame", row.names = c(NA, 
        -4L))
        

        【讨论】:

          猜你喜欢
          • 2017-10-10
          • 2023-03-17
          • 1970-01-01
          • 2020-10-05
          • 2022-01-23
          • 2012-08-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多