按行顺序识别NA

时间:2016-12-16 12:44:26

标签: r na

我希望根据条件在行序列中填充NA值。请参阅下面的示例。

ID | Observation 1 | Observation 2 | Observation 3 | Observation 4 | Observation 5
 A         NA              0               1             NA             NA

条件是:

  • 之前的所有NA值!序列中的NA值应保留为NA;
  • 但序列之后的所有NAs!NA值应标记(“remove”)

在上面的示例中,观察1中的NA值应保持为NA。但是,观察4和5中的NA值应改为“删除”。

1 个答案:

答案 0 :(得分:3)

您可以定义功能:

replace.na <- function(r,val) {
  i <- is.na(r)
  j <- which(i)
  k <- which(!i)
  r[j[j > k[length(k)]]] <- val
  r
}

然后,假设你有data.frame这样:

r <- data.frame(ID=c('A','B'),obs1=c(NA,1),obs2=c(0,NA),obs3=c(1,2),obs4=c(NA,3),obs5=c(NA,NA))
##  ID obs1 obs2 obs3 obs4 obs5
##1  A   NA    0    1   NA   NA
##2  B    1   NA    2    3   NA

apply的所有数字列,我们可以r行上的函数:

r[,-1] <- t(apply(r[,-1],1,replace.na,999))    
##  ID obs1 obs2 obs3 obs4 obs5
##1  A   NA    0    1  999  999
##2  B    1   NA    2    3  999

这会将r[,-1]视为matrixapply的输出会填充matrix,默认情况下会按列填充。因此,我们必须在将列替换回matrix之前转置生成的r

另一种致电replace.na的方式是:

r[,-1] <- do.call(rbind,lapply(data.frame(t(r[,-1])),replace.na,999))

在这里,我们首先转置r的数字列并将其设为data.frame。这使r的每一行成为列表中的列,即结果数据帧。然后在这些列上使用lapply来应用replace.narbind结果。

如果您想在第一个非NA之后标记所有NA,那么函数replace.na应为:

replace.na <- function(r,val) {
  i <- is.na(r)
  j <- which(i)
  k <- which(!i)
  r[j[j > k[1]]] <- val
  r
}

将其应用于数据:

r[,-1] <- do.call(rbind,lapply(data.frame(t(r[,-1])),replace.na,999))
##  ID obs1 obs2 obs3 obs4 obs5
##1  A   NA    0    1  999  999
##2  B    1  999    2    3  999