在 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
的输出(因此可以强制转换为类似于 aggregate
的 data.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
有谁知道如何在 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
的输出(因此可以强制转换为类似于 aggregate
的 data.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