【问题标题】:Obtaining a list of all fiscal years between two dates获取两个日期之间所有会计年度的列表
【发布时间】:2021-05-18 15:40:46
【问题描述】:

联邦财政年度从 10 月 1 日9 月 30 日,由结束日期的年份确定。例如,FY20 是从 2019 年 10 月 1 日到 2020 年 9 月 30 日

给定一个具有唯一 ID、开始日期和结束日期的数据框,我如何获得一个包含这些日期之间所有会计年度的长表,而无需编写计算来手动验证每个会计年度?

ID   START_DT   END_DT
1    08/15/17   08/15/19 
2    08/15/17   08/15/18

可重现的例子:

dat <- data.frame(id = c(1, 2),
           start_dt = c(as.Date("2017-08-15"), as.Date("2017-08-15")),
           end_dt = c(as.Date("2019-08-15"), as.Date("2018-08-15")))

期望的最终结果:

ID  FY
1   17
1   18
1   19
2   17
2   18

编辑:可能的解决方案

这是受 Jon Spring 建议启发的一种解决方案:

dat <- data.frame(id = c(1, 2),
           start_dt = c(as.Date("2017-08-15"), as.Date("2017-08-15")),
           end_dt = c(as.Date("2019-08-15"), as.Date("2018-08-15")))

dat_fy <- data.frame(date_seq = seq(from = min(dat$start_dt), 
                                    to = max(dat$end_dt), 
                                    by = 1)) %>% 
  mutate(fy = ifelse(month(date_seq) <= 9, 
                     year(date_seq), 
                     year(date_seq) + 1))

dat %>% 
  full_join(dat_fy, by = character()) %>% 
  filter(date_seq >= start_dt & date_seq <= end_dt) %>% 
  distinct(id, fy)

【问题讨论】:

  • 这听起来很适合使用非等连接,可以使用data.tablesqldffuzzyjoin 应用。首先创建一个 FY-end 日期列表,然后加入它,条件是 start 早于这些日期,end 晚于这些日期。
  • 非常感谢。我最终使用了带有查找表的基于连接的解决方案

标签: r


【解决方案1】:

定义一个函数fyear,通过转换为 yearqtr 类并添加 1/4 将日期转换为会计年度,这会将 Oct/Nov/Dec 推到下一个日历年,因此该日历年是要求的会计年度。最后通过id分组将其应用于每一行。

library(dplyr)
library(zoo)

fyear <- function(...) as.integer(as.yearqtr(...) + 1/4)

dat %>% 
  group_by(id) %>% 
  group_modify(~ data.frame(fyear = fyear(.$start_dt):fyear(.$end_dt) %% 100)) %>%
  ungroup

给予:

# A tibble: 5 x 2
     id fyear
  <dbl> <dbl>
1     1    17
2     1    18
3     1    19
4     2    17
5     2    18

【讨论】:

    【解决方案2】:

    data.table 方法使用带有财政年度的查找表

    library(data.table)
    library(lubridate)
    setDT(dat)
    dat.fiscal <- data.table( start = seq(as.Date("2000-10-01"), as.Date("2020-10-01"), by = "1 year"),
                              end   = seq(as.Date("2001-09-30"), as.Date("2021-09-30"), by = "1 year"))
    dat.fiscal[, fy := lubridate::year(end)]
    setkey(dat, start_dt, end_dt)
    setkey(dat.fiscal, start, end)
    
    foverlaps(dat, dat.fiscal)
    #         start        end   fy id   start_dt     end_dt
    # 1: 2016-10-01 2017-09-30 2017  2 2017-08-15 2018-08-15
    # 2: 2017-10-01 2018-09-30 2018  2 2017-08-15 2018-08-15
    # 3: 2016-10-01 2017-09-30 2017  1 2017-08-15 2019-08-15
    # 4: 2017-10-01 2018-09-30 2018  1 2017-08-15 2019-08-15
    # 5: 2018-10-01 2019-09-30 2019  1 2017-08-15 2019-08-15
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 2017-06-12
      • 2013-08-09
      • 2022-01-04
      • 2010-10-05
      • 2021-02-28
      • 1970-01-01
      相关资源
      最近更新 更多