r - 使用前一天的数据填充时间序列中的缺失值 - R
问题描述
我有一个数据框,其中每一行是不同的日期,每一列是不同的时间序列。
表中的日期范围为 01.01.2019-01.01.2021。
某些时间序列仅与部分日期相关,并且在周末和节假日有缺失值。
如何仅使用每列相关日期的前一天值来完成每个时间序列的缺失值(如果特定列中的时间序列是从 01.03.2019 到 01.09.2019 我只想完成缺失值这个日期范围)?
另外,如果时间序列停止超过 5 天然后继续,我想停止完成,然后再次重新开始完成。
我尝试使用填充功能:
data <- data %>%
fill(colnames(data))
但它也会在特定时间序列结束后完成缺失的数据。
例如df是:
# Date time_series_1 time_series_2 time_series_3
1 01-01-2019 NA 10 8
2 02-01-2019 5 NA 10
3 03-01-2019 10 NA 20
4 04-01-2019 20 6 40
5 05-01-2019 30 NA NA
6 06-01-2019 NA 8 NA
7 07-01-2019 7 NA NA
8 08-01-2019 5 NA NA
9 09-01-2019 NA NA 5
10 10-01-2019 NA NA NA
11 11-01-2019 NA NA 7
12 12-01-2019 NA NA 10
13 13-01-2019 NA NA 11
14 14-01-2019 NA NA 12
15 15-01-2019 NA NA NA
16 16-01-2019 NA NA 9
17 17-01-2019 NA NA 10
18 18-01-2019 NA NA 10
19 19-01-2019 5 NA 11
20 20-01-2019 NA NA NA
21 21-01-2019 5 NA NA
22 22-01-2019 6 NA NA
所需的输出是:
# Date time_series_1 time_series_2 time_series_3
1 01-01-2019 NA 10 8
2 02-01-2019 5 10 10
3 03-01-2019 10 10 20
4 04-01-2019 20 6 40
5 05-01-2019 30 6 40
6 06-01-2019 30 8 40
7 07-01-2019 7 NA 40
8 08-01-2019 5 NA 40
9 09-01-2019 NA NA 5
10 10-01-2019 NA NA 5
11 11-01-2019 NA NA 7
12 12-01-2019 NA NA 10
13 13-01-2019 NA NA 11
14 14-01-2019 NA NA 12
15 15-01-2019 NA NA 12
16 16-01-2019 NA NA 9
17 17-01-2019 NA NA 10
18 18-01-2019 NA NA 10
19 19-01-2019 5 NA 11
20 20-01-2019 5 NA 11
21 21-01-2019 5 NA 11
22 22-01-2019 6 NA 11
解决方案
编辑
感谢@G。Grothendieck 提到na.locf0
有maxgap
可以直接处理 5 天条件的论点。
data[-1] <- lapply(data[-1], zoo::na.locf0, maxgap = 5)
data
较早的答案
仅当连续的长度小于等于 5时,您才可以编写一个用rle
和zoo::na.locf0
替换的函数。将此函数应用于具有 的多个列。NA
NA
lapply
conditionally_replace_na <- function(x) {
ifelse(with(rle(is.na(x)), rep(lengths, lengths)) <= 5 & is.na(x),
zoo::na.locf0(x), x)
}
data[-1] <- lapply(data[-1], conditionally_replace_na)
data
# Date time_series_1 time_series_2 time_series_3
#1 01-01-2019 NA 10 8
#2 02-01-2019 5 10 10
#3 03-01-2019 10 10 20
#4 04-01-2019 20 6 40
#5 05-01-2019 30 6 40
#6 06-01-2019 30 8 40
#7 07-01-2019 7 NA 40
#8 08-01-2019 5 NA 40
39 09-01-2019 NA NA 5
#10 10-01-2019 NA NA 5
#11 11-01-2019 NA NA 7
#12 12-01-2019 NA NA 10
#13 13-01-2019 NA NA 11
#14 14-01-2019 NA NA 12
#15 15-01-2019 NA NA 12
#16 16-01-2019 NA NA 9
#17 17-01-2019 NA NA 10
#18 18-01-2019 NA NA 10
#19 19-01-2019 5 NA 11
#20 20-01-2019 5 NA 11
#21 21-01-2019 5 NA 11
#22 22-01-2019 6 NA 11
函数也可以应用dplyr::across
library(dplyr)
data %>% mutate(across(starts_with('time_series'), conditionally_replace_na))