r - 如果下一个有效数据点距离超过 2 个间隔,则用零填充 R 中的 NA

标签 r replace na

我有多个带有 NA 的向量,我打算用 0 填充距有效数据点超过 2 个间隔的 NA。例如:

x <- c(3, 4, NA, NA, NA, 3, 3)

预期输出是,
3, 4, NA, 0, NA, 3, 3 

最佳答案

更新 -

这可能是最简单和最快的解决方案之一(感谢 G. Grothendieck 的回答)。只需知道该值是否为 NA在任何一侧 NA是足够的信息。因此,使用 leadlag来自 dplyr包裹 -

na2zero <- function(x) {
  x[is.na(lag(x, 1, 0)) & is.na(lead(x, 1, 0)) & is.na(x)] <- 0
  x
}

na2zero(x = c(3, 4, NA, NA, NA, 3, 3))
[1]  3  4 NA  0 NA  3  3

na2zero(x = c(3, 4, NA, NA, NA, NA, NA, 3, 3))
[1]  3  4 NA  0  0  0 NA  3  3

na2zero(x = c(3, 4, NA, NA, NA, 3, 3, NA, NA, 1, NA, 0, 0, rep(NA, 4L)))
[1]  3  4 NA  0 NA  3  3 NA NA  1 NA  0  0 NA  0  0 NA

上一个答案(也很快)-

这是使用 rle 的一种方法和 replace来自基础 R。此方法每 NA 轮一次,这不是运行长度中的端点,变成 0 ——
na2zero <- function(x) {
  run_lengths <- rle(is.na(x))$lengths
  replace(x, 
    sequence(run_lengths) != 1 &
    sequence(run_lengths) != rep(run_lengths, run_lengths) &
    is.na(x),
  0)
}

na2zero(x = c(3, 4, NA, NA, NA, 3, 3))
[1]  3  4 NA  0 NA  3  3

na2zero(x = c(3, 4, NA, NA, NA, NA, NA, 3, 3))
[1]  3  4 NA  0  0  0 NA  3  3

更新的基准 -
set.seed(2)
x <- c(3, 4, NA, NA, NA, 3, 3)
x <- sample(x, 1e5, T)

microbenchmark(
  Rui(x),
  Shree_old(x), Shree_new(x),
  markus(x),
  IceCreamT(x),
  Uwe1(x), Uwe2(x), Uwe_Reduce(x),
  Grothendieck(x),
  times = 50
)

all.equal(Shree_dplyr(x), Rui(x)) # [1] TRUE
all.equal(Shree_dplyr(x), Shree_rle(x)) # [1] TRUE
all.equal(Shree_dplyr(x), markus(x)) # [1] TRUE
all.equal(Shree_dplyr(x), Uwe1(x)) # [1] TRUE
all.equal(Shree_dplyr(x), Uwe2(x)) # [1] TRUE
all.equal(Shree_dplyr(x), Uwe_Reduce(x)) # [1] TRUE
all.equal(Shree_dplyr(x), Grothendieck(x)) # [1] TRUE


Unit: milliseconds
           expr        min         lq        mean     median          uq        max neval
         Rui(x) 286.026540 307.586604  342.620266 318.404731  363.844258  518.03330    50
   Shree_rle(x)  51.556489  62.038875   85.348031  65.012384   81.882141  327.57514    50
 Shree_dplyr(x)   3.996918   4.258248   17.210709   6.298946   10.335142  207.14732    50
      markus(x) 853.513854 885.419719 1001.450726 919.930389 1018.353847 1642.25435    50
   IceCreamT(x)  12.162079  13.773873   22.555446  15.021700   21.271498  199.08993    50
        Uwe1(x) 162.536980 183.566490  225.801038 196.882049  269.020395  439.17737    50
        Uwe2(x)  83.582360  93.136277  115.608342  99.165997  115.376903  309.67290    50
  Uwe_Reduce(x)   1.732195   1.871940    4.215195   2.016815    4.842883   25.91542    50
Grothendieck(x) 620.814291 688.107779  767.749387 746.699435  850.442643  982.49094    50

PS:请查看 TyredSquirell 的答案,这似乎是 Uwe 领先滞后答案的基本版本,但速度稍快一些(未在上面进行基准测试)。

关于r - 如果下一个有效数据点距离超过 2 个间隔,则用零填充 R 中的 NA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56692176/

相关文章:

r - get_map 未传递 API key (HTTP 状态为 '403 Forbidden' )

python 的 scipy.stats.ranksums 与 R 的 wilcox.test

r - 将文本行分隔为数据框的列

java 将特殊字符替换为文本

python - 仅当列中的特定值是唯一的时,如何替换它?

r - R:将NA添加到数据帧

Java exec 无法运行程序,错误 = 2

PHP:返回两个字符之间的字符串

r - 如何确保 'NA' 是 "not"最后一个因子级别?

R 用 NA 填充插值矩阵