【问题标题】:How to replace consecutive NAs with zero given a max gap parameter (in R)如何在给定最大间隙参数的情况下用零替换连续的 NA(在 R 中)
【发布时间】:2017-07-07 02:13:58
【问题描述】:

我想用零替换每行所有连续的NA 值,但前提是连续的NAs 的数量小于参数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] 不适用 1 2 3 3 3 5 6 7 不适用 不适用

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

我想得到

0 1 2 3 0 0 5 6 7 不适用 不适用

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

【问题讨论】:

  • 最后三个 NA 应该保持 NA - 谢谢!

标签: r na imputation tidyverse


【解决方案1】:

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

【讨论】:

  • 我们怎样才能优雅地把它应用到 data.frame 或 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))
  • 如果函数 f 作用于单个向量,则:t(apply(d, 1, f)) 生成一个矩阵,其中每一行都经过变换。
【解决方案2】:

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

【讨论】:

  • @docendodiscimus 感谢 cmets。我读错了。现已修复
【解决方案3】:

你可以例如这样做:

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

【讨论】:

    猜你喜欢
    • 2020-08-30
    • 1970-01-01
    • 2020-11-07
    • 2011-12-31
    • 2020-08-25
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多