在 group_by 中使用 summarize_each 计算平均值时如何处理缺失值(NAs)

10

我有一个数据框 md:

md <- data.frame(x = c(3,5,4,5,3,5), y = c(5,5,5,4,4,1), z = c(1,3,4,3,5,5),
      device1 = c("c","a","a","b","c","c"), device2 = c("B","A","A","A","B","B"))
md[2,3] <- NA
md[4,1] <- NA
md

我想使用dplyr按设备1/设备2组合计算均值:

library(dplyr)
md %>% group_by(device1, device2) %>% summarise_each(funs(mean))

然而,我得到了一些NA值。我希望这些NA值被忽略(na.rm = TRUE)- 我尝试过了,但是函数不想接受这个参数。 这两行代码都会导致错误:

md %>% group_by(device1, device2) %>% summarise_each(funs(mean), na.rm = TRUE)
md %>% group_by(device1, device2) %>% summarise_each(funs(mean, na.rm = TRUE))

2
你可能需要使用 funs(mean= mean(., na.rm=TRUE)) - akrun
3个回答

13
其他答案已经向您展示了将mean(., na.rm = TRUE)传递到summarize/_each的语法。
个人而言,我经常处理这个问题,它非常令人恼火,因此我会定义以下方便使用的NA-aware基本函数集(例如在我的.Rprofile中),这样您就可以使用summarize(mean_)在dplyr中应用它们,而不需要繁琐的参数传递;同时也使源代码更加清晰易读,这是另一个强有力的优点:
mean_   <- function(...) mean(..., na.rm=T)
median_ <- function(...) median(..., na.rm=T)
sum_    <- function(...) sum(..., na.rm=T)
sd_     <- function(v)   sqrt(sum_((v-mean_(v))^2) / length(v))
cor_    <- function(...) cor(..., use='pairwise.complete.obs')
max_    <- function(...) max(..., na.rm=T)
min_    <- function(...) min(..., na.rm=T)
pmax_   <- function(...) pmax(..., na.rm=T)
pmin_   <- function(...) pmin(..., na.rm=T)
table_  <- function(...) table(..., useNA='ifany')
mode_   <- function(...) {
  tab <- table(...)
  names(tab[tab==max(tab)]) # the '==' implicitly excludes NA values
}
clamp_  <- function(..., minval=0, maxval=70) pmax(minval, pmin(maxval,...))

您真正希望能够一次性地切换全局开关,例如na.action/na.pass/na.omit/na.fail,以告诉函数默认行为该做什么,而不会像当前跨不同包时那样抛出错误或不一致。

曾经有一个名为Defaults的CRAN软件包用于设置每个函数的默认值,但自2014年以来就未得到维护,即3.x之前。更多信息请参见在项目特定基础上设置函数默认值R


1
我非常反对那些给我点踩的人,这个解决方案让我花费了数年的痛苦才得出;它紧凑、易读、优雅,而且你仍然可以通过 ... 传递参数来覆盖默认值。如果唯一的反对意见是命名规范的话,那就提出一个更好的吧。 - smci
@Jaap:由于我提到这个代码将放在我的~/.Rprofile文件中,而且还有很多其他的样板代码,所以我强烈倾向于编写紧凑而不是冗长的代码。因此,使用na.rm=T而不是na.rm = TRUE。当你消除无意义的空格时,它实际上更易读。 - smci
没问题,我认为让它更易读会更好。 - Jaap

10

尝试:

 library(dplyr)
 md %>% group_by(device1, device2) %>%
        summarise_each(funs(mean(., na.rm = TRUE)))

8

就是这么简单:

funs(mean(., na.rm = TRUE))

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