r - 使用 summarise_each() 计算忽略 NA 的记录

r - using summarise_each() to count records ignoring NAs

有没有办法使用summarise_each()来计算数据框中的记录数,但忽略NAs?

示例/示例数据

df_sample <- structure(list(var_1 = c(NA, NA, NA, NA, 1, NA), var_2 = c(NA, 
  NA, NA, NA, 2, 1), var_3 = c(NA, NA, NA, NA, 3, 2), var_4 = c(NA_real_, 
  NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), var_5 = c(NA, 
  NA, NA, NA, 4, 3)), .Names = c("var_1", "var_2", "var_3", "var_4", 
  "var_5"), row.names = 5:10, class = "data.frame")

> df_samp
   var_1 var_2 var_3 var_4 var_5
5     NA    NA    NA    NA    NA
6     NA    NA    NA    NA    NA
7     NA    NA    NA    NA    NA
8     NA    NA    NA    NA    NA
9      1     2     3    NA     4
10    NA     1     2    NA     3

使用summarise_each()n()统计所有记录:

library(dplyr)
df_samp %>%
  summarise_each(funs(n()))

## result:
   var_1 var_2 var_3 var_4 var_5
1     6     6     6     6     6

我知道 n() 不接受参数,因此我可以在 summarise_each() 中使用另一种方法,它会在计算记录数时忽略 NAs,如果变量全部为 NA?

,return 会归零吗

想要的结果

   var_1 var_2 var_3 var_4 var_5
1     1     2     2     0     2

下面的方法让我走到了那里,但我也想 return 0 for var_4:

df_samp %>%
  melt %>%
  filter(!is.na(value)) %>%
  group_by(variable) %>%
  summarise(records = n())

## result:
  variable records
1    var_1       1
2    var_2       2
3    var_3       2
4    var_5       2

尝试:

df_sample %>% summarise_all(funs(sum(!is.na(.))))

给出:

#  var_1 var_2 var_3 var_4 var_5
#1     1     2     2     0     2

使用data.table

 library(data.table)
 setDT(df_sample)[, lapply(.SD, function(x) sum(!is.na(x)))]
 #   var_1 var_2 var_3 var_4 var_5
 #1:     1     2     2     0     2

或者用base R

 vapply(df_sample, function(x) sum(!is.na(x)), numeric(1))
 #var_1 var_2 var_3 var_4 var_5 
 #  1     2     2     0     2 

sum(is.na(.) 是使用 tidyverse 的正确方法。

这是一个 purrr 替代方案:

df_sample %>% 
  map_df(function(x) sum(!is.na(x)))

df_sample %>% 
  map_df(~sum(!is.na(.x)))

df_sample %>% 
  map_dfr(~sum(!is.na(.x)))

df_sample %>% 
  map_dfc(~sum(!is.na(.x)))

...一样一样。