在R中将每月数据转换为每日数据

时间:2018-05-04 05:06:53

标签: r date

我有一个包含月度数据的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

5 个答案:

答案 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