如何在R中给定最大间隙参数,用零替换连续的NA?

3

我希望将每行中所有连续的 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替换2个连续的NA,而不是最后一个非NA值。

我希望得到

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

如何在R中实现这一点?我可以使用tidyverse中的函数吗?


最后三个NA应该保持不变 - 谢谢! - Richi W
3个回答

2
如果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

我们如何以逐行的方式优雅地将其应用于数据框或tibble?x = c(NA,1,2,3,NA,NA,5,6,7,NA,NA,NA) y = c(NA,1,2,3,NA,NA,5,6,7,NA,NA,NA)d = data.frame(rbind(x,y)) - Richi W
如果函数 f 适用于单个向量,则 t(apply(d, 1, f)) 会生成一个矩阵,其中每一行都被转换。 - G. Grothendieck

1
我们可以使用 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

感谢您的评论。我之前阅读有误,现已修正。 - akrun

1
你可以这样做:

例如:

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)

这可以让您针对x设置列间的maxgap,为2,而针对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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接