r - 通过平滑峰值填充 NA
问题描述
df <- data.frame(date = seq(from=as.POSIXct(as.Date("2020-10-01")),
to= as.POSIXct(as.Date("2020-10-02")) , by = 'hour'),
val = c(15,20,18,22,17,NA,NA,NA,80,14,23,16,19,21,NA,NA,60,18,15,20,22,19,NA,35,18))
'NA' 的序列不均匀,后跟峰值,例如: val = 80, 60 和 35 。
我想通过平滑峰值来填充“NA”。例如:在第一个 NA 序列中,三个 NA 后面跟着 80,这等于四个数据点,因此,80 除以 4 = 20 。
注意:峰值不是异常值,因此数据点的总和不应改变。
如果可能的话,我想用上述条件填充 NA,同时保留信号行为(趋势和季节性)。
非常感谢。
解决方案
以下函数NA
用下一个非NA
值除以序列长度填充值序列。
fill_na <- function(x){
na <- is.na(x)
r <- rle(na)
div <- r$lengths[r$values] + 1L
cs <- cumsum(r$lengths)[r$values]
for(i in seq_along(div)){
if(cs[i] < length(x)){
x[ (cs[i] - div[i] + 1L):(cs[i] + 1L) ] <- x[ cs[i] + 1L ]/div[i]
}
}
x
}
fill_na(df$val)
# [1] 15.0 20.0 18.0 22.0 20.0 20.0 20.0 20.0 20.0 14.0 23.0
#[12] 16.0 19.0 20.0 20.0 20.0 20.0 18.0 15.0 20.0 22.0 17.5
#[23] 17.5 17.5 18.0
推荐阅读
- kubernetes - 一个容器进程在多个容器 POD 中崩溃会发生什么?
- vue.js - 将特定模块加载为单独的块
- node.js - Lambda 节点 JS Shopify API 调用
- google-apps-script - GAS:“您每天运行服务高级版 gmail 的次数过多” issu
- vb.net - VB.NET:将datagridview中的文本列转换为图像列并根据文本设置图标
- javascript - 无法读取模态弹出窗口上未定义错误的属性“值”
- macros - 尝试在 Verilog 代码的编译时/运行时更改包含语句
- javascript - 包装器不会在 setData 上更新
- mysql - 在Mysql的json类型列vai hibernate中映射Json字符串
- angular-material - 通过角度缩放后拖动svg子