代码之家  ›  专栏  ›  技术社区  ›  Richie Cotton Joris Meys

使用数据帧中的缺失值创建ts时间序列

  •  7
  • Richie Cotton Joris Meys  · 技术社区  · 6 年前

    我有一个数据帧,包含一个月度数据的时间序列,其中有一些缺少的值。

    dates <- seq(
      as.Date("2010-01-01"), as.Date("2017-12-01"), "1 month"
    )
    n_dates <- length(dates)
    dates <- dates[runif(n_dates) < 0.5]
    time_data <- data.frame(
      date = dates,
      value = rnorm(length(dates))
    )
    ##          date      value
    ## 1  2010-02-01  1.3625419
    ## 2  2010-06-01  0.1512481
    ## etc.
    

    forecast ,我想把这个转换成 ts

    这样做的愚蠢方法是在整个时间段内创建一组定期的每月日期,然后左键联接回原始数据。

    library(dplyr)
    first_date <- min(time_data$date)
    last_date <- max(time_data$date)
    full_dates <- data.frame(
      date = seq(first_date, last_date, "1 month")
    )
    extended_time_data <- left_join(full_dates, time_data, by = "date")
    ##          date      value
    ## 1  2010-02-01  1.3625419
    ## 2  2010-03-01         NA
    ## etc.
    

    ts() .

    library(lubridate)
    time_series <- ts(
      extended_time_data$value, 
      start = c(year(first_date), month(first_date)),
      frequency = 12
    )
    

    对于这样一个简单的任务,这是一个冗长和相当恶心。

    我还研究了第一次转换为 xts timetk 但没有什么比这更简单的方法了。

    这个问题是个骗局 How to create time series with missing datetime values ,但答案更加模糊。

    如何创建 缺少值的时间序列中的对象?

    3 回复  |  直到 6 年前
        1
  •  7
  •   akrun    6 年前

    而不是使用 left_join complete ,将其转换为 tsibble 对象,该对象现在与 forecast 包函数

    library(tidyverse)
    library(tsibble)
    time_data %>% 
      complete(date = seq(min(date), max(date), by = "1 month"), 
            fill = list(value = NA)) %>%
      as_tsibble(index = date)
    
    
    # A tsibble: 94 x 2 [1D]
    #   date         value
    #   <date>       <dbl>
    # 1 2010-02-01   1.02 
    # 2 2010-03-01  NA    
    # 3 2010-04-01  NA    
    # 4 2010-05-01   1.75 
    # 5 2010-06-01  NA    
    # 6 2010-07-01  NA    
    # 7 2010-08-01  -0.233
    # 8 2010-09-01  NA    
    # 9 2010-10-01  NA    
    #10 2010-11-01  -0.987
    # ... with 84 more rows
    

    如上所述,它与e兼容 预测 功能

    library(fable)
    time_data %>% 
       complete(date = seq(min(date), max(date), by = "1 month"), 
             fill = list(value = 0)) %>% 
       as_tsibble(index = date) %>%
       ETS(value) %>% 
       forecast %>%
       autoplot
    

    注:此处,缺失值被插补为0。

    enter image description here

    fill

    time_data %>% 
       complete(date = seq(min(date), max(date), by = "1 month")) %>% 
       fill(value) %>% 
       as_tsibble(index = date) %>% 
       ETS(value) %>%
       forecast %>%
       autoplot
    

    n_dates <- 3
    
        2
  •  9
  •   G. Grothendieck    6 年前

    使用最后注释中定义的输入数据帧,将其转换为索引为class的zoo对象 yearmon . 那么 as.ts ts .

    library(zoo)
    
    z <- read.zoo(DF, FUN = as.yearmon)
    as.ts(z)
    ##      Jan Feb Mar Apr May Jun Jul Aug
    ## 2000   1  NA  NA   2   3  NA   4   5
    

    如果你想用管道来表达:

    library(magrittr)
    library(zoo)
    
    DF %>% read.zoo(FUN = as.yearmon) %>% as.ts
    

    na.locf na.approx (线性插值), na.spline , na.StructTS (季节性卡尔曼滤波)或其他填充函数。例如

    library(forecast)
    
    DF %>% read.zoo(FUN = as.yearmon) %>% as.ts %>% na.spline %>% forecast
    

    注意

    set.seed n_dates DF

    library(zoo)
    
    dates <- as.Date(as.yearmon("2000-01") + c(0, 3, 4, 6, 7)/12)
    DF <- data.frame(dates, values = seq_along(dates))
    

    给:

    > DF
           dates values
    1 2000-01-01      1
    2 2000-04-01      2
    3 2000-05-01      3
    4 2000-07-01      4
    5 2000-08-01      5
    
        3
  •  0
  •   Chriss Paul    6 年前

    base 选择和使用 set.seed(789) 在运行数据生成之前

    temp <- which(full_dates$date%in%time_data$date)
    full_dates$new[temp] <- time_data$value
    head(full_dates, 20)
    
             date         new
    1  2010-02-01  0.62589399
    2  2010-03-01  0.98117664
    3  2010-04-01          NA
    4  2010-05-01 -0.04770986
    5  2010-06-01 -1.51961483
    6  2010-07-01          NA
    7  2010-08-01  0.79493644
    8  2010-09-01 -0.14423251
    9  2010-10-01 -0.70649791
    10 2010-11-01  0.61071247
    11 2010-12-01          NA
    12 2011-01-01  1.08506164
    13 2011-02-01 -0.71134925
    14 2011-03-01  1.15628805
    15 2011-04-01  1.23556280
    16 2011-05-01 -0.32245531
    17 2011-06-01          NA
    18 2011-07-01          NA
    19 2011-08-01  0.73277540
    20 2011-09-01 -0.28752883
    

    data.table

    setDT(full_dates)[temp, new:= time_data$value]
    

    现在开始 xts

    xts::xts(full_dates[,-1], order.by = full_dates$date,  frequency = 12 )