考虑数据集中的以下行: -
#Row (initially):
NA NA NA NA NA NA NA 2 3 1 4 5 2 NA NA 6 7
我希望将所有这些行转换为
#Row (modified) :
0 0 0 0 0 0 0 2 3 1 4 5 2 NA NA 6 7
只有在非na值之前发生的初始NA被替换为零,而不是之后的那些。
编辑:我的数据是矩阵,例如:
NA NA NA NA 1 1 1 1 1 1
NA NA NA NA 1 1 1 1 1 1
NA NA NA NA 1 1 1 1 1 1
NA NA NA NA NA NA NA 1 NA 1
NA NA NA NA NA NA NA 1 NA 1
NA NA NA NA NA NA NA NA NA 1
1 1 1 1 1 1 1 1 NA 1
1 1 1 1 1 1 1 1 1 1
应修改为
0 0 0 0 1 1 1 1 1 1
0 0 0 0 1 1 1 1 1 1
0 0 0 0 1 1 1 1 1 1
0 0 0 0 0 0 0 1 NA 1
0 0 0 0 0 0 0 1 NA 1
0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 NA 1
1 1 1 1 1 1 1 1 1 1
答案 0 :(得分:4)
定义一个函数并使用apply。这是一个有效的例子。该函数只是测试逻辑值的cumsum是否在增加。
x<-c(NA,NA,NA,NA,1,0,NA,NA,3)
y<-c(2,NA,3,NA,1,0,NA,2,3)
z<-c(NA,NA,3,NA,1,0,NA,NA,3)
df<-data.frame(x,y,z)
initialNA<-function(x){
index<-cumsum(is.na(x))>=seq_along(x)
x[index]<-0
x
}
df2<-data.frame(t(apply(df,1,initialNA)))
答案 1 :(得分:3)
以下是rle()
的解决方案:
x <- c(NA, NA, NA, NA, NA, NA, NA, 2, 3, 1, 4, 5, 2, NA, NA, 6, 7)
if (is.na(x[1])) x[1:rle(is.na(x))$lengths[1]] <- 0
x
对于行式应用:
f <- function(x) {
if (is.na(x[1])) x[1:rle(is.na(x))$lengths[1]] <- 0
x
}
apply(yourMatrix, 1, f)
最终你必须转置结果,因为apply()
从矩阵的行逐列构造结果:
t(apply(yourMatrix, 1, f))
此任务的zoo
中有一个功能:
x <- c(NA, NA, NA, NA, NA, NA, NA, 2, 3, 1, 4, 5, 2, NA, NA, 6, 7)
library("zoo")
na.fill(x, c(0,NA,NA))
答案 2 :(得分:1)
更新示例:
我们可以使用apply
行方式和replace
值为0,直到第一次出现非NA值。
t(apply(mat, 1, function(x) replace(x, cumsum(!is.na(x)) == 0, 0)))
# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
#[1,] 0 0 0 0 1 1 1 1 1 1
#[2,] 0 0 0 0 1 1 1 1 1 1
#[3,] 0 0 0 0 1 1 1 1 1 1
#[4,] 0 0 0 0 0 0 0 1 NA 1
#[5,] 0 0 0 0 0 0 0 1 NA 1
#[6,] 0 0 0 0 0 0 0 0 0 1
#[7,] 1 1 1 1 1 1 1 1 NA 1
#[8,] 1 1 1 1 1 1 1 1 1 1
原始答案
我们可以一起使用which
和min
来查找第一个非NA值的索引,并将这些值替换为0.
x[1:min(which(!is.na(x))) - 1] <- 0
x
#[1] 0 0 0 0 0 0 0 2 3 1 4 5 2 NA NA 6 7
或which.max
x[1:which.max(!is.na(x)) - 1] <- 0
最简单的which.min
x[1:which.min(is.na(x)) - 1] <- 0
数据强>
x <- c(NA, NA, NA, NA, NA, NA, NA, 2, 3, 1, 4, 5, 2, NA, NA, 6, 7)
答案 3 :(得分:1)
使用cummin
:
x[cummin(is.na(x))==1] <- 0
#[1] 0 0 0 0 0 0 0 2 3 1 4 5 2 NA NA 6 7
cumprod
也可以使用。
至于你的编辑,对整个矩阵做同样的事情,说m
:
t(apply(m,1,function(x) replace(x, cummin(is.na(x))==1, 0)))
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 0 0 0 0 1 1 1 1 1 1
# [2,] 0 0 0 0 1 1 1 1 1 1
# [3,] 0 0 0 0 1 1 1 1 1 1
# [4,] 0 0 0 0 0 0 0 1 NA 1
# [5,] 0 0 0 0 0 0 0 1 NA 1
# [6,] 0 0 0 0 0 0 0 0 0 1
# [7,] 1 1 1 1 1 1 1 1 NA 1
# [8,] 1 1 1 1 1 1 1 1 1 1