R- 在第一个 NA 之后用 NA 替换数据帧行中的所有值
R- Replace all values in rows of dataframe after first NA by 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
}
有没有更有效的方法来做到这一点?提前致谢。
你可以这样做:
# sample data
mat <- matrix(1, 10, 10)
set.seed(231)
mat[sample(100, 7)] <- NA
您可以将 apply
与 cumsum
和 is.na
一起使用来跟踪需要放置 NA 的位置(即跨行放置 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
我们可以使用 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))
我使用 dplyr
包中的 cumany
函数完成此操作,满足条件后每个元素都 returns 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)
我有一个包含 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
}
有没有更有效的方法来做到这一点?提前致谢。
你可以这样做:
# sample data
mat <- matrix(1, 10, 10)
set.seed(231)
mat[sample(100, 7)] <- NA
您可以将 apply
与 cumsum
和 is.na
一起使用来跟踪需要放置 NA 的位置(即跨行放置 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
我们可以使用 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))
我使用 dplyr
包中的 cumany
函数完成此操作,满足条件后每个元素都 returns 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)