如何在 tibble 中有效地计算开始日期和结束日期的顺序?
How to calculate the sequence of start and end dates efficiently in a tibble?
我有以下出发点:
#dataset:
schedule <- tibble(start = as.Date(c("2018-07-11", NA, NA)), duration = c(10,23,9),flag_StartActual = c(TRUE,FALSE,FALSE))
table格式:
> 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
。
我尝试过各种方法,但到目前为止我还没有成功。我考虑的事情是:
- 使用 lag(end) 函数从上一行获取
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)))
)
无论如何,我有点卡住了,希望有人对如何解决这个问题有一些聪明的想法?
循环播放:
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
列,我认为它更容易一些。
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
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
我有以下出发点:
#dataset:
schedule <- tibble(start = as.Date(c("2018-07-11", NA, NA)), duration = c(10,23,9),flag_StartActual = c(TRUE,FALSE,FALSE))
table格式:
> 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
。
我尝试过各种方法,但到目前为止我还没有成功。我考虑的事情是:
- 使用 lag(end) 函数从上一行获取
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)))
)
无论如何,我有点卡住了,希望有人对如何解决这个问题有一些聪明的想法?
循环播放:
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
列,我认为它更容易一些。
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
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