我想插入丢失的数据,但是跳过丢失数据行多于X数(例如3个)的场景。我下面有代码,但最后一步不起作用。
我以前发布了一个问题,并得到了很好的答案(How do I prevent interpolation between values where there are more than 2 missing rows of data?)。但是,我简化了示例数据框,现在当我尝试运行代码时,在最后一步中出现此错误:
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步:将近似函数应用于目标列(使用线性插值对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:对所有数据中的所有列应用ContinuousNA函数,并将结果转换为矩阵:
m_NA <- map(alldata, consecutiveNA, len = 3) %>%
as.data.frame() %>%
as.matrix()
第4步:基于m_NA在alldata_int中用NA替换那些TRUE,然后完成工作:
alldata_int[m_NA] <- NA
运行步骤4时,出现此错误:
Error in `[<-.data.frame`(`*tmp*`, m_NA, value = NA) : unsupported matrix index in replacement
我认为这是因为时间戳列左侧还有其他非数字列。有没有简单的方法可以调整此代码以解决此问题?还是更好的解决方案?
答案 0 :(得分:3)
na.approx
具有一个maxgap
参数:
library(zoo)
ok <- sapply(alldata, is.numeric)
replace(alldata, ok, lapply(alldata[ok], na.approx, maxgap = 2, na.rm = FALSE))
答案 1 :(得分:1)
由于alldata_int
,您的year(r_timestamp)
有另外一列group_by
。您必须删除该列以使alldata_int
和m_NA
具有相同的尺寸。以下对我有用。
顺便说一句,year
可能来自lubridate
软件包。最好提供功能的来源。
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"]])) %>%
ungroup() %>%
select(-`year(r_timestamp)`)
alldata_int[m_NA] <- NA