代码之家  ›  专栏  ›  技术社区  ›  cdeterman

R中以前的日期

r
  •  0
  • cdeterman  · 技术社区  · 8 年前

    structure(list(a = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("a", 
    "b"), class = "factor"), dt = structure(c(NA, 17287, 17318, NA, 
    17379, 17410), class = "Date")), .Names = c("a", "dt"), row.names = c(NA, 
    -6L), class = "data.frame")
    

      a         dt
    1 a       <NA>
    2 a 2017-05-01
    3 a 2017-06-01
    4 b       <NA>
    5 b 2017-08-01
    6 b 2017-09-01
    

    在我的实际数据中,这种情况发生过多次。如何用上个月的开始日期进行回填。

    理想情况下,我想用 dplyr . 我能找到的最接近的就是 lubridate::floor_date 和 dplyr::lead 这就使得最后一次约会 NA .

    tmp %>%
      group_by(a) %>%
      mutate(dt = floor_date(lead(dt, 1) - 1, "month"))
    
    # A tibble: 6 x 2
    # Groups:   a [2]
      a     dt        
      <fct> <date>    
    1 a     2017-04-01
    2 a     2017-05-01
    3 a     NA        
    4 b     2017-07-01
    5 b     2017-08-01
    6 b     NA 
    

    如有任何想法,我们将不胜感激。

    2 回复  |  直到 8 年前
        1
  •  0
  •   mmyoung77    8 年前

    lubridate 除了 dplyr :

    tmp <- structure(list(a = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("a", "b"), class = "factor"), 
                          dt = structure(c(NA, 17287, 17318, NA, 17379, 17410), class = "Date")),
                     .Names = c("a", "dt"), 
                     row.names = c(NA, -6L), 
                     class = "data.frame")
    
    library(lubridate)
    library(dplyr)
    
    tmp %>%
      group_by(a) %>%
      mutate(newDT = if_else(is.na(dt), lead(dt) %m-% months(1), dt))
    tmp
    
    # A tibble: 6 x 3
    # Groups:   a [2]
      a     dt         newDT     
      <fct> <date>     <date>    
    1 a     NA         2017-04-01
    2 a     2017-05-01 2017-05-01
    3 a     2017-06-01 2017-06-01
    4 b     NA         2017-07-01
    5 b     2017-08-01 2017-08-01
    6 b     2017-09-01 2017-09-01
    

    newDT 变成你想要的格式。(编辑:感谢@phiver更正了我的代码!)

        2
  •  0
  •   zack    8 年前

    我认为,目前接受的解决方案将无法工作,如果有超过1个相邻的 NA 的值 dt .

    另一种选择是,注意顺序很重要:

    解决方案

    dat
    
      a         dt
    1 a       <NA>
    2 a       <NA>
    3 a 2017-05-01
    4 a 2017-06-01
    5 b       <NA>
    6 b 2017-08-01
    7 b 2017-09-01
    
    library(dplyr)
    library(tidyr)
    
    dat %>%
      group_by(a) %>%
      mutate(helper = ifelse(is.na(dt), NA, cumsum(!is.na(dt)))) %>%
      fill(helper, .direction = 'up') %>%
      group_by(a, helper) %>%
      mutate(dt = coalesce(dt,
                           max(dt, na.rm = TRUE) - months(max(row_number()) - row_number()))) %>%
      dplyr::select(-helper)
    
    # A tibble: 7 x 3
    # Groups:   a, helper [4]
      helper a     dt        
       <int> <fct> <date>    
    1      1 a     2017-03-01
    2      1 a     2017-04-01
    3      1 a     2017-05-01
    4      2 a     2017-06-01
    5      1 b     2017-07-01
    6      1 b     2017-08-01
    7      2 b     2017-09-01
    

    数据

    dat <-structure(list(a = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L), .Label = c("a", 
    "b"), class = "factor"), dt = structure(c(NA, NA, 17287, 17318, 
    NA, 17379, 17410), class = "Date")), .Names = c("a", "dt"), row.names = c(NA, 
    -7L), class = "data.frame")