R中缺失数据的线性插值

Posted

技术标签:

【中文标题】R中缺失数据的线性插值【英文标题】:Linear interpolation for missing data in R 【发布时间】:2018-09-19 05:01:53 【问题描述】:

我有一个数据集记录了不同条件下的瞳孔大小。正如预期的那样,数据中存在眨眼伪影(表现为眨眼开始期间瞳孔大小值的极度下降和眼睛完全闭合时的“-1”,然后瞳孔大小再次逐渐增加)。

据我所知,基于眨眼开始之前和之后的值对眨眼伪影进行线性插值是在瞳孔大小数据中平滑眨眼的可接受方法。

示例数据:

df<-structure(list(Pupil_Avg = c(8.984, 8.984, 8.988001, 8.988001, 
8.978001, 8.978001, 8.9780005, 8.9780005, 8.9780005, 8.9780005, 
8.9780005, 8.9800005, 8.981, 8.9810005, 8.979, 8.979, 8.979, 
8.979, 8.979, 8.979, 8.979, 8.979, 8.979, 8.979, 8.9750005, 8.964, 
8.964001, 8.9660005, 8.9650005, 8.964001, 8.9610005, 8.9620005, 
8.9630005, 8.9630005, 8.963001, 8.963001, 8.96, 8.96, 8.9600005, 
8.962, 8.962, 8.969001, 8.9730005, 8.9670005, 8.9610005, 8.9610005, 
8.9610005, 8.9610005, 8.9610005, 8.9520005, 8.949001, 8.9450005, 
8.9450005, 8.9400005, 8.933001, 8.938001, 8.9510005, 8.956001, 
8.956001, 8.956001, 8.956001, 8.956001, 8.943001, 8.9280005, 
8.9280005, 8.9280005, 8.9280005, 8.9280005, 8.9350005, 8.9470005, 
8.95, 8.9530005, 8.957001, 8.9480005, 8.946, 8.944, 8.944, 8.9460005, 
8.9460005, 8.9480005, 8.9440005, 8.941, 8.938, 8.9280005, 8.9280005, 
8.9280005, 8.9280005, 8.9280005, 8.9280005, 8.929, 8.929, 8.9280005, 
8.9280005, 8.9210005, 8.918, 8.919, 8.92, 8.92, 8.92, 8.9170005, 
8.9100005, 8.9100005, 8.92, 8.9220005, 8.9220005, 8.9100005, 
8.9100005, 8.912, 8.912, 8.912, 8.912, 8.912, 8.9340005, 8.9610005, 
8.958001, 8.985, 8.978, 8.9880005, 8.9880005, 9.014, 9.014, 9.014, 
9.014, 9.014, 8.9740005, 8.9520005, 8.789, 8.6460005, 8.471001, 
8.326, 8.129001, 7.862, 7.862, 7.862, 7.862, 7.862, 7.862, 7.174, 
6.6910005, 6.518, 2.461, 2.182, 1.942, 1.942, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1.487, -1, 
-1, -1, -1, 2.202, 2.202, 2.281, 2.344, 6.265, 6.378, 6.4910005, 
6.8980005, 6.925, 7.04, 7.591, 7.7900005, 7.8470005, 7.978001, 
7.978001, 7.978001, 7.978001, 7.978001, 8.159, 8.1300005, 8.154, 
8.227, 8.281, 8.3160005, 8.353, 8.4430005, 8.4970005, 8.4970005, 
8.4970005, 8.4970005, 8.5150005, 8.6390005, 8.9930005, 9.0110005, 
9.0330005, 9.035, 9.0360005), BLINK_IDENTIFICATION = c(NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Blink Onset", NA, NA, 
NA, "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
"Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", 
NA, "Eye Closed", "Eye Closed", "Eye Closed", "Eye Closed", "Blink Offset", 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-651L))

正如您在BLINK_IDENTIFICATION 列中看到的那样,已经确定了眨眼的开始(第 141 行)和偏移(第 615 行)。当眼睛闭合时(Pupil_Avg 列中的-1)也已在这些标签之间识别出来。

我的主要目标是根据眨眼开始和结束之前和之后的值,对从“眨眼开始”到“偏移”之后的 x 次观察的数据进行线性插值。

谁能建议一种方法来做到这一点? R 中似乎有各种插值函数(例如 approx())。我只是不是 100% 确定如何实施它们。理想情况下,我希望尽可能避免使用for loop,因为我的完整数据集有数百万行长,但如果没有其他方法,我将使用 for 循环。

编辑:这是一个使用上述数据集插入眨眼的函数示例:

install.packages("zoo")
library('zoo')
library(dplyr)

# replace every '-1' value with 'NA'
df$Pupil_Avg[df$Pupil_Avg == -1] <- NA

df<-df%>%mutate(approx = na.approx(Pupil_Avg))

上面的结果是从第一次闭眼开始的插值(Pupil_Avg 列中的 NA)。这是一个开始,但如前所述,我需要从“Blink Onset”之前的行开始插值。

感谢您的宝贵时间。

【问题讨论】:

【参考方案1】:

你可以这样做:

library("imputeTS")
onset <- which("Blink Onset" == df$BLINK_IDENTIFICATION)[[1]]
offset <- which("Blink Offset" == df$BLINK_IDENTIFICATION)[[1]]

df$BLINK_IDENTIFICATION[onset:offset] <- -1
df$Pupil_Avg[df$BLINK_IDENTIFICATION == -1] <- NA
df <- na.interpolation(df$Pupil_Avg, option ="linear")

如果您的时间序列中恰好有 1 个 blink_onset 和 offset,则此方法有效。如果您的系列中有多个,只需删除 which 函数中的 [[1]],然后您将获得所有出现的列表。然后,您使用这两个出现向量将系列的各个部分设置为 NA。

该示例现在使用 imputeTS 的插值函数代替 zoo。两者都做这项工作。 imputeTS 的功能稍微快一些,但可能其他代码无论如何都会占用大部分计算时间。您可以将选项设置为“spline”和“stine”以从线性插值更改为 Spline 或 Stineman 插值。 (如果您使用的是动物园,则为 na.spline)

【讨论】:

以上是关于R中缺失数据的线性插值的主要内容,如果未能解决你的问题,请参考以下文章

R语言ggplot2可视化:使用pracma包的interp1函数对缺失值进行线性插值后进行可视化分析用虚线标记进行数据填充的区域

使用线性回归为 R 中的一个变量和多个国家/地区估算缺失数据

Java 线性插值填充缺失点

Java 线性插值填充缺失点

机器学习数据预处理之缺失值:插值法填充+ lagrange插值+拉格朗日插值

机器学习数据预处理之缺失值:插值法填充+多项式插值