2016-01-06 141 views
2

我有一個3500個觀測值和278個變量的數據幀。對於從第一列開始的每一行,我想用NAs替換第一個NA之後出現的所有值。舉例來說,我想從一個數據幀走,像這樣:R-將第一個NA之後的數據幀行中的所有值替換爲NA

X1 X2 X3 X4 X5 
1 3 NA 6 9 
1 NA 4 6 18 
6 7 NA 3 1 
10 1 2 NA 2 

要像

X1 X2 X3 X4 X5 
1 3 NA NA NA 
1 NA NA NA NA 
6 7 NA NA NA 
10 1 2 NA NA 

我嘗試使用下面的嵌套的循環,但它不是終止:

for(i in 2:3500){ 
firstna <- min(which(is.na(df[i,]))) 
df[i, firstna:278] <- NA 
} 

有沒有更有效的方法來做到這一點?提前致謝。

回答

8

你可以做這樣的事情:

# sample data 
mat <- matrix(1, 10, 10) 
set.seed(231) 
mat[sample(100, 7)] <- NA 

您可以使用applycumsumis.na跟蹤其中的NA需要放置(即在該行那裏的NAS中累積更大的地方比0)。然後,使用這些位置將NA分配到適當位置的原始結構。

mat[t(apply(is.na(mat), 1, cumsum)) > 0 ] <- NA 
#  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
# [1,] 1 1 1 1 1 1 NA NA NA NA 
# [2,] NA NA NA NA NA NA NA NA NA NA 
# [3,] 1 1 1 1 1 1 1 1 1  1 
# [4,] 1 1 1 1 1 1 1 1 1  1 
# [5,] 1 1 1 NA NA NA NA NA NA NA 
# [6,] 1 1 1 1 1 1 1 1 1  1 
# [7,] 1 NA NA NA NA NA NA NA NA NA 
# [8,] 1 1 1 1 1 1 1 1 1  1 
# [9,] 1 1 1 1 1 1 1 1 1  1 
#[10,] 1 1 NA NA NA NA NA NA NA NA 

工程數據框罰款。使用提供的示例數據:

d<-read.table(text=" 
X1 X2 X3 X4 X5 
1 3 NA 6 9 
1 NA 4 6 18 
6 7 NA 3 1 
10 1 2 NA 2 ", header=TRUE) 

d[t(apply(is.na(d), 1, cumsum)) > 0 ] <- NA 
# X1 X2 X3 X4 X5 
#1 1 3 NA NA NA 
#2 1 NA NA NA NA 
#3 6 7 NA NA NA 
#4 10 1 2 NA NA 
3

我們可以使用rowCumsumslibrary(matrixStats)

library(matrixStats) 
d*NA^rowCumsums(+(is.na(d))) 
# X1 X2 X3 X4 X5 
#1 1 3 NA NA NA 
#2 1 NA NA NA NA 
#3 6 7 NA NA NA 
#4 10 1 2 NA NA 

還是一個base R選項

d*NA^do.call(cbind,Reduce(`+`,lapply(d, is.na), accumulate=TRUE)) 
1

我這個使用從該cumany功能做dplyr包,這個在條件滿足後,h爲每個元素返回TRUE

df <- read.table(text = "X1 X2 X3 X4 X5 
         1 3 NA 6 9 
         1 NA 4 6 18 
         6 7 NA 3 1 
         10 1 2 NA 2 ", 
       header = T) 

library(plyr) 
library(dplyr) 

na_row_replace <- function(x){ 
    x[which(cumany(is.na(x)))] <- NA 
    return(x) 
} 

adply(df, 1, na_row_replace)