【问题标题】:Populating Data Frame Column with Quarter End Dates (R)使用季度结束日期 (R) 填充数据框列
【发布时间】:2020-04-01 13:54:14
【问题描述】:

我正在尝试根据边界日期获取我的数据框 (ValuationDate) 的一列以反映“季度结束”日期(给定年份的 12/31、3/31、6/30、9/30)已经提供了。

所以,我有一个“索引”列 (IDNum)、一个“.id”列(计算 IDNum)和两个日期字段(报告日期和结算日期)。

基本上,给定报告日期和结算日期,我想为这两者之间的每个季度结束日期以及报告和结算日期本身生成记录。

例如:

报告日期:2001-12-29;结算日期:2002-05-31

这应该生成 4 条记录:

  1. 2001-12-29
  2. 2001-12-31
  3. 2002-03-31
  4. 2002-05-31

我已经成功地复制了正确的行次数,并且可以在其中获得两个“简单”日期(每条记录的第一个和最后一个),但在中间日期(“什么去这里”部分代码)。

library(zoo)
    ClaimID_sam <- "1x1"
    ReptDat_sam <- strptime("2001-12-29", format = "%Y-%m-%d")
    SettDat_sam <- strptime("2002-05-31", format = "%Y-%m-%d")
    RecordCount <- as.integer((4*(as.yearqtr(SettDat_sam) - as.yearqtr(ReptDat_sam))) + 2)

    sam_DF <- data.frame(ClaimID_sam,ReptDat_sam,SettDat_sam,RecordCount)
    sam_DF <- as.data.frame(lapply(sam_DF,rep,RecordCount))
    sam_DF = getanID(sam_DF,"ClaimID_sam")

    sam_DF$ValDate <- ifelse(sam_DF$.id == 1, 
                                  as.Date(sam_DF$ReptDat_sam),
                                        "WHAT GOES HERE?????") 

    sam_DF$ValDate = ifelse(sam_DF$.id == sam_DF$RecordCount, 
                                  as.Date(sam_DF$SettDat_sam),
                                  sam_DF$ValDate)

编辑 @g-grothendieck 的解决方案几乎是完美的,虽然有些奇怪,但还没有达到四分之一的终点?

   > do.call("rbind", by(ModData, ModData$ClaimID, add_dates))
       ClaimID Loss_Reported_Date settlementDate       ValuationDate
11X1.1    11X1         2001-12-29     2002-05-31 2001-12-29 00:00:00
11X1.2    11X1         2001-12-29     2002-05-31 2001-12-30 18:00:00
11X1.3    11X1         2001-12-29     2002-05-31 2002-03-30 18:00:00
11X1.4    11X1         2001-12-29     2002-05-31 2002-05-31 00:00:00
11X2.1    11X2         2002-04-06     2002-10-04 2002-04-06 00:00:00
11X2.2    11X2         2002-04-06     2002-10-04 2002-06-29 19:00:00
11X2.3    11X2         2002-04-06     2002-10-04 2002-09-29 19:00:00
11X2.4    11X2         2002-04-06     2002-10-04 2002-10-04 00:00:00

【问题讨论】:

  • 函数as.yearqtr()从何而来?请提供包裹。
  • 来自图书馆(动物园),抱歉。

标签: r date


【解决方案1】:

假设我们的输入是一个包含 ID、st、en 列的数据框,如下所示。不同 ID 的 st 和 en 值可能不同。

以下示例对每个 ID 具有相同的开始日期和相同的结束日期,但代码处理一般情况。

使用函数make_dates,对于每个输入ID,即每一行,将sten都转换为yearqtr类,在它们之间创建一个序列,转换为季度结束日期(frac = 1表示季度末),在其中包括 sten,确保没有元素超过 en 并删除重复项。使用 group_by/group_modify 将其应用于每个 ID(即每行),或者在最后我们展示了如何使用 do.call/by 作为替代方案。

library(dplyr)
library(zoo)

# test input
inp <- data.frame(ID = 1:2, st = as.Date("2001-12-29"), en = as.Date("2002-05-31"))

# given dates st & en return a vector of them and intervening qtr ends
make_dates <- function(st, en) {
  st <- as.Date(st)
  en <- as.Date(en)
  yq1 <- as.yearqtr(st)
  yq2 <- as.yearqtr(en)
  dates <- as.Date(seq(yq1, yq2, 1/4), frac = 1)
  unique(pmin(c(st, dates, en), en))
}

inp %>%
  group_by(ID) %>%
  group_modify(~ cbind(., Date = make_dates(st, en))) %>%
  ungroup

给予:

# A tibble: 8 x 4
     ID st         en         Date      
  <int> <date>     <date>     <date>    
1     1 2001-12-29 2002-05-31 2001-12-29
2     1 2001-12-29 2002-05-31 2001-12-31
3     1 2001-12-29 2002-05-31 2002-03-31
4     1 2001-12-29 2002-05-31 2002-05-31
5     2 2001-12-29 2002-05-31 2001-12-29
6     2 2001-12-29 2002-05-31 2001-12-31
7     2 2001-12-29 2002-05-31 2002-03-31
8     2 2001-12-29 2002-05-31 2002-05-31

dplyr 管道可以在没有 dplyr 的情况下交替完成,如下所示:

add_dates <- function(x) with(x, data.frame(ID, st, en, Date = make_dates(st, en)))
do.call("rbind", by(inp, inp$ID, add_dates))

更新

已经更新了好几次了。

【讨论】:

  • 这很棒。让它在示例数据上工作,但很难连接到我现有的数据框。 ** 我的“开始日期”:ModData$Loss_Reported_Date ** 我的“结束数据”:ModData$settlementDate ** 我的“id”:ModData$.id
  • 是的,这让我离我更近了,虽然日期有点晚了?添加到原始帖子以进行格式化
  • 这是时区问题。 strptime 产生 POISIXct,而不是日期。确保您从一开始就使用 Date ,就像答案中一样。
猜你喜欢
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多