首页 > 解决方案 > 如何在 R 中与 NA 值聚合

问题描述

有没有办法与 NA 值聚合?

假设我有以下数据框:

df1 <- data.frame(A = c(1, 2, NA, 4, 5),
                  id = c(11, 12, 13, 14, 15), 
                  k = c(8, 5, 3, 1, 7), 
                  score = c(0, 9, 22, 3, 4))
df1

##   A id k score
## 1  1 11 8     0
## 2  2 12 5     9
## 3 NA 13 3    22
## 4  4 14 1     3
## 5  5 15 7     4

我想按列Ak对列score进行分组,其中一个具有 NA 值。

所以当我跑步时

aggregate(x = df1[, "score"], by = df1[, c("k","A")], 
          FUN = sum, na.action=na.pass)

我得到以下结果

##    k A x
## 1  1 8 1 0
## 2  2 5 2 9
## 3  3 1 4 3
## 4  4 7 5 4

但我想得到与使用 sqldf 相同的东西

sqldf::sqldf("SELECT A, k,
                     SUM(score) 
             FROM df1
             GROUP BY A, k")

##    A k SUM(score)
## 1 NA 3         22
## 2  1 8          0
## 3  2 5          9
## 4  4 1          3
## 5  5 7          4

那么我怎样才能只使用基本 R 函数得到这个结果呢?

谢谢。

标签: rdataframeaggregate

解决方案


1) paste/type.convert使用 . 将 A 转换为字符paste。这也将 NA 转换为字符串“NA”。然后最后转换回来。

transform(aggregate(score ~ k + A, transform(df1, A = paste(A)), sum),
  A = type.convert(A))
##   k  A score
## 1 8  1     0
## 2 5  2     9
## 3 1  4     3
## 4 7  5     4
## 5 3 NA    22

或表示为管道的相同内容:

library(magrittr)

df1 %>%
  transform(A = paste(A)) %>%
  aggregate(score ~ k + A, ., sum) %>%
  transform(A = type.convert(A))

2) 替换为 -Inf上面的一个变体是将 NA 替换为 -Inf 然后在最后转换回来:

transform(aggregate(score ~ k + A, transform(df1, A = replace(A, is.na(A), -Inf)), sum),
  A = replace(A, is.infinite(A), NA))
##   k  A score
## 1 3 NA    22
## 2 8  1     0
## 3 5  2     9
## 4 1  4     3
## 5 7  5     4

3) collap折叠包中的折叠将保留NA:

library(collapse)

collap(df1, ~ k + A, fsum)[-2]
##    A k score
## 1  4 1     3
## 2 NA 3    22
## 3  2 5     9
## 4  5 7     4
## 5  1 8     0

推荐阅读