Is there any alternative way to replace the following codes under dplyr to avoid explicit loop and data name to achieve the following?
This is to create an adjusted date, if the condition of the current supp_date less than the previous supp_date + tablet is met.
Sample data: (This is the new sample data with else
case in it.)
test <- read.table(text =
"supp_date tablet
2017-07-19 30
2017-08-07 30
2017-09-08 30
2017-10-30 30
2017-11-08 30
2017-12-07 30", header = T)
R code:
test$supp_date <- as.Date(test$supp_date, "%Y-%m-%d")
test$adj_fill_dt <- as.Date(NA, "%Y-%m-%d")
test$adj_fill_dt[1] <- test$supp_date[1]
for(i in 2:6) {
if (test[i, "supp_date"] < test[i-1, "adj_fill_dt"] + test[i-1, "tablet"]) {
test[i, "adj_fill_dt"] <- test[i-1, "adj_fill_dt"] + test[i-1, "tablet"]
} else {
test[i, "adj_fill_dt"] <- test[i, "supp_date"]
}
}
From:
supp_date tablet
2017-07-19 30
2017-08-07 30
2017-09-08 30
2017-10-30 30
2017-11-08 30
2017-12-07 30
To:
supp_date tablet adj_fill_dt
2017-07-19 30 2017-07-19
2017-08-07 30 2017-08-18
2017-09-08 30 2017-09-17
2017-10-30 30 2017-10-30
2017-11-08 30 2017-11-29
2017-12-07 30 2017-12-29
We can do this recursively with accumulate
library(tidyverse)
df %>%
mutate(tmp = as.numeric(supp_date),
adj_fill_dt = as.Date(accumulate(tmp[-1], ~
pmax(.x + tablet[1], .y), .init = tmp[1]),
origin = '1970-01-01'),
tmp = NULL)
# supp_date tablet adj_fill_dt
#1 2017-07-19 30 2017-07-19
#2 2017-08-07 30 2017-08-18
#3 2017-09-08 30 2017-09-17
#4 2017-10-30 30 2017-10-30
#5 2017-11-08 30 2017-11-29
#6 2017-12-07 30 2017-12-29
Or with base R
using Reduce
v1 <- as.numeric(df$supp_date)
as.Date(Reduce(function(u, v) pmax(u + 30, v), v1[-1],
init = v1[1], accumulate = TRUE), origin = '1970-01-01')
#[1] "2017-07-19" "2017-08-18" "2017-09-17" "2017-10-30" "2017-11-29"
#[6] "2017-12-29"
df <- structure(list(supp_date = structure(c(17366, 17385, 17417, 17469,
17478, 17507), class = "Date"), tablet = c(30L, 30L, 30L, 30L,
30L, 30L)), .Names = c("supp_date", "tablet"), row.names = c(NA,
-6L), class = "data.frame")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With