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

基于前一行中的值设置时间序列中的日期值

  •  0
  • marcel  · 技术社区  · 5 年前

    我有以下几点:

    df <- data.frame(A = c(1:8), ref.date = c(NA, "10/12/18", NA, NA, "12/15/19", NA, NA, NA))
    df$ref.date <- as.Date(df$ref.date, format = "%m/%d/%y")
    df$new.date <- NA
    

    A  ref.date new.date
    1     <NA>       NA
    2 10/12/18       10/12/18
    3     <NA>       10/12/18
    4     <NA>       10/12/18
    5 12/15/19       12/15/19
    6     <NA>       12/15/19
    7     <NA>       12/15/19
    8     <NA>       12/15/19
    

    我试过了

    library(dplyr)
    df <- df %>% mutate(new.date = ifelse(is.na(ref.date), lag(new.date), ref.date))
    df$new.date <- as.Date(df$new.date, format = "%m/%d/%y")
    

    但这产生了数字格式的日期,并且没有正确填充ref.date为NA的行。

    0 回复  |  直到 5 年前
        1
  •  0
  •   Ronak Shah    5 年前

    我们可以复制 ref.date 进入之内 new.date fill tidyr

    library(dplyr)
    df %>% mutate(new.date = ref.date) %>% tidyr::fill(new.date)
    
    #  A   ref.date   new.date
    #1 1       <NA>       <NA>
    #2 2 2018-10-12 2018-10-12
    #3 3       <NA> 2018-10-12
    #4 4       <NA> 2018-10-12
    #5 5 2019-12-15 2019-12-15
    #6 6       <NA> 2019-12-15
    #7 7       <NA> 2019-12-15
    #8 8       <NA> 2019-12-15
    
        2
  •  3
  •   cimentadaj    5 年前

    我认为应该这样做:

    df <- data.frame(A = c(1:8), ref.date = c(NA, "10/12/18", NA, NA, "12/15/19", NA, NA, NA))
    df$ref.date <- as.Date(df$ref.date, format = "%m/%d/%y")
    df$new.date <- NA
    
    library(dplyr)
    #> 
    #> Attaching package: 'dplyr'
    #> The following objects are masked from 'package:stats':
    #> 
    #>     filter, lag
    #> The following objects are masked from 'package:base':
    #> 
    #>     intersect, setdiff, setequal, union
    library(tidyr)
    
    df %>%
      mutate(new.date = ref.date) %>% 
      fill(`new.date`, .direction = "down")
    #>   A   ref.date   new.date
    #> 1 1       <NA>       <NA>
    #> 2 2 2018-10-12 2018-10-12
    #> 3 3       <NA> 2018-10-12
    #> 4 4       <NA> 2018-10-12
    #> 5 5 2019-12-15 2019-12-15
    #> 6 6       <NA> 2019-12-15
    #> 7 7       <NA> 2019-12-15
    #> 8 8       <NA> 2019-12-15
    
        3
  •  0
  •   ThomasIsCoding    5 年前

    下面是一些基本的解决方案。

    • 使用 rle() + cumsum()
    df$new.date <- with(rle(cumsum(!is.na(df$ref.date))),
                        rep(df$ref.date[c(0,cumsum(lengths[-length(lengths)]))+1],lengths))
    
    • 使用 split() + rbind() :
    df <- do.call(rbind,
                  c(make.row.names = F,
                    lapply(split(df,cumsum(!is.na(df$ref.date))), 
                           function(v) cbind(v,new.date = head(v$ref.date,1)))))
    

    以至于

    > df
      A   ref.date   new.date
    1 1       <NA>       <NA>
    2 2 2018-10-12 2018-10-12
    3 3       <NA> 2018-10-12
    4 4       <NA> 2018-10-12
    5 5 2019-12-15 2019-12-15
    6 6       <NA> 2019-12-15
    7 7       <NA> 2019-12-15
    8 8       <NA> 2019-12-15