代码之家  ›  专栏  ›  技术社区  ›  mikey

将NA替换为R向量中先前数字的修改版本

  •  0
  • mikey  · 技术社区  · 4 年前

    我有一个带有一些NAs的向量,我想用之前的非NA值减去0.1来替换其中的一些NAs。如果NAs字符串超过某个长度(例如2),我也不想替换NAs。这里有一个例子

    x <- c(1:3, NA, 4, NA, NA, 5, NA, NA, NA, 6, NA)
    

    我想做一个向量,看起来像

    x_prime <- c(1:3, 2.9, 4, 3.9, 3.8, 5, NA, NA, NA, 6, 5.9)
    

    打印出来看起来像:

    > x_prime
     [1] 1.0 2.0 3.0 2.9 4.0 3.9 3.8 5.0  NA  NA  NA 6.0  5.9
    

    更复杂的是,我想要跟踪我修改过的索引,所以我还想要一个

    idx <- c(4, 6, 7, 13)
    

    如果第一个位置是NA(以及所有领先的NAs),我们可以离开它,什么也不做。

    我在网上发现了一些类似的问题 this ,我也尝试过类似的功能,但没有成功。有什么想法吗?提前谢谢你。

    0 回复  |  直到 4 年前
        1
  •  3
  •   Ronak Shah    4 年前

    基本R选项 ave :

    len <- 2
    x1 <- ave(x, cumsum(!is.na(x)), FUN = function(v) {
      if(length(v) > len + 1) v 
      else v[1] - seq(0, by= 0.1, length.out = length(v))
      })
    
    x1
    #[1] 1.0 2.0 3.0 2.9 4.0 3.9 3.8 5.0  NA  NA  NA 6.0 5.9
    

    我们创建一组 NA 值与第一个非NA值一起使用,并在 大道 .如果组长度大于 len + 1 ( + 1 因为第一个值不是 然后我们不改变组中的任何东西,否则我们从组中的第一个值减去0,0.1,0.2。


    要获得被替换的位置,请查找 他在 x 哪些不是 他在 x1 .

    which(is.na(x) & !is.na(x1))
    #[1]  4  6  7 13
    
        2
  •  2
  •   akrun    4 年前

    这里有一个选项 diff cumsum split

    library(zoo)
    lst1 <- split(x, cumsum(c( diff(!is.na(x)) < 0, TRUE)))
    unname(unlist(lapply(lst1, function(x) if(sum(is.na(x)) <= 2) 
          na.locf0(x) -seq(0, length.out = length(x), by = 0.1) else x)))
    #[1] 1.0 1.9 3.0 2.9 4.0 3.9 3.8 5.0  NA  NA  NA 6.0  NA
    

    第二种情况

    as.vector(unlist(sapply(split(seq_along(x) * is.na(x), 
         cumsum(c( diff(!is.na(x)) < 0, TRUE))), 
             function(x)  x[x != 0 & sum(x != 0) <=2])))
    #[1]  4  6  7 13
    
        3
  •  1
  •   Steffen Moritz    4 年前

    使用软件包的版本 imputeTS 使用 na_locf 带参数 maxgap :

    library("imputeTS")
    x_prime <- na_locf(x, maxgap = 2)
    idx <- which(is.na(imp) != is.na(x))
    x_prime[idx] <- x_prime[idx] - 0.1
    

    结果:

    x_prime
    [1] 1.0 2.0 3.0 2.9 4.0 3.9 3.9 5.0  NA  NA  NA 6.0 5.9
    
    idx
    [1]  4  6  7 13
    

    编辑: 简短的加法,似乎我对“用之前的非NA值减去0.1替换NAs”的解释有所不同。不确定这是否是故意的,但您似乎更希望也执行负0.1,而之前结转的值是插补值。