I think this is what you want
library(tidyverse)
library(lubridate)
df <- data.frame(stringsAsFactors=FALSE,
transaction_id = c("1", "2"),
trade_date = as.Date(c("2019-07-01", "2019-08-01")),
start = as.Date(c("2019-08-01", "2019-12-01")),
end = as.Date(c("2019-10-31", "2020-02-28")),
price = c(5, 6),
currency = c("CAD", "CAD"),
volume = c(10000, 5000)
)
# Sample data
df
#> transaction_id trade_date start end price currency volume
#> 1 1 2019-07-01 2019-08-01 2019-10-31 5 CAD 10000
#> 2 2 2019-08-01 2019-12-01 2020-02-28 6 CAD 5000
# Desired output
df %>%
group_by(transaction_id) %>%
mutate(start=list(seq(start, end, "months"))) %>%
unnest_longer(c(start)) %>%
mutate(end = ceiling_date(start, "month") - 1)
#> # A tibble: 6 x 7
#> # Groups: transaction_id [2]
#> transaction_id trade_date start end price currency volume
#> <chr> <date> <date> <date> <dbl> <chr> <dbl>
#> 1 1 2019-07-01 2019-08-01 2019-08-31 5 CAD 10000
#> 2 1 2019-07-01 2019-09-01 2019-09-30 5 CAD 10000
#> 3 1 2019-07-01 2019-10-01 2019-10-31 5 CAD 10000
#> 4 2 2019-08-01 2019-12-01 2019-12-31 6 CAD 5000
#> 5 2 2019-08-01 2020-01-01 2020-01-31 6 CAD 5000
#> 6 2 2019-08-01 2020-02-01 2020-02-29 6 CAD 5000
Created on 2019-09-24 by the reprex package (v0.3.0.9000)