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

时间:2015-06-27 09:09:49

标签: r dplyr

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

示例/示例数据

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()中使用另一种方法,在计算记录数时会忽略NA,并且如果变量全部为NA,则返回零?

期望的结果

   var_1 var_2 var_3 var_4 var_5
1     1     2     2     0     2

以下方法让我了解其中的一部分,但我还想为var_4返回0:

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

3 个答案:

答案 0 :(得分:15)

尝试:

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

给出了:

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

答案 1 :(得分:5)

使用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 

答案 2 :(得分:0)

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)))

...相同。