【问题标题】:Selecting columns based on missing values in each row根据每行中的缺失值选择列
【发布时间】:2019-08-18 12:51:16
【问题描述】:

我想知道(对于每一行)我的数据中的任何 NA 属于哪些列。目标是创建一个新列/变量,列出数据显示为 NA 的列的名称,对于该特定行,最好使用 dplyr。

使用这个模拟数据,

data = tibble(var_1 = c(NA, 4, 5, 6, 7), var_2 = c(4, 5, 6, 7, 8), var_3 = c(NA, NA, NA, 3, 5))

我想创建 missing_col 列:

  var_1 var_2 var_3       missing_col
1    NA     4    NA  "var_1", "var_3"             
2     4     5    NA           "var_3"
3     5     6    NA           "var_3"
4     6     7     3                NA
5     7     8     5                NA

到目前为止,我的方法是将 rowwise() 函数与 mutate 以及嵌套的 select_if() 和函数结合使用。但是,到目前为止,我尝试过的所有功能都不允许我单独考虑每一行(而不是整列)。下面我介绍了我的方法的一般结构。

data %>% 
  rowwise() %>%
  mutate(missing_col = select_if(function(x) ... )) %>%
  names()

任何有关适当功能的指导将不胜感激。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:
    > data %>% 
    +   mutate(missing_col = apply(., 1, function(x) which(is.na(x)))  %>% 
    +            map_chr(., function(x) if_else(length(x)==0, 
    +                                           "NA", 
    +                                           paste(names(x), collapse=", "))))
    # A tibble: 5 x 4
      var_1 var_2 var_3 missing_col 
      <dbl> <dbl> <dbl> <chr>       
    1    NA     4    NA var_1, var_3
    2     4     5    NA var_3       
    3     5     6    NA var_3       
    4     6     7     3 NA          
    5     7     8     5 NA   
    

    【讨论】:

      【解决方案2】:

      你可以试试这个:

      #Unlist the results from apply
      missing_col=unlist(x=apply(X=data, MARGIN=1, FUN=function(x){
      
        #Get the names of the rows which have NA
        NamesNA=names(which(is.na(x)))
      
        #If there's no NA then replace the 'character(0)' for NA.
        if(length(NamesNA)!=0){
      
          #Concatenate names if there are more than one
          paste0(NamesNA, collapse=",")
      
        }else{
      
          #Replace 'character(0)'
          NA  
      
        }
      })
      )
      
      #Add column with desired output
      data$missing_col=missing_col
      

      这给出了所需的输出:

      # A tibble: 5 x 4
        var_1 var_2 var_3 missing_col
        <dbl> <dbl> <dbl> <chr>      
      1    NA     4    NA var_1,var_3
      2     4     5    NA var_3      
      3     5     6    NA var_3      
      4     6     7     3 NA         
      5     7     8     5 NA   
      

      【讨论】:

        【解决方案3】:

        一种可能的解决方案是直接在 mutate 中使用 apply 而不是 rowwiserowwise 可能有一个等效的方法,但我对该功能的经验是有限的。第二个mutate 仅在您需要NA 用于没有NA 的行时才需要。

        data %>% 
          mutate(missing_col = apply(., 1, function(x) names(.)[is.na(x)] %>% paste(collapse = ", "))) %>% 
          mutate(missing_col = if_else(missing_col == "", NA_character_, missing_col))
        

        【讨论】:

          【解决方案4】:

          这不是一个整洁的方式,但申请似乎很简单:

          data = tibble(var_1 = c(NA, 4, 5, 6, 7), var_2 = c(4, 5, 6, 7, 8), var_3 = c(NA, NA, NA, 3, 5))
          
          data$missing = apply(data,1,function(x) names(x)[is.na(x)])
          

          哪个输出:

          data
          # A tibble: 5 x 4
            var_1 var_2 var_3 missing  
            <dbl> <dbl> <dbl> <list>   
          1 NA     4.00 NA    <chr [2]>
          2  4.00  5.00 NA    <chr [1]>
          3  5.00  6.00 NA    <chr [1]>
          4  6.00  7.00  3.00 <chr [0]>
          5  7.00  8.00  5.00 <chr [0]>
          

          所以缺失列的每个元素都是一个包含字符向量的列表

          data$missing[[1]]
          [1] "var_1" "var_3"
          data$missing[[1]][1]
          [1] "var_1"
          

          【讨论】:

          • 如果我运行它,我最终会得到一个不会在新列中显示实际列名的小标题 - 只是 ""
          • 虽然它在打印出来时不显示数据,但您将能够访问缺失列中的每个值,而这里的一些其他答案是将它们组合成一个字符串,这很难一起工作。
          • 这很有帮助,因为我需要项目的数量。谢谢狮子座!
          猜你喜欢
          • 1970-01-01
          • 2021-05-08
          • 2018-01-20
          • 1970-01-01
          • 1970-01-01
          • 2017-12-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多