代码之家  ›  专栏  ›  技术社区  ›  jgozal

删除丢失值超过30%的所有变量

  •  2
  • jgozal  · 技术社区  · 10 年前

    我发现这个函数可以检测任何给定数据帧中每列缺失值的比例:

    propmiss <- function(dataframe) lapply(dataframe,function(x) data.frame(nmiss=sum(is.na(x)), n=length(x), propmiss=sum(is.na(x))/length(x)))
    

    我将其分配给一个变量,如下所示:

    propmissdf <- propmiss(df)  
    

    然后我将数据帧循环到数据中的NULL变量,如下所示:

    for(i in (1:length(df))){  
      var = names(df)[i]
      if((propmissdf[[var]][[3]]) > 0.3) { #the 3 index represents the proportion inside propmissdf
      df[var] <- NULL   
       }
    }
    

    这给了我一个错误:

    Error in if ((propmissdf[[var]][[3]]) > 0.3) { :argument is of length zero
    

    但不知怎的,它起了作用。它删除了几个缺失值比例大于0.3的变量,但如果我再次运行for循环,它会删除更多变量,直到再删除3或4次,直到删除所有变量。为什么会发生这种情况?请随时纠正我的问题,或者想出一个更好的方法来删除NAs超过30%的变量。

    2 回复  |  直到 10 年前
        1
  •  2
  •   A5C1D2H2I1M1N2O1R2T1    10 年前

    您可以使用以下内容:

    df <- df[colSums(is.na(df))/nrow(df) < .3]
    
    • colSums(is.na(df)) 会计算出有多少 NA 每个列中都有值。
    • 将该输出除以 data.frame 以获得比例。
    • 使用 < .3 以创建可用于子集相关列的逻辑比较。

    示例数据和示例:

    set.seed(2)
    df <- data.frame(matrix(sample(c(NA, 1:4), 20, TRUE), nrow = 4))
    df
    #   X1 X2 X3 X4 X5
    # 1 NA  4  2  3  4
    # 2  3  4  2 NA  1
    # 3  2 NA  2  2  2
    # 4 NA  4  1  4 NA
    
    colSums(is.na(df))/nrow(df)
    #   X1   X2   X3   X4   X5 
    # 0.50 0.25 0.00 0.25 0.25 
    
    df[colSums(is.na(df))/nrow(df) < .3]
    #   X2 X3 X4 X5
    # 1  4  2  3  4
    # 2  4  2 NA  1
    # 3 NA  2  2  2
    # 4  4  1  4 NA
    

    作为参考,这里有一个快速的时间比较:

    set.seed(1)
    df <- data.frame(matrix(sample(c(NA, 1:4), 4000, TRUE), ncol = 1000))
    
    akfun <- function() {
      i1 <-sapply(df, function(x) {
        pr <- prop.table(table(factor(is.na(x), levels=c(TRUE, FALSE))))
        pr[as.logical(names(pr))]< 0.3
      })
      df[i1]
    }
    
    amfun <- function() df[colSums(is.na(df))/nrow(df) < .3]
    
    identical(amfun(), akfun())
    # [1] TRUE
    
    system.time(akfun())
    #    user  system elapsed 
    #   0.172   0.000   0.173 
    system.time(amfun())
    #    user  system elapsed 
    #   0.000   0.000   0.001 
    
        2
  •  2
  •   akrun    10 年前

    我们可以用 sapply ,获取 count “NA”值的 table ,使用`prop。表来查找比例并创建逻辑向量。

    i1 <-sapply(df, function(x) {
    
          pr <- prop.table(table(factor(is.na(x), levels=c(TRUE, FALSE))))
    
          pr[as.logical(names(pr))]< 0.3
    
     })
    

    此向量可用于细分列。

    df[i1]
    

    如果我们需要删除列

    df[!i1] <- list(NULL) #contributed by @Ananda Mahto
    df
    #   X2 X3 X4 X5
    #1  4  2  3  4
    #2  4  2 NA  1
    #3 NA  2  2  2
    #4  4  1  4 NA
    

    注意: df 摘自@Ananda Mahto的帖子