爆炸日期从年度到月度

时间:2017-04-18 01:09:19

标签: r

我有每年每股账面价值(bps)数据,这些数据需要分成每月的时间序列。我希望加入月度价格系列来计算每月价格预订(P / B)

我的月度数据如下所示(dput下方):

  date      |    bps
------------------------
2012-06-29  |   2.44376
2013-06-28  |   1.73054
2014-06-30  |   1.68171
2015-06-30  |   2.07297
2016-06-30  |   1.77073

我想要的是推出每月出现的所有数据点:

  date      |    bps
------------------------
2012-06-29  |   2.44376
2012-07-31  |   2.44376
2012-08-31  |   2.44376
  ...             ...
2013-05-31  |   2.44376
2013-06-28  |   1.73054
  ...             ...

等等。有没有人知道在R中执行此操作的光滑,非循环方式?

这是我的bps数据框的玩具版本:

df = structure(list(date = structure(c(1340892000, 1372341600, 1404050400, 
1435586400, 1467208800), class = c("POSIXct", "POSIXt"), tzone = ""), bps = 
c(2.44376, 1.73054, 1.68171, 2.07297, 1.77073)), .Names = c("date", 
"bps"), class = "data.frame", row.names = c(NA, 5L))

2 个答案:

答案 0 :(得分:2)

使用不是第一个月的日期有点棘手,但您可以使用seq.POSIXt轻松获得序列。使用lubridate来挖掘日期,

library(tidyverse)
library(lubridate)

df %>% mutate(date = ceiling_date(date, 'month'),
              date = map2(date, 
                          lead(date - 1, default = last(date)), 
                          seq, by = 'month')) %>% 
    unnest() %>% 
    mutate(date = date - days(1))

#>        bps       date
#> 1  2.44376 2012-06-30
#> 2  2.44376 2012-07-31
#> 3  2.44376 2012-08-31
#> 4  2.44376 2012-09-30
#> 5  2.44376 2012-10-31
#> 6  2.44376 2012-11-30
#> 7  2.44376 2012-12-31
#> 8  2.44376 2013-01-31
#> 9  2.44376 2013-02-28
#> 10 2.44376 2013-03-31
#> 11 2.44376 2013-04-30
#> 12 2.44376 2013-05-31
#> 13 1.73054 2013-06-30
#> 14 1.73054 2013-07-31
#> 15 1.73054 2013-08-31
#> 16 1.73054 2013-09-30
#> 17 1.73054 2013-10-31
#> 18 1.73054 2013-11-30
#> 19 1.73054 2013-12-31
#> 20 1.73054 2014-01-31
#> 21 1.73054 2014-02-28
#> 22 1.73054 2014-03-31
#> 23 1.73054 2014-04-30
#> 24 1.73054 2014-05-31
#> 25 1.68171 2014-06-30
#> 26 1.68171 2014-07-31
#> 27 1.68171 2014-08-31
#> 28 1.68171 2014-09-30
#> 29 1.68171 2014-10-31
#> 30 1.68171 2014-11-30
#> 31 1.68171 2014-12-31
#> 32 1.68171 2015-01-31
#> 33 1.68171 2015-02-28
#> 34 1.68171 2015-03-31
#> 35 1.68171 2015-04-30
#> 36 1.68171 2015-05-31
#> 37 2.07297 2015-06-30
#> 38 2.07297 2015-07-31
#> 39 2.07297 2015-08-31
#> 40 2.07297 2015-09-30
#> 41 2.07297 2015-10-31
#> 42 2.07297 2015-11-30
#> 43 2.07297 2015-12-31
#> 44 2.07297 2016-01-31
#> 45 2.07297 2016-02-29
#> 46 2.07297 2016-03-31
#> 47 2.07297 2016-04-30
#> 48 2.07297 2016-05-31
#> 49 1.77073 2016-06-30

答案 1 :(得分:1)

不是特别漂亮,但添加一个月,回滚一天然后离开你去:

tmp <- df[rep(seq_len(nrow(df)),each=12),]
mon <- as.numeric(format(tmp$date,"%m")) + 1:12

tmp$date <- as.POSIXct(paste(
  as.numeric(format(tmp$date,"%Y")) + (mon > 12),
  rep(month.abb,2)[mon],
  "01",
  sep="-"
), format="%Y-%b-%d") - as.difftime(1,units="days")

tmp
#           date     bps
#1    2012-06-30 2.44376
#1.1  2012-07-31 2.44376
#1.2  2012-08-31 2.44376
#1.3  2012-09-30 2.44376
#1.4  2012-10-31 2.44376
#1.5  2012-11-30 2.44376
#1.6  2012-12-31 2.44376
#1.7  2013-01-31 2.44376
#1.8  2013-02-28 2.44376
#1.9  2013-03-31 2.44376
#1.10 2013-04-30 2.44376
#1.11 2013-05-31 2.44376
#2    2013-06-30 1.73054
#2.1  2013-07-31 1.73054
#2.2  2013-08-31 1.73054
# etc etc