【问题标题】:Split a rows into two when a date range spans a change in calendar year当日期范围跨越日历年的更改时,将行拆分为两行
【发布时间】:2020-05-16 07:15:20
【问题描述】:

我想弄清楚当日期范围跨越一个日历年时如何添加一行。下面是一个最小的代表:

我有一个这样的日期框架:

have <- data.frame(
  from = c(as.Date('2018-12-15'), as.Date('2019-12-20'), as.Date('2019-05-13')), 
  to = c(as.Date('2019-06-20'), as.Date('2020-01-25'), as.Date('2019-09-10'))
)
have
#>         from         to
#> 1 2018-12-15 2019-06-20
#> 2 2019-12-20 2020-01-25
#> 3 2019-05-13 2019-09-10

tofrom 跨越一个日历年时,我想要一个分成两行的data.frame。

want <- data.frame(
  from = c(as.Date('2018-12-15'), as.Date('2019-01-01'), as.Date('2019-12-20'), as.Date('2020-01-01'), as.Date('2019-05-13')), 
  to = c(as.Date('2018-12-31'), as.Date('2019-06-20'), as.Date('2019-12-31'), as.Date('2020-01-25'), as.Date('2019-09-10'))
)
want
#>         from         to
#> 1 2018-12-15 2018-12-31
#> 2 2019-01-01 2019-06-20
#> 3 2019-12-20 2019-12-31
#> 4 2020-01-01 2020-01-25
#> 5 2019-05-13 2019-09-10

我想这样做是因为对于特定的行,我想知道每年有多少天。

want$time_diff_by_year <- difftime(want$to, want$from)

reprex package (v0.3.0) 于 2020-05-15 创建

非常感谢任何基本的 R、tidyverse 解决方案。

【问题讨论】:

  • 是真的
  • 我又添加了两行。这行得通吗?
  • 一行可能会跨越 两年 年,例如2018-05-132020-03-10?如果是这样,您是否想要显而易见的东西,即是否分成三行?

标签: r


【解决方案1】:

您可以使用map2 确定日期间隔所需的额外年份,然后使用unnest 为每一年创建额外的行。

然后,您可以确定部分年份和完整日历年之间的交叉日期间隔。这将保留给定年份从 1 月 1 日开始或 12 月 31 日结束的部分年份。

library(tidyverse)
library(lubridate)

have %>%
  mutate(date_int = interval(from, to),
         year = map2(year(from), year(to), seq)) %>%
  unnest(year) %>%
  mutate(year_int = interval(as.Date(paste0(year, '-01-01')), as.Date(paste0(year, '-12-31'))),
         year_sect = intersect(date_int, year_int),
         from_new = as.Date(int_start(year_sect)),
         to_new = as.Date(int_end(year_sect))) %>%
  select(from_new, to_new)

输出

# A tibble: 5 x 2
  from_new   to_new    
  <date>     <date>    
1 2018-12-15 2018-12-31
2 2019-01-01 2019-06-20
3 2019-12-20 2019-12-31
4 2020-01-01 2020-01-25
5 2019-05-13 2019-09-10

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 2016-08-15
    • 2020-02-28
    • 2013-11-09
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    相关资源
    最近更新 更多