如何在给定最大间隙参数的情况下用零替换连续的 NA(在 R 中)

How to replace consecutive NAs with zero given a max gap parameter (in R)

我想用零替换每行所有连续的 NA 值,但前提是连续的 NA 的数量小于参数 maxgap.

这与函数非常相似zoo::na.locf

x = c(NA,1,2,3,NA,NA,5,6,7,NA,NA,NA)
zoo::na.locf(x,  maxgap = 2, na.rm = FALSE)

给予

[1] NA 1 2 3 3 3 5 6 7 NA NA NA

有两点与我的目标不同: 我也想替换前导 NA,我想用 0 而不是最后一个非 NA 值替换 2 个连续的 NA。

我想得到

0 1 2 3 0 0 5 6 7 NA NA NA

我如何在 R 中执行此操作。我可以使用 tidyverse 中的函数吗?

我们可以使用rle来做到这一点

f1 <- function(vec){
  rl <- rle(is.na(vec))
  lst <- within.list(rl, {
               i1 <- seq_along(values)==1
               i2 <- seq_along(values) != length(values)
               values[!((lengths==2 & values & i2)|
                      (values & i1))] <- FALSE

             })
   vec[inverse.rle(lst)] <- 0
   vec
 }
f1(x)
#[1]  0  1  2  3  0  0  5  6  7 NA NA NA

如果 yna.locf 行的结果,那么如果 y[i] 不是 NA 但 x[i] 是 NA 那么它被替换,所以给它赋值 0。此外,如果它是前导 NA,当下面的 cumsum(...) 项为 0 时出现,则也将其替换。

replace(y, (!is.na(y) & is.na(x)) | cumsum(!is.na(y)) == 0, 0)
## [1]  0  1  2  3  0  0  5  6  7 NA NA NA

你可以,例如这样做:

require(data.table)
require(dplyr)

x = c(NA,1,2,3,NA,NA,5,6,7,NA,NA,NA)

my_replace <- function(x, n, maxgap){
  if(is.na(x[1]) && n <= maxgap){
    x <- 0
  }
  x
}

data.frame(x, y=x) %>% 
  group_by(data.table::rleid(x)) %>% 
  mutate(x = my_replace(x, n(), 2), y = my_replace(y, n(), 1)) %>% 
  ungroup() %>% 
  select(x,y)

这允许您按列设置 maxgap:for x 2 for y 1.

这导致:

# A tibble: 12 × 2
       x     y
   <dbl> <dbl>
1      0     0
2      1     1
3      2     2
4      3     3
5      0    NA
6      0    NA
7      5     5
8      6     6
9      7     7
10    NA    NA
11    NA    NA
12    NA    NA