根据每行中的缺失值选择列

时间:2019-03-27 20:29:56

标签: r dplyr

我想(对于每一行)知道数据中的任何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()

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

4 个答案:

答案 0 :(得分:1)

您可以尝试以下方法:

#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   

答案 1 :(得分: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 :(得分:0)

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

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"

答案 3 :(得分:0)

一种可能的解决方案是直接在突变中使用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))