【问题标题】:Replace initial NA values with zero in a row until non NA column在行中用零替换初始 NA 值,直到非 NA 列
【发布时间】:2017-05-24 07:59:09
【问题描述】:

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

#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

【问题讨论】:

    标签: r vector na


    【解决方案1】:

    定义一个函数并使用apply。这是一个工作示例。该函数只是测试逻辑值的累积和是否在增加。

    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)))
    

    【讨论】:

      【解决方案2】:

      这是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))
      

      【讨论】:

        【解决方案3】:

        使用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
        

        【讨论】:

          【解决方案4】:

          对于更新的示例:

          我们可以逐行使用applyreplace 的值,直到第一次出现非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)
          

          【讨论】:

          • 这必须在每一行上逐行执行。是否可以对整个矩阵这样做。
          • @risabh 你能否用一个例子来更新你的问题,解释你想要做什么?
          • 您编辑的想法源于我的回答!我不会这样做。
          猜你喜欢
          • 1970-01-01
          • 2011-12-05
          • 1970-01-01
          • 2019-06-27
          相关资源
          最近更新 更多