将初始NA值替换为连续零,直到非NA列

时间:2017-05-24 07:59:10

标签: r vector na

考虑数据集中的以下行: -

#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

4 个答案:

答案 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

原始答案

我们可以一起使用whichmin来查找第一个非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