首页 > 解决方案 > 创建函数以用 R 中的先前值填充缺失值

问题描述

我正在尝试创建一个过滤器,该过滤器使用前一个值来填充缺失值,最多两个缺失值(x_i+1 和 x_i+2)用相同的值(x_i)填充。

我组合的第一个函数存在边界问题,因此我进行了其他一些尝试。下面是其中的两个。我所有的尝试都失败了——大多数错误都是

“未找到对象 x”或“意外 } 在”

fillfun <- function(x){
  for(i in seq_along(x[["reg"]])){
    if (is.na(x[["reg"]][[i]])) {
      if (is.na(x[["reg"]][[i+1]]) && is.na(x[["reg"]][[i+2]])) (x[["reg"]][[i]] <- NA)
          else (for(i > 1){ 
            if(is.na(x[["reg"]][[i+1]]) && is.na(x[["reg"]][[i-1]])) (x[["reg"]][[i]] <- NA) })

          else (for(i > 2){
            if (is.na(x[["reg"]][[i-1]]) && is.na(x[["reg"]][[i-2]])) (x[["reg"]][[i]] <- NA) })

     else (x[["reg"]][[i]] <- x[["reg"]][[i-1]])
      }
  }
  return(x)
}


#another attempt 

g <- rep(NA, each=34)
cust <- rep(NA, each=34)
reg <- rep(NA, each=34)
arti <- rep(NA, each=34)
mch0s <- rep(NA, each=34)
yrwk <- rep(NA, each=34)
regpr <- rep(NA, each=34)

fillfun <- function(x){
  g <- rep(NA, each=34)
  cust <- rep(NA, each=34)
  reg <- rep(NA, each=34)
  arti <- rep(NA, each=34)
  mch0s <- rep(NA, each=34)
  yrwk <- rep(NA, each=34)
  regpr <- rep(NA, each=34)

  for(i in seq_along(x[["reg"]])){


    ifelse( (is.na(x[["reg"]][[i]])) , #cond
            (ifelse( (is.na(x[["reg"]][[i+1]]) && is.na(x[["reg"]][[i+2]])), (x[["reg"]][[i]] <- NA) ), 
            ifelse(((i > 1) && (is.na(x[["reg"]][[i+1]]) && is.na(x[["reg"]][[i-1]]))), (x[["reg"]][[i]] <- NA) ), 
            ifelse(((i >2) && (is.na(x[["reg"]][[i-1]]) && is.na(x[["reg"]][[i-2]]))), (x[["reg"]][[i]] <- NA) ), #                  (x[["reg"]][[i]] <- x[["reg"]][[i-1]])))), (g <- x[["reg"]][[i]]))

    cust <- x[["customer"]][[[i]]]
    reg <- x[["region"]][[[i]]]
    arti <- x[["article"]][[[i]]]
    mch0s <- x[["mch0"]][[[i]]]
    yrwk <- x[["yearwk"]][[[i]]]
    regpr <- x[["reg"]][[[i]]]


  }
  return(list(customer=cust, region=reg , article=arti, mch0=mch0s, yearwk=yrwk, reg=regpr, newreg=g))
}

以下是我需要此函数处理的一些数据示例。请记住,这些向量在列表中的列表中的列表中,因此我将使用嵌套lapply()来运行填充函数。

c(NA, NA, 3.37, NA, 3.37, 3.37, NA, NA, NA, NA, NA, 2.97, NA, NA, NA, NA, NA, NA, NA, 3.37, 3.37, NA, 3.34, 3.37, 3.37, 3.37, NA, NA, NA, NA, NA, NA, NA, NA)

c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 4.48, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)

c(4.48, 4.48, 4.48, 4.48, 4.48, NA, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, NA, NA, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48, 4.48)

我欢迎对此采取全新的方法。非常感谢您的所有帮助。

标签: rfunction

解决方案


这是一种不依赖于额外包的方法:

test <- c(NA, NA, 3.37, NA, 3.37, 3.37, NA, NA, NA, NA, NA, 2.97, NA, NA, NA, NA, NA, NA, NA, 3.37, 3.37, NA, 3.34, 3.37, 3.37, 3.37, NA, NA, NA, NA, NA, NA, NA, NA)

n.steps <- 2

tmp <- embed( c(rep(NA,n.steps), test), n.steps+1)

result <- apply(tmp, 1, function(x){
  x[!is.na(x)][1]
})

cbind(test, result)

代码可以转换为函数以在其他*apply函数中使用。这确实会创建向量的多个副本,因此对于非常长的向量可能效率低下。


推荐阅读