2016-12-16 66 views
3

我想根据条件在行顺序中填充顺序的NA值。请看下面的例子。按行顺序识别NA的顺序

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

的条件是:

  • 所有NA值之前的序列中的NA值应保持NA;
  • 但所有NAS后的序列中!NA值应该被标记的(“去除”)

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

+1

什么是你的实际数据的结构?请使用'dput(name_of_object)'发布一个样本。在包含数字数据的data.frame中使用字符串'“remove”'作为标志将会产生问题,因为您不能在给定列中混合使用数字和非数字值。 – nrussell

+0

感谢您的及时回应。该对象是仅包含数值变量的数据帧。我说删除只是一个例子,它可以是任何数字作为标志。 – Prometheus

+0

我知道你说的行式,但是'观察1','观察2'等分开的列,并且您想要为数据帧/表的每一行执行此操作吗? – aichao

回答

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 

This treat r[,-1]作为matrix,并且apply的输出填充matrix,默认情况下按列填充。因此,在将列更换回r之前,我们必须对产生的matrix进行转置。

另一种方式来调用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 
+0

很棒@aichao ...即使我正在尝试类似的东西,但你做了这份工作! –

+0

如果我想将obs2更改为999,解决方案r [j [j = k [length(k)]]] < - val是什么? – Prometheus

+0

非常感谢!很有帮助。 – Prometheus