首页 文章

如何有效地计算开始和结束日期的顺序?

提问于
浏览
1

我有以下起点:

#dataset:
schedule <- tibble(start = as.Date(c("2018-07-11", NA, NA)), duration = c(10,23,9),flag_StartActual = c(TRUE,FALSE,FALSE))

以表格形式:

> schedule
# A tibble: 3 x 3
  start      duration flag_StartActual
  <date>        <dbl> <lgl>           
1 2018-07-11       10 TRUE            
2 NA               23 FALSE           
3 NA                9 FALSE

我想计算 end (=开始持续时间) . 一旦第一行完成,我想让第一行的 end 成为第二行的 start .

我已经尝试了各种方法,但到目前为止我还没有成功 . 我考虑的事情是:

  • 使用滞后(结束)功能从上一行获取 end . 这适用于第二行,但对于以下所有行, end 尚不存在 .

  • 我已经尝试了 rowwise() 但是在这种情况下我没有让 lag() 功能起作用 .

下面的代码或多或少地做了我想要它做的事情,但这不是很整洁,因为需要为每一行添加一个mutate(然后重新计算所有前面的行) .

> schedule %>%
+   mutate(
+     end = start + ddays(duration),
+     start = as_datetime(ifelse(flag_StartActual==TRUE,start,lag(end)))
+   )  %>%
+   mutate(
+     end = start + ddays(duration),
+     start = as_datetime(ifelse(flag_StartActual==TRUE,start,lag(end)))
+   )
# A tibble: 3 x 4
  start               duration flag_StartActual end                
  <dttm>                 <dbl> <lgl>            <dttm>             
1 2018-07-11 00:00:00       10 TRUE             2018-07-21 00:00:00
2 2018-07-21 00:00:00       23 FALSE            2018-08-13 00:00:00
3 2018-08-13 00:00:00        9 FALSE            NA

在下面的代码中包含 rowwise() 不起作用:

schedule %>%
  rowwise() %>%
  mutate(
    end = start + ddays(duration),
    start = as_datetime(ifelse(flag_StartActual==TRUE,start,lag(end)))
  )

无论如何,我有点卡住,希望有人对如何处理这个有一些明智的想法?

3 回答

  • 3
    library(dplyr)
    
    schedule %>% 
      mutate(start = start[1] + lag(cumsum(duration), default = 0)
             , end = start + duration)
    
    # # A tibble: 3 x 4
    #   start      duration flag_StartActual end       
    #   <date>        <dbl> <lgl>            <date>    
    # 1 2018-07-11    10.0  T                2018-07-21
    # 2 2018-07-21    23.0  F                2018-08-13
    # 3 2018-08-13     9.00 F                2018-08-22
    
  • 1

    循环它:

    for (i in 2:nrow(schedule)) 
        schedule$start[i]<-schedule$start[i-1]+schedule$duration[i-1] 
    schedule$end<-schedule$start+schedule$duration
    schedule
    
    # A tibble: 3 × 4
           start duration flag_StartActual        end
          <date>    <dbl>            <lgl>     <date>
    1 2018-07-11       10             TRUE 2018-07-21
    2 2018-07-21       23            FALSE 2018-08-13
    3 2018-08-13        9            FALSE 2018-08-22
    

    注意我在计算所有开始后创建了 end 列,我认为它更容易一些 .

  • 1
    schedule %>%
       mutate(
         start = schedule$start[1] + ddays(c(0, cumsum(schedule$duration)[- n()])),
         end = schedule$start[1] + ddays(cumsum(schedule$duration))
       )
    
    # A tibble: 3 x 4
      start      duration flag_StartActual end       
      <date>        <dbl> <lgl>            <date>    
    1 2018-07-11       10 TRUE             2018-07-21
    2 2018-07-21       23 FALSE            2018-08-13
    3 2018-08-13        9 FALSE            2018-08-22
    

相关问题