2016-01-06 68 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)