创建函数以使用R中的先前值填充缺失值

时间:2018-07-31 16:28:16

标签: r function

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

我编写的第一个函数存在边界问题,因此我做了一些其他尝试。以下是其中两个。我所有的尝试都以失败告终-大多数错误是

  

“未找到对象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)

我欢迎采用全新的方法。在此先感谢所有帮助。

1 个答案:

答案 0 :(得分:0)

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

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函数中使用的函数。这确实会创建向量的多个副本,因此对于很长的向量来说可能效率不高。