按组计算缺失值的总数?

5

编辑:输入

我对这个非常新。

我有一个类似于这个问题: 按组计数丢失变量?

从那个问题中获取输入数据:

df1 <- data.frame(
  Z = sample(LETTERS[1:5], size = 10000, replace = T),
  X1 = sample(c(1:10,NA), 10000, replace = T),
  X2 = sample(c(1:25,NA), 10000, replace = T),
  X3 = sample(c(1:5,NA), 10000, replace = T))

正如一位用户所提出的,可以使用summarise_each函数:

df1 %>% 
  group_by(Z) %>% 
  summarise_each(funs(sum(is.na(.))))
#Source: local data frame [5 x 4]
#
#       Z    X1    X2    X3
#  (fctr) (int) (int) (int)
#1      A   169    77   334
#2      B   170    77   316
#3      C   159    78   348
#4      D   181    79   326
#5      E   174    69   341  

然而,我只想获得每个组中缺失值的总数。
我也尝试过这个方法,但它没有起作用:R按组计算NA 理想情况下,它应该给我类似这样的结果:
#       Z    sumNA 
#  (fctr)   (int) 
#1      A    580
#2      B    493
#3      C    585
#4      D    586
#5      E    584  

提前感谢。


1
欢迎来到Stackoverflow!对于给定的结果,你的输入数据是什么? - pogibas
你能否提供样本数据?请编辑问题并附上dput(df)的输出结果。如果太大,请使用dput(head(df, 20))的输出结果。(df是您的数据集名称。) - Rui Barradas
使用第一个链接问题中的数据,也许可以使用 group_by(df1, Z) %>% summarize(n = sum(is.na(X1)))?这些数字与您在此处展示的数字不同,但这可能是由于未受控制的随机性(应该使用 set.seed)。 - r2evans
3个回答

8
您可以使用“tidyverse”方法。
require(tidyverse)
#Sample data
dat <- data.frame(group = rep(c("a", "b", "c", "d", "g"), 3), 
                  y = rep(c(1, NA, 2, NA, 3), 3))


dat %>% 
  group_by(group) %>% 
  summarise(sumNA = sum(is.na(y)))

输出:

  group sumNA
  <fct> <int>
1 a         0
2 b         3
3 c         0
4 d         3
5 g         0

编辑

但是,如果你有多个列,你可以使用summarize_all(或者如果你想指定列,可以使用summarize_at; 感谢@bschneidr的评论):

#Sample data
set.seed(123)
dat <- data.frame(group = sample(letters[1:4], 10, replace = T), 
                  x = sample(c(1,NA), 10, replace = T), 
                  y = sample(c(1,NA), 10, replace = T), 
                  z = sample(c(1, NA), 10, replace = T))

dat %>% 
  group_by(group) %>% 
  summarize_all(.funs = funs('NA' = sum(is.na(.))))

# A tibble: 4 x 4
  group  x_NA  y_NA  z_NA
  <fct> <int> <int> <int>
1 a         1     1     0
2 b         3     2     2
3 c         0     1     1
4 d         1     4     2

如果我有更多的变量怎么办?我可以在sum(is.na(y+z+...))中键入所有变量。但是有没有一种方法可以不必键入每个变量而完成这个操作呢? - J. Ziegler
你可以使用dplyr包中的summarize_at函数。例如,以下代码将为变量X和Y计算缺失值数量:data %>% group_by(group) %>% summarize_at(.vars = vars(X, Y), .funs = funs('NA' = sum(is.na(.)))) - bschneidr

2
如果您的数据看起来像链接帖子:
df1 <- data.frame(
  Z = as.factor(sample(LETTERS[1:5], size = 10000, replace = T)),
  X1 = sample(c(1:10,NA), 10000, replace = T),
  X2 = sample(c(1:25,NA), 10000, replace = T),
  X3 = sample(c(1:5,NA), 10000, replace = T)
)

您可以在基础R中执行以下操作:
res <- sapply(split(df1[-1], f = df1$Z), function(x) colSums(is.na(x)))
print(res)
#     A   B   C   D   E
#X1 193 180 199 170 183
#X2  74  68  79  90  87
#X3 350 349 340 336 328

如果您绝对需要转置,可以调用t(res)
print(t(res))
#   X1 X2  X3
#A 193 74 350
#B 180 68 349
#C 199 79 340
#D 170 90 336
#E 183 87 328

编辑:如果你想得到所有NA的总和而不是每个变量内部的总和,则可以对上述内容进行以下小修改:

res2 <- sapply(split(df1[-1], f = df1$Z), function(x) sum(is.na(x)))
print(res2)
#  A   B   C   D   E 
#589 588 569 646 598 

或者,colSums(res)也可以给你同样的结果。同样,如果需要按列进行操作,可以使用t()


是的,但我不想将其拆分为X1、X2、X3。只需要每个组的总缺失值即可。 - J. Ziegler
@J.Ziegler 那么每个 Z 级别中三列 NA 的总和?我已经编辑了我的答案。 - Anders Ellern Bilgrau

2

data.table 解决方案

library(data.table)
setDT(df1)

df1[, .(sumNA = sum(is.na(.SD))), by = Z]

#    Z sumNA
# 1: A   559
# 2: C   661
# 3: E   596
# 4: B   597
# 5: D   560

dplyr解决方案使用rowSums(.[-1]),即除第一列外所有列的行总和。

library(dplyr)

df1 %>% 
  group_by(Z) %>% 
  summarise_all(~sum(is.na(.))) %>% 
  transmute(Z, sumNA = rowSums(.[-1]))

# # A tibble: 5 x 2
#   Z     sumNA
#   <fct> <dbl>
# 1 A       559
# 2 B       597
# 3 C       661
# 4 D       560
# 5 E       596

太棒了,data.table 的方式!你还可以向原始数据集添加新列:setDT(df1)[, sumNA := sum(is.na(.SD)), by = Z] - Peter Chen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接