r - 使用季度结束日期 (R) 填充数据框列
问题描述
我正在尝试获取我的数据框(ValuationDate)的一列,以根据已经提供的边界日期反映“季度结束”日期(给定年份的 12/31、3/31、6/30、9/30)。
所以,我有一个“索引”列(IDNum)、一个“.id”列(计算 IDNum)和两个日期字段(报告日期和结算日期)。
基本上,给定报告日期和结算日期,我想为这两者之间的每个季度结束日期以及报告和结算日期本身生成记录。
例如:
报告日期:2001-12-29;结算日期:2002-05-31
这应该生成 4 条记录:
- 2001-12-29
- 2001-12-31
- 2002-03-31
- 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
解决方案
假设我们的输入是一个包含 ID、st、en 列的数据框,如下所示。不同 ID 的 st 和 en 值可能不同。
下面的示例对于每个 ID 具有相同的开始日期和相同的结束日期,但代码处理一般情况。
使用 function make_dates
,对于每个输入 ID,即对于每一行,都将st
和转换en
为yearqtr
类,在它们之间创建一个序列,转换为季度结束日期(frac = 1 表示季度结束),包括st
anden
在其中,确保没有元素超出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))
更新
已经更新好几次了。
推荐阅读
- rust - 有没有办法根据常量的存在有条件地编译?
- feathersjs - Featherjs - 添加自定义字段以挂钩上下文对象
- elasticsearch - 如何让 elasticsearch 5.6.3 跨集群搜索工作?
- regex - 仅显示特定的正则表达式组并使用 sed 在 bash 中删除该行的其余部分
- mysql - MySQL对多个分组的最新值求和
- python - 这是使用 smtplib 的方式吗
- python - Python 序数排名
- node.js - IS LIST 在对话流实现中是否与@sys.any 一起使用?
- c++ - 重命名符号时如何排除库包含?
- r - 在 R 中形成重要结果的列表