【问题标题】:R- Replace all values in rows of dataframe after first NA by NAR-将第一个NA之后的数据帧行中的所有值替换为NA
【发布时间】:2016-01-06 06:44:34
【问题描述】:

我有一个包含 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
}

有没有更有效的方法来做到这一点?提前致谢。

【问题讨论】:

    标签: r na


    【解决方案1】:

    你可以这样做:

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

    您可以将applycumsumis.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
    

    【讨论】:

      【解决方案2】:

      我们可以从library(matrixStats)使用rowCumsums

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-27
          • 2021-08-30
          • 2021-11-05
          • 1970-01-01
          • 2023-03-13
          • 1970-01-01
          • 1970-01-01
          • 2021-07-29
          相关资源
          最近更新 更多