我有一个包含月度数据的data.frame df:
Date Value
2008-01-01 3.5
2008-02-01 9.5
2008-03-01 0.1
我希望在这个月的每一天都有数据(我会假设每个月的价值不会改变),因为我将把它合并到另一个包含月度数据的表中。
我希望输出看起来像这样:
Date Value
2008-01-02 3.5
2008-01-03 3.5
2008-01-04 3.5
2008-01-05 3.5
2008-01-06 3.5
2008-01-07 3.5
2008-01-08 3.5
2008-01-09 3.5
2008-01-10 3.5
2008-01-11 3.5
2008-01-12 3.5
2008-01-13 3.5
2008-01-14 3.5
2008-01-15 3.5
2008-01-16 3.5
2008-01-17 3.5
2008-01-18 3.5
2008-01-19 3.5
2008-01-20 3.5
2008-01-21 3.5
2008-01-22 3.5
2008-01-23 3.5
2008-01-24 3.5
2008-01-25 3.5
2008-01-26 3.5
2008-01-27 3.5
2008-01-28 3.5
2008-01-29 3.5
2008-01-30 3.5
2008-01-31 3.5
2008-02-01 9.5
我已尝试to.daily
,但我的电话:
df <- to.daily(df$Date)
返回
Error in to.period(x, "days", name = name, ...) : ‘x’ contains no data
答案 0 :(得分:1)
不确定我是否完全理解,但我认为这样的事情可能有用。
首先,我定义月度数据表
library(data.table)
DT_month=data.table(Date=as.Date(c("2008-01-01","2008-02-01","2008-03-01","2008-05-01","2008-07-01"))
,Value=c(3.5,9.5,0.1,5,8))
然后,您必须执行以下操作
DT_month[,Month:=month(Date)]
DT_month[,Year:=year(Date)]
start_date=min(DT_month$Date)
end_date=max(DT_month$Date)
DT_daily=data.table(Date=seq.Date(start_date,end_date,by="day"))
DT_daily[,Month:=month(Date)]
DT_daily[,Year:=year(Date)]
DT_daily[,Value:=-100]
for( i in unique(DT_daily$Year)){
for( j in unique(DT_daily$Month)){
if(length(DT_month[Year==i & Month== j,Value])!=0){
DT_daily[Year==i & Month== j,Value:=DT_month[Year==i & Month== j,Value]]
}
}
}
基本上,代码将在单独的列中定义每个月值的月份和年份。
然后,它将使用每月数据中的最小和最大日期创建每日数据向量,并为日常数据创建两个单独的年份和月份列。
最后,它会将每日和每月数据的每个组合用日常值填充每日值。如果没有针对某个月份和年份组合的数据,则会显示-100。
如果有效,请告诉我。
答案 1 :(得分:0)
也许不是一个有效的,但我们可以做基础R
do.call("rbind", lapply(1:nrow(df), function(i)
data.frame(Date = seq(df$Date[i],
(seq(df$Date[i],length=2,by="months") - 1)[2], by = "1 days"),
value = df$Value[i])))
我们基本上会生成从sequence
到该月最后一天的start_date
个日期,该日期由
seq(df$Date[i],length=2,by="months") - 1)[2]
并为所有日期重复相同的value
并将它们放入数据框中。
我们获得了一个数据框列表,然后我们可以rbind
使用do.call
。
答案 2 :(得分:0)
使用tidyr::expand
的选项会在月的第一天到月的最后一天之间展开一行。 lubridate::floor_date
可以提供月中的第一天,lubridate::ceiling_date() - days(1)
将提供一个月的最后一天。
library(tidyverse)
library(lubridate)
df %>% mutate(Date = ymd(Date)) %>%
group_by(Date) %>%
expand(Date = seq(floor_date(Date, unit = "month"),
ceiling_date(Date, unit="month")-days(1), by="day"), Value) %>%
as.data.frame()
# Date Value
# 1 2008-01-01 3.5
# 2 2008-01-02 3.5
# 3 2008-01-03 3.5
# 4 2008-01-04 3.5
# 5 2008-01-05 3.5
#.....so on
# 32 2008-02-01 9.5
# 33 2008-02-02 9.5
# 34 2008-02-03 9.5
# 35 2008-02-04 9.5
# 36 2008-02-05 9.5
#.....so on
# 85 2008-03-25 0.1
# 86 2008-03-26 0.1
# 87 2008-03-27 0.1
# 88 2008-03-28 0.1
# 89 2008-03-29 0.1
# 90 2008-03-30 0.1
# 91 2008-03-31 0.1
数据:强>
df <- read.table(text =
"Date Value
2008-01-01 3.5
2008-02-01 9.5
2008-03-01 0.1",
header = TRUE, stringsAsFactors = FALSE)
答案 3 :(得分:0)
另一种方式:
library(lubridate)
d <- read.table(text = "Date Value
2008-01-01 3.5
2008-02-01 9.5
2008-03-01 0.1",
stringsAsFactors = FALSE, header = TRUE)
Dates <- seq(from = min(as.Date(d$Date)),
to = ceiling_date(max(as.Date(d$Date)), "month") - days(1),
by = "1 days")
data.frame(Date = Dates,
Value = setNames(d$Value, d$Date)[format(Dates, format = "%Y-%m-01")])
答案 4 :(得分:0)
to.daily
只能应用于xts/zoo
个对象,并且只能转换为LOWER频率。即从每日到每月,但不是相反。
实现目标的一种简单方法是将df
转换为xts
对象:
df.xts <- xts(df$Value,order.by = df$Date)
合并,如下:
na.locf(merge(df.xts, foo=zoo(NA, order.by=seq(start(df.xts), end(df.xts),
"day",drop=F)))[, 1])
df.xts
2018-01-01 3.5
2018-01-02 3.5
2018-01-03 3.5
2018-01-04 3.5
2018-01-05 3.5
2018-01-06 3.5
2018-01-07 3.5
….
2018-01-27 3.5
2018-01-28 3.5
2018-01-29 3.5
2018-01-30 3.5
2018-01-31 3.5
2018-02-01 9.5
2018-02-02 9.5
2018-02-03 9.5
2018-02-04 9.5
2018-02-05 9.5
2018-02-06 9.5
2018-02-07 9.5
2018-02-08 9.5
….
2018-02-27 9.5
2018-02-28 9.5
2018-03-01 0.1
如果您想在一个月内持续调整价格,请使用na.spline
代替na.locf
。