在R中的时间序列中使用xblocks内插值

时间:2019-02-28 20:06:17

标签: r time-series interpolation xts zoo

我在弄清楚如何使用xblocks()工作时遇到了麻烦。首先,这是来自更大数据集的一个小示例:

data <- data.frame(
    Date = sample(c("1993-07-05", "1993-07-05", "1993-07-05", "1993-08-30", "1993-08-30", "1993-08-30", "1993-08-30", "1993-09-04", "1993-09-04")),   
    Oxygen = sample(c("0.9", "0.4", "4.2", "5.6", "7.3", NA, "9.5", NA, "0.3")))

然后我使用xts计算每个月的平均值:

xtsAveragedata <- xts(Averagedata[-1], Averagedata[[1]])
xtsAverageMonthlyData <- apply.monthly(xtsAveragedata, FUN = mean)

现在,我对数据进行线性插值:

Interpolateddata <- na.approx(xtsAverageMonthlyData)

我想创建一个图形,在其中使用xblocks()或类似的东西来显示数据中我使用插值的区域,就像这样,我在网上找到了: enter image description here

如何对所有值执行此操作/对整个数据集进行自动化?参考指南中没有任何示例可以翻译成类似的内容。

感谢您的帮助。非常感谢。

1 个答案:

答案 0 :(得分:1)

因此,它不使用xtszoo,但也许本演练会有所帮助。我使用的是稍大(且每天)的数据集,但它应该是可重现的:

library(tidyverse)
library(lubridate)

set.seed(4)
df <- tibble(
  Date = seq.Date(ymd("1993-07-01"), by = "1 day", length.out = 100),
  Oxygen = runif(100, 0, 10)
)

# Randomly assign 20 records to NA
df[sample(1:nrow(df), 20), "Oxygen"] <- NA

df_for_plot <- df %>%
  arrange(Date) %>%
  group_by(month(Date)) %>%
  mutate(
    is_na = is.na(Oxygen),
    month_avg = mean(Oxygen, na.rm = TRUE),
    oxygen_to_plot = if_else(is_na, month_avg, Oxygen)
  )

df_for_plot
#> # A tibble: 100 x 6
#> # Groups:   month(Date) [4]
#>    Date        Oxygen `month(Date)` is_na month_avg oxygen_to_plot
#>    <date>       <dbl>         <dbl> <lgl>     <dbl>          <dbl>
#>  1 1993-07-01  5.86               7 FALSE      5.87         5.86  
#>  2 1993-07-02  0.0895             7 FALSE      5.87         0.0895
#>  3 1993-07-03  2.94               7 FALSE      5.87         2.94  
#>  4 1993-07-04  2.77               7 FALSE      5.87         2.77  
#>  5 1993-07-05  8.14               7 FALSE      5.87         8.14  
#>  6 1993-07-06 NA                  7 TRUE       5.87         5.87  
#>  7 1993-07-07  7.24               7 FALSE      5.87         7.24  
#>  8 1993-07-08  9.06               7 FALSE      5.87         9.06  
#>  9 1993-07-09  9.49               7 FALSE      5.87         9.49  
#> 10 1993-07-10  0.731              7 FALSE      5.87         0.731 
#> # ... with 90 more rows

# Plot the regular data, but for the geom_rect use only the filtered data where the is_na column is TRUE.
# Assuming you have daily data, you just set the xmax to be that Date + 1.
ggplot(df_for_plot, aes(x = Date, y = oxygen_to_plot)) +
  geom_line() +
  geom_rect(
    data = df_for_plot %>% filter(is_na), 
    aes(xmin = Date, xmax = Date + 1, ymin = -Inf, ymax = +Inf), fill = "skyblue", alpha = 0.5
  )