在 R 中按 NA 聚合

Aggregate by NA in R

有谁知道如何在 R 中通过 NA 进行聚合。

如果你拿下面的例子来说

a <- matrix(1,5,2)
a[1:2,2] <- NA
a[3:5,2] <- 2
aggregate(a[,1], by=list(a[,2]), sum)

输出为:

Group.1 x
2       3

但是有没有办法让输出在输出中包含 NA,如下所示:

Group.1 x
2       3
NA      2

谢谢

使用 dplyr 的摘要

library(dplyr)

a %>%
  as.data.frame %>%
  group_by(V2) %>%
  summarize(V1_sum = sum(V1))

您也可以尝试通过 is.na(a[,2]) 进行聚合。

aggregate(a[,1], by=list(is.na(a[,2])), sum)

#   Group.1 x
# 1   FALSE 3
# 2    TRUE 2

如果你想要一个比 NA 更精细的区别,那么你可能想要定义一个新变量,它使用以前未使用的值来表示 NA(一个因子会更优雅, 但数字向量是最简单的):

b <- a[,2]
b[is.na(b)] <- 999
aggregate(a[,1], by=list(b), sum)

#   Group.1 x
# 1       2 3
# 2     999 2

您可能需要考虑 rowsum() 而不是 aggregate()。它实际上是为矩阵上的这种精确操作而设计的,并且比 aggregate() 快得多。我们可以用 addNA()NA 添加到 a[, 2] 的因子水平。这将确保 NA 显示为分组变量。

rowsum(a[, 1], addNA(a[, 2]))
#      [,1]
# 2       3
# <NA>    2

如果您仍想使用 aggregate(),您也可以合并 addNA()

aggregate(a[, 1], list(Group = addNA(a[, 2])), sum)
#   Group x
# 1     2 3
# 2  <NA> 2

还有一个选项 data.table -

library(data.table)
as.data.table(a)[, .(x = sum(V1)), by = .(Group = V2)]
#    Group x
# 1:    NA 2
# 2:     2 3

Using sqldf:

a <- as.data.frame(a)
sqldf("SELECT V2 [Group], SUM(V1) x 
      FROM a 
      GROUP BY V2")

输出:

  Group x
1    NA 2
2     2 3

stats package

AdamO 提案的变体:

data.frame(xtabs( V1 ~ V2 , data = a,na.action = na.pass, exclude = NULL))

输出:

    V2 Freq
1    2    3
2 <NA>    2

Rich 的 addNA 解决方案不需要对 aggregate 语法进行任何实质性更改,因此我认为这是最好的解决方案。我会指出另一个选项,它产生类似于 table 的输出(因此可以强制转换为类似于 aggregatedata.frame 结构)是 xtabs

xtabs(a[, 1] ~ a[, 2], addNA=T)

给出:

  Group.1 x
1       2 3
2    <NA> 2

我看到的另一个 "trick" 正在为这些数据分配一个缺失的代码。我们都喜欢 R 的 NA 输出,但是将缺失代码分配给分组变量是一个很好的编码练习。我们取它比数据集中的最大值多一位,形式为 -999...99.

codemiss <- function(x) -10^(floor(log(max(abs(x), na.rm=T), base=10))+2)-1

一般情况下工作。

然后你得到

a[, 2][is.na(a[, 2])] <- codemiss(a[, 2])

并且:

aggregate(a[, 1], list(a[, 2]), sum)

给你:

  Group.1 x
1     -99 2
2       2 3