我会尝试通过提取样本数据来解释我的问题
ID Region Start_Date End_Date
1 Reg1 27/1/2017 27/1/2017
2 Reg1 27/2/2017 05/3/2017
1 Reg1 24/3/2017 25/5/2017
现在我希望结果是这样的:
ID Region n_Start_Date n_End_Date
1 Reg1 27/1/2017 27/1/2017
2 Reg2 27/2/2017 28/2/2017
2 Reg2 01/3/2017 05/3/2017
1 Reg1 24/3/2017 31/3/2017
1 Reg1 01/4/2017 30/4/2017
1 Reg1 01/5/2017 31/5/2017
我正在考虑实施的当前方法:
我创建了一个数据框,其中有14条记录,每个月的开始日期和结束日期分别为2017年和2018年:
Year Month Start of Month End of Month
2017 1 1/1/2017 31/1/2017
2017 2 1/2/2017 28/2/2017
2017 3 1/3/2017 31/3/2017
2017 4 1/4/2017 30/4/2017
2017 5 1/5/2017 31/5/2017
2017 6 1/6/2017 30/6/2017
2017 7 1/7/2017 31/7/2017
2017 8 1/8/2017 31/8/2017
2017 9 1/9/2017 30/9/2017
2017 10 1/10/2017 31/10/2017
2017 11 1/11/2017 30/11/2017
2017 12 1/12/2017 31/12/2017
2018 1 2/12/2017 31/1/2018
2018 2 3/12/2017 28/2/2018
我已经为年和月制作了一个新专栏:
如果开始日期年份,月份与结束日期年份,月份相同,则下一个相同的开始日期和结束日期将复制到新数据框,如
ID Region Start_Date End_Date n_Start_Date n_End_Date
1 Reg1 27/1/2017 27/1/2017 27/1/2017 27/1/2017
如果开始日期年份,月份不相同,则会附加
ID Region Start_Date End_Date n_Start_Date n_End_Date
2 Reg2 27/2/2017 05/3/2017 27/2/2017 28/2/2017
2 Reg2 27/2/2017 05/3/2017 01/3/2017 05/3/2017
我找不到任何类似的问题,我已经完成了link,但没有用。
如果有更好的方法,请告诉我。
答案 0 :(得分:1)
我想我已经理解了你想要的东西,如果你的结束日期不在同一年份和月份,那么你会产生一个新的行。 生成的行应该在该月的一天后开始,并在该月末结束。
# packages we need
library(tidyverse)
library(lubridate)
test_data <- tribble(
~ID, ~Region, ~Start_Date, ~End_Date,
1L, "Reg1", "27/1/2017", "27/1/2017",
2L, "Reg2", "27/2/2017", "05/3/2017",
1L, "Reg1", "24/3/2017", "25/5/2017"
) %>% mutate_at(vars(Start_Date, End_Date), dmy)
如果我们根据任何开始和结束制作一个功能,我们可以轻松地应用它。
expand_dates <- function(start, end) {
# the number of entries we want to add
to_add <- month(end) - month(start)
# Take the start date, roll it forwards until the month is equal to the end month
start_dates <- start + months(0:to_add)
# everything but the first start_date is rolled back to first of month
start_dates <- c(start_dates[1],
rollback(start_dates[-1], roll_to_first = T))
# end dates are just the start_dates rolled forwards to the end of the month
# apply to all but last, thats the end date
end_dates <- c(rollback(ceiling_date(start_dates[-length(start_dates)], unit = "months")), end)
data.frame(start_dates = start_dates,
end_dates = end_dates)
}
我们可以使用map2
中的purrr
,这使我们可以迭代开始日期和结束日期。使用mutate
我们已添加到列表中。列表列中的每个元素都是一个data.frame,它是从我们的新函数输出的。我们将使用unnest
将数据扩展到所需的数据。
test_data %>%
mutate(test = map2(Start_Date, End_Date, expand_dates)) %>%
unnest()
# A tibble: 6 x 6
ID Region Start_Date End_Date start_dates end_dates
<int> <chr> <date> <date> <date> <date>
1 1 Reg1 2017-01-27 2017-01-27 2017-01-27 2017-01-27
2 2 Reg2 2017-02-27 2017-03-05 2017-02-27 2017-02-28
3 2 Reg2 2017-02-27 2017-03-05 2017-03-01 2017-03-05
4 1 Reg1 2017-03-24 2017-05-25 2017-03-24 2017-03-31
5 1 Reg1 2017-03-24 2017-05-25 2017-04-01 2017-04-30
6 1 Reg1 2017-03-24 2017-05-25 2017-05-01 2017-05-25