r - 将季度行扩展到多个月行
问题描述
我有一个数据集,其中有一列引用日期。日期以季度的方式书写(即以每 3 个月为 1 个单位)。一栏表示该日期实际上是按季度还是按月计算的。我只想处理季度类型。
我想将每个季度的行扩展到每月的 3 行。另一列称为“收益”也会受到影响,并应除以“3”(即一个季度的月数)。
例子:
example <- data.frame(quarterly_reports = as.Date(as.character(c(20200331,20200630, 20200930,20201231, 20210131)), "%Y%m%d"),
type = c("q","q","q","q","m"),
gains = c(18000, 30000, 45000, 60000, 10000))
这是它的样子:
quarterly_reports type gains
1 2020-03-31 q 18000
2 2020-06-30 q 30000
3 2020-09-30 q 45000
4 2020-12-31 q 60000
5 2021-01-31 m 10000
我想要的是与此类似的输出(并注意我如何将增益列除以 3):
quarterly_reports type gains
1 2020-01-31 m 6000
2 2020-02-28 m 6000
3 2020-03-31 m 6000
4 2020-04-30 m 10000
5 2020-05-31 m 10000
6 2020-06-30 m 10000
7 2020-07-31 m 15000
8 2020-08-31 m 15000
9 2020-09-30 m 15000
10 2020-10-31 m 20000
11 2020-11-30 m 20000
12 2020-12-31 m 20000
13 2021-01-31 m 10000
注意:我正在使用data.table
,并且正在尝试lubridate
将日期从季度转换为月度。我有大约 300 万行这样的行,所以我正在寻找一些又快又脏的东西。
任何答复表示赞赏。
解决方案
更新:根据@Henrik 的建议,这里有一个更有效的选择:
library(lubdridate)
newexample <- example[type == 'q', .(
quarterly_reports = quarterly_reports %m-% months(rep(0:2, .N)),
type = "m",
gains = gains/3) ]
setorder(newexample, quarterly_reports)
newexample
# quarterly_reports type gains
# <Date> <char> <num>
# 1: 2020-01-31 m 6000
# 2: 2020-02-29 m 6000
# 3: 2020-03-31 m 6000
# 4: 2020-04-30 m 10000
# 5: 2020-05-30 m 10000
# 6: 2020-06-30 m 10000
# 7: 2020-07-30 m 15000
# 8: 2020-08-30 m 15000
# 9: 2020-09-30 m 15000
# 10: 2020-10-31 m 20000
# 11: 2020-11-30 m 20000
# 12: 2020-12-31 m 20000
(这可能要慢得多,为后代保留。)
我不知道这会在data.table
' 的正常引用语义方面为您节省很多效率,因为它必须创建很多行(我认为这不是就地完成的)。无论哪种方式,
library(zoo)
library(data.table)
setDT(example)
newexample <- example[type == "q",][,rn:=seq_len(nrow(.SD))][, .(
quarterly_reports = as.Date(seq(as.yearmon(quarterly_reports), length.out = 3, by = -1/12), frac = 1),
type = rep("m", 3),
gains = rep(gains, 3) / 3
), by = rn ][,rn:=NULL]
newexample <- rbindlist(list(newexample, example[type != "q",]))
setorder(newexample, "quarterly_reports")
newexample[]
# quarterly_reports type gains
# <Date> <char> <num>
# 1: 2020-01-31 m 6000
# 2: 2020-02-29 m 6000
# 3: 2020-03-31 m 6000
# 4: 2020-04-30 m 10000
# 5: 2020-05-31 m 10000
# 6: 2020-06-30 m 10000
# 7: 2020-07-31 m 15000
# 8: 2020-08-31 m 15000
# 9: 2020-09-30 m 15000
# 10: 2020-10-31 m 20000
# 11: 2020-11-30 m 20000
# 12: 2020-12-31 m 20000
# 13: 2021-01-31 m 10000
(zoo::as.yearmon
@G.Grothendieck 之前的答案建议使用https://stackoverflow.com/a/47634838/3358272,以便将日期保持为每个月的最后一天。)
推荐阅读
- angular - 如何阻止材料下拉自动完成选择在 Angular 8/9 中触发另一个搜索查询?
- api - Gerrit API - 使用可选的 WEB_LINKS 获取 CommitInfo - 查询语法
- python - Python:我如何确定投掷时使球运动最远的角度?
- express - Loopback 4 使用带有环回的现有快速服务器
- php - 如何在php中加密和解密字符串?
- python - Python 如果我调用我的函数,我应该如何解决这个问题,它返回函数对象
- flutter - Flutter google_pay 实现
- python - matplotlib.pyplot show() 不清除图形
- javascript - Vue 与 Muuri - 如何使用?
- asyncfileupload - Blazor 文件上传 IFormFile