【问题标题】:Linear Interpolation starting from zero从零开始的线性插值
【发布时间】:2018-01-26 07:02:53
【问题描述】:

我有一个每日时间序列数据集,我正在尝试对其执行每小时线性插值。我的代码在点之间执行线性插值,但我需要在每个 ID 的最后一个点之后从 0 开始并开始新的一天。

以下是我在每日原始数据中添加缺失时间后的输出

以下是我执行以下代码后的输出,但我不知道如何从 0 开始:

dfYPO0_20171 <- dfYPO0_2017 
%>% mutate(TIMESTAMP = as.POSIXct(as.character(TIMESTAMP))) 
%>% group_by(ID) 
%>% do(left_join(data.frame(ID= .$ID[1], TIMESTAMP = seq(min(.$TIMESTAMP), max(.$TIMESTAMP), by = "hour")), ., by=c("ID", "TIMESTAMP"))) 
%>% mutate(CALC_HOURLY_PROD= na.approx(.$"Total Prod Yest"))

以下是我希望输出的样子:

提前感谢您的帮助!

【问题讨论】:

  • 复制列,先填零,然后运行na.approx?
  • 请不要为您的数据提供图片。没有人愿意再次全部输入。相反,请使用dput 制作可打印的数据形式并将其粘贴到您的问题中。
  • 很抱歉,我保证以后不会发生。

标签: r


【解决方案1】:

这是一种使用tidyverse 包的方法。首先,我们将根据缺失值的运行创建组,然后使用approx 进行插值。

library(tidyverse)

# Fake data
dat = data.frame(time=seq(as.Date("2015-01-01"), as.Date("2015-01-31"), "1 day"),
                 prod=c(10.4, rep(NA,19), 25.8, rep(NA,9), 14.2))

dat = dat %>% 
  # Create groups based on runs of NA followed by a value
  mutate(group = rev(cumsum(!is.na(rev(prod))))) %>% 
  # Operate on the groups we just created
  group_by(group) %>% 
  # First, add a zero at the beginning of each group, then run the approx function
  #  to interpolate values for all groups of length greater than 1 
  mutate(prod = replace(prod, row_number()==1 & n()>1, 0),
         prod = if(n()>1) approx(time, prod, xout=time)$y else prod) %>%
  ungroup %>% select(-group)
         time      prod
1  2015-01-01 10.400000
2  2015-01-02  0.000000
3  2015-01-03  1.357895
...
19 2015-01-19 23.084211
20 2015-01-20 24.442105
21 2015-01-21 25.800000
22 2015-01-22  0.000000
23 2015-01-23  1.577778
24 2015-01-24  3.155556
...
29 2015-01-29 11.044444
30 2015-01-30 12.622222
31 2015-01-31 14.200000

【讨论】:

  • 完美运行,感谢您也向我展示了一个新包!