【问题标题】:Fill dates column with next date from previous date in row用行中上一个日期的下一个日期填充日期列
【发布时间】:2020-01-12 00:56:46
【问题描述】:

我必须在数据框中填写日期列,将最后一天添加到最后日期,然后添加到末尾(添加一天)。它没有填补缺失的日期,因为从最后一个日期开始没有更多的日期,所以没有间隔。

还有更多列,但为了示例,让我们保持简单。

df <- structure(list(dates = c("1991-01-01", "1991-01-02", "1991-01-03", 
NA, NA, NA)), row.names = c(NA, 6L), class = c("tbl_df", "tbl", 
"data.frame"))

# A tibble: 6 x 1
  dates     
* <chr>     
1 1991-01-01
2 1991-01-02
3 1991-01-03
4 NA        
5 NA        
6 NA 

我知道我可以用序列 (seq.Date) 代替它来填充它,但我想前段时间我在某处读到了一个优雅的函数,用于使用最后日期和滞后来填充向量。

预期结果:

# A tibble: 6 x 1
  dates     
* <chr>     
1 1991-01-01
2 1991-01-02
3 1991-01-03
4 1991-01-04   
5 1991-01-05        
6 1991-01-06   

类似于zoo::na.locf(),但考虑到日期,我事先不知道“从”和“到”

有什么提示吗?

【问题讨论】:

    标签: r date dataframe dplyr zoo


    【解决方案1】:

    另一个dplyrtidyr 可能是:

    df %>%
     mutate(dates = as.Date(dates, format = "%Y-%m-%d")) %>%
     fill(dates) %>%
     mutate(dates = if_else(duplicated(dates), 
                            dates + cumsum(duplicated(dates)), 
                            dates))
    
      dates     
      <date>    
    1 1991-01-01
    2 1991-01-02
    3 1991-01-03
    4 1991-01-04
    5 1991-01-05
    6 1991-01-06
    

    或者只涉及dplyr的可能性:

    df %>%
     mutate(dates = as.Date(dates, format = "%Y-%m-%d"),
            dates = if_else(is.na(dates),
                            last(na.omit(dates)) + cumsum(is.na(dates)),
                            dates))
    

    【讨论】:

      【解决方案2】:

      我们可以尝试将fill 缺失的日期与之前的值相加,然后将cumsumNA 值添加到其中。

      library(dplyr)
      
      df %>%
        mutate(temp = +(is.na(dates)), 
              dates = as.Date(dates)) %>% 
        tidyr::fill(dates) %>%
        mutate(dates_new = dates + cumsum(temp)) %>%
        select(-temp)
      
      #   dates      dates_new 
      #  <date>     <date>    
      #1 1991-01-01 1991-01-01
      #2 1991-01-02 1991-01-02
      #3 1991-01-03 1991-01-03
      #4 1991-01-03 1991-01-04
      #5 1991-01-03 1991-01-05
      #6 1991-01-03 1991-01-06
      

      【讨论】:

        【解决方案3】:

        这是一个基本的 R 想法,

        as.Date(max(df$dates, na.rm = TRUE)) + seq(sum(is.na(df$dates)))
        #[1] "1991-01-04" "1991-01-05" "1991-01-06"
        

        或将它们分配回您的数据框,即

        df$dates[is.na(df$dates)] <- as.character(as.Date(max(df$dates, na.rm = TRUE)) + seq(sum(is.na(df$dates))))
        
        df
        #1 1991-01-01
        #2 1991-01-02
        #3 1991-01-03
        #4 1991-01-04
        #5 1991-01-05
        #6 1991-01-06
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-19
          • 2023-03-25
          • 2022-01-05
          • 2016-04-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多