【问题标题】:Impute missing values with ROLLING mean in R在 R 中使用 ROLLING 平均值估算缺失值
【发布时间】:2017-06-23 16:25:12
【问题描述】:

我是 R 新手,正在努力解决一个问题。

我需要一个函数来根据给定大小的窗口内元素的平均值来估算 vector 中的缺失值。

但是,这个窗口会移动,因为假设我的NA 位于位置 30,而我的窗口大小为 10,则应计算 x[20:40] 的平均值。所以对于每个找到的NA,window-mean 都会不同。

我一直在尝试这个:

impute.to.window.mean <- function(x, window) {

  na.idx <- is.na(x)  #find missing values in x

  for (na in na.idx) {

    y <- (x[na]-window):(x[na]+window)
    na.idx[na] <- mean(y, na.rm = TRUE)
  }

  return(x)
}

但它不正确,我不知道如何继续。

【问题讨论】:

    标签: r missing-data imputation imputets


    【解决方案1】:

    您可能需要考虑使用imputeTS 包。下面是一个使用简单移动平均线和 4 窗口填充值的示例:

    x <- rnorm(100)
    x[c(7, 21, 33)] <- NA
    
    imputeTS::na_ma(x, k = 4, weighting = "simple")
    

    【讨论】:

      【解决方案2】:

      使用 zoo::rollapply,这可以在一个语句中完成。在这个例子中,我们使用了一个长度为 5 的窗口(当前点两侧各 2 个):

      library(zoo)
      
      x <- replace(1:20, c(4, 6, 10, 15), NA) # test data
      
      
      rollapply(c(NA, NA, x, NA, NA), 5, 
          function(x) if (is.na(x[3])) mean(x, na.rm = TRUE) else x[3])
      

      给予:

       [1]  1.000000  2.000000  3.000000  3.333333  5.000000  6.666667  7.000000
       [8]  8.000000  9.000000 10.000000 11.000000 12.000000 13.000000 14.000000
      [15] 15.000000 16.000000 17.000000 18.000000 19.000000 20.000000
      

      【讨论】:

        【解决方案3】:

        R 基础:

        df <- data.frame(x = sample(c(1:10,NA),1000, replace = T))
        window <- 10
        
        lapply(1:(nrow(df)-window), function(x) ifelse(is.na(df[x,'x']),mean(df[x:(x+10),'x'],na.rm=T),df[x,'x']))
        

        我现在唯一的区别是我期待这些价值观。但您可以根据自己的规格进行更改。

        【讨论】:

          【解决方案4】:

          您的索引有点偏离

          impute.to.window.mean <- function(x, window) {
            na.idx <- which(is.na(x))  #find missing values in x
          
            for (na in na.idx) {
              y <- sort(x[(na - window):(na + window)])
              x[na] <- mean(y)
            }
          
            return(x)
          }
          

          举例说明

          set.seed(1)
          x <- sample(10)
          na <- 6
          x[na] <- NA
          # [1]  3  4  5  7  2 NA  9  6 10  1
          
          window <- 3L
          

          我使用了sort,因为它会一步删除NAs;你想要这个向量的平均值,它们是属于window的所有值

          sort(x[(na - window):(na + window)])
          # [1]  2  5  6  7  9 10
          
          mean(sort(x[(na - window):(na + window)]))
          # [1] 6.5
          

          现在测试你的函数

          impute.to.window.mean(x, window)
          # [1]  3.0  4.0  5.0  7.0  2.0  6.5  9.0  6.0 10.0  1.0
          

          编辑

          其实你应该使用

          y <- sort(x[pmax(1L, (na - window)):pmin(length(x), (na + window))])
          

          而不是NA 出现在例如 2 并且您的窗口大于 1 的情况

          ## current version
          impute.to.window.mean(x, 10)
          # Error in x[(na - window):(na + window)] : 
          #   only 0's may be mixed with negative subscripts
          
          ## version with pmax/pmin
          impute.to.window.mean(x, 10)
          # [1]  3.000000  4.000000  5.000000  7.000000  2.000000  5.222222  9.000000  6.000000 10.00000 1.000000
          
          mean(sort(x))
          # [1] 5.222222
          
          impute.to.window.mean <- function(x, window) {
            na.idx <- which(is.na(x))  #find missing values in x
          
            for (na in na.idx) {
              # y <- sort(x[(na - window):(na + window)])
              y <- sort(x[pmax(1L, (na - window)):pmin(length(x), (na + window))])
              x[na] <- mean(y)
            }
          
            return(x)
          }
          

          【讨论】:

            【解决方案5】:

            "Caret" 包的 preProcess 函数有一个名为 "knnImpute" 的方法可以做到这一点。试一试。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-08-16
              • 1970-01-01
              • 2020-06-07
              • 1970-01-01
              相关资源
              最近更新 更多