r - 如何防止在缺失数据行数超过 X 的值之间进行插值?
问题描述
我想插入丢失的数据,但跳过丢失数据行数超过 X(例如 3)的场景。我有下面的代码,但最后一步不起作用。
我之前发布了一个问题并得到了很好的答案(如何防止在缺少 2 行以上数据的值之间进行插值?)。但是,我过度简化了示例数据框,现在当我尝试运行代码时,在最后一步出现此错误:
Error in `[<-.data.frame`(`*tmp*`, m_NA, value = NA) : unsupported matrix index in replacement
有没有一种简单的方法来调整下面的代码来处理这个问题?还是有更好的解决方案?
这是我的数据的一个子集:
alldata <- structure(list(q_cms = c(0.157, 0.154, 0.154, 0.151, 0.144, 0.151,
0.151, 0.154, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, 0.157, 0.144, NA), site = c("Wade", "Wade", "Wade", "Wade",
"Wade", "Wade", "Wade", "Wade", "Wade", "Wade", "Wade", "Wade",
"Wade", "Wade", "Wade", "Wade", "Wade", "Wade", "Wade", "Wade",
"Wade", "Wade", "Wade", "Wade", "Wade"), r_timestamp = structure(c(1479691800,
1479692700, 1479693600, 1479694500, 1479695400, 1479696300, 1479697200,
1479698100, 1479698160, 1479698220, 1479698280, 1479698340, 1479698400,
1479698460, 1479698520, 1479698580, 1479698640, 1479698700, 1479698760,
1479698820, 1479698880, 1479698940, 1479699000, 1479699900, 1479699960
), class = c("POSIXct", "POSIXt"), tzone = "Etc/GMT-4"), NO3_mgNL = c(0.0351,
NA, NA, NA, NA, NA, NA, NA, 0.0316, 0.0309, 0.0309, 0.03, 0.029,
0.0297, 0.0278, 0.0278, 0.0304, 0.0292, 0.0267, 0.0282, 0.0293,
0.0313, 0.0306, NA, 0.0311), DOC_mgL = c(1.854, NA, NA, NA, NA,
NA, NA, NA, 1.85, 1.843, 1.836, 1.822, 1.802, 1.836, 1.797, 1.808,
1.817, 1.815, 1.813, 1.813, 1.824, 1.826, 1.82, NA, 1.831)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -25L))
这是我要执行的代码。在此示例中,我试图跳过有 3 个或更多连续缺失数据行的插值:
所需软件包:
library('tidyverse')
library('lubridate')
第 1 步:创建一个函数,continuousNA,它可以根据阈值(由参数 len 指定)识别向量中的连续 NA:
consecutiveNA <- function(x, len = 3){
rl <- rle(is.na(x))
logi <- rl$lengths >= len & rl$values
rl$values <- logi
inver <- inverse.rle(rl)
return(inver)
}
第 2 步:将 approx 函数应用于目标列(使用线性插值对 NA 进行插值):
alldata_int <- alldata %>%
arrange(site, r_timestamp) %>%
group_by(site, year(r_timestamp)) %>%
mutate_at(vars(c(NO3_mgNL, DOC_mgL)),
funs(approx(r_timestamp, ., r_timestamp, rule=1, method="linear")[["y"]]))
第 3 步:对 alldata 中的所有列应用 ContinuousNA 函数,并将结果转换为矩阵:
m_NA <- map(alldata, consecutiveNA, len = 3) %>%
as.data.frame() %>%
as.matrix()
第四步:根据m_NA将alldata_int中的那些TRUE替换为NA,然后工作就完成了:
alldata_int[m_NA] <- NA
当我运行第 4 步时,我收到此错误:
Error in `[<-.data.frame`(`*tmp*`, m_NA, value = NA) : unsupported matrix index in replacement
我认为这是因为时间戳列左侧的附加非数字列。有没有一种简单的方法来调整这段代码来处理这个问题?还是更好的解决方案?
解决方案
na.approx
zoo包里有个maxgap
说法:
library(zoo)
ok <- sapply(alldata, is.numeric)
replace(alldata, ok, lapply(alldata[ok], na.approx, maxgap = 2, na.rm = FALSE))
推荐阅读
- swift - 如何显示/隐藏添加到 NSWindow 标题栏的按钮?
- git - 我做了 git pull --rebase 现在我的分支中有其他人的提交 - 为什么
- c# - 仅当前面没有制表符或空格时才匹配括号组
- javascript - 如何在javascript中对带有负数的表格进行排序
- postman - “令牌包含无效的段数”
- python - 我不确定如何在合并排序过程中删除重复项
- c++ - 在不同的文件中定义属于另一个类的类
- ruby-on-rails - 如何获取图像变体的高度和宽度?
- postgresql - Docker 正在寻找另一个 postgres 参考
- r - 如何为另一列中的每个唯一值返回列的最大值?