【问题标题】:Grouping by a variable, then finding proportion of missing values for each column in R按变量分组,然后查找 R 中每列的缺失值比例
【发布时间】:2017-04-15 21:45:19
【问题描述】:

我有一个带有因子变量的数据框和带有几个 NA 的列,如图所示。

var col1 col2 col3
C    1    NA   1
A    NA   1    1 
C    NA   NA   NA
A    1    NA   1
B    NA   1    1
A    1    1    1
B    1    NA   1
B    1    1    1
C    NA   NA   1
B    NA   1   1

我正在寻找一种方法来对变量进行分组并获取每列缺失值的比例,按“var”中的级别分组。输出应如下所示:

var col1 col2 col3
A    0.33 0.33  0
B    0.5  0.25  0 
C    0.66 1.00  0.33

任何方法都可以,并且可以使用不同的方法,但最好使用简单的 dplyr 方法。谢谢!

编辑:我正在寻找一种方法,该方法允许我一次对多列执行此操作并返回类似于我上面显示的数据框。

假设我的数据被命名为“df”,我想一次性获取所有列的缺失比例无需再次手动输入名称。

以下代码不起作用,但它是我想要实现的总体思路。也许一个函数会有所帮助,但我不确定我会如何处理它。

df %>% group_by(var) %>% summarise(names(df[,-1]) = sum(is.na(names(df[,-1])))/n())

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    这是一个更通用的dplyr 解决方案summarise_each,它将接受任意数量的列:

    df1 <-read.table(text="var col1 col2 col3
    C    1    NA   1
    A    NA   1    1
    C    NA   NA   NA
    A    1    NA   1
    B    NA   1    1
    A    1    1    1
    B    1    NA   1
    B    1    1    1
    C    NA   NA   1
    B    NA   1   1",header=TRUE, stringsAsFactors=FALSE)
    
    library(dplyr)
    df1 %>%
    group_by(var) %>%
    summarise_each(funs(sum(is.na(.))/length(.)))
    
    # A tibble: 3 × 4
        var      col1      col2      col3
      <chr>     <dbl>     <dbl>     <dbl>
    1     A 0.3333333 0.3333333 0.0000000
    2     B 0.5000000 0.2500000 0.0000000
    3     C 0.6666667 1.0000000 0.3333333
    

    【讨论】:

      【解决方案2】:

      你可以试试这样的:

      # Create some arbitrary matrix
      rs <- 100
      dat <- data.frame(matrix(1,rs,3))
      
      for(i in 1:rs){
      dat[i,sample(1:3,2,)] <- NA
      }
      
      dat <- cbind(rep(c("A","B","C"),rs)[1:rs],dat)
      
      colnames(dat)[1] <- "var"
      
      # Use the by function with an apply statement
      by(dat[,c("X1","X2","X3")],dat[,"var"],function(x) apply(x,2,function(z){
          n <- length(z)
          miss <- sum(is.na(z))
          prop <- miss/n
          }))
      

      【讨论】:

        【解决方案3】:

        我们也可以使用来自base Raggregate 来做到这一点

        aggregate(.~var, data, FUN = function(x) sum(is.na(x))/length(x), na.action=NULL)
        #  var      col1      col2      col3
        #1   A 0.3333333 0.3333333 0.0000000
        #2   B 0.5000000 0.2500000 0.0000000
        #3   C 0.6666667 1.0000000 0.3333333
        

        data.table

        library(data.table)
        setDT(data)[, lapply(.SD, function(x) sum(is.na(x))/.N), var]
        

        【讨论】:

          【解决方案4】:

          假设您的数据在数据框data 中,您可以执行以下操作:

          ## Your data:
          data <- structure(list(var = structure(c(3L, 1L, 3L, 1L, 
              2L, 1L, 2L, 2L, 3L, 2L), .Label = c("A", "B", "C"), 
              class = "factor"), col1 = c(1, NA, NA, 1, NA, 1, 1, 1, NA, NA), 
              col2 = c(NA, 1, NA, NA, 1, 1, NA, 1, NA, 1), 
              col3 = c(1, 1, NA, 1, 1, 1, 1, 1, 1, 1)), 
              .Names = c("var", "col1", "col2", "col3"), 
              row.names = c(NA, -10L), class = "data.frame")
          
          library(dplyr)
          outDf <- data %>% group_by(var) %>%
              dplyr::summarise(col1 = sum(is.na(col1))/n(),
                            col2 = sum(is.na(col2))/n(),
                            col3 = sum(is.na(col3))/n())
          
          outDf 
          ### A tibble: 3 × 4
          ##     var      col1      col2      col3
          ##  <fctr>     <dbl>     <dbl>     <dbl>
          ##1      A 0.3333333 0.3333333 0.0000000
          ##2      B 0.5000000 0.2500000 0.0000000
          ##3      C 0.6666667 1.0000000 0.3333333
          

          编辑: 要一次调用将其应用于所有列,您可以使用:

          outDf <- data %>% group_by(var) %>%
            dplyr::summarise_all(function(x) sum(is.na(x))/length(x))
          
          outDf
          ### A tibble: 3 × 4
          ##     var      col1      col2      col3
          ##  <fctr>     <dbl>     <dbl>     <dbl>
          ##1      A 0.3333333 0.3333333 0.0000000
          ##2      B 0.5000000 0.2500000 0.0000000
          ##3      C 0.6666667 1.0000000 0.3333333
          

          【讨论】:

          • 如果我有多个列,有没有一种方法可以应用一个函数一次性返回所有列,而无需重复输入
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-08-28
          • 2019-08-08
          • 1970-01-01
          • 2020-06-15
          • 2020-08-16
          • 1970-01-01
          • 2020-05-02
          相关资源
          最近更新 更多