R-在第一个NA之后用NA替换数据帧行中的所有值

时间:2016-01-06 06:44:35

标签: r na

我有3500个观测值和278个变量的数据框。对于从第一列开始的每一行,我想用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循环,但它没有终止:

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

有更有效的方法吗?提前谢谢。

3 个答案:

答案 0 :(得分:8)

你可以这样做:

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

您可以applycumsumis.na一起使用来跟踪需要放置NAs的位置(即,在累积的NA总和大于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

答案 1 :(得分:3)

我们可以使用rowCumsums

中的library(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))

答案 2 :(得分:1)

我使用cumany包中的dplyr函数执行此操作,该函数在满足条件后为每个元素返回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)