2016-12-16 88 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