【问题标题】:Dealing with NAs when calculating mean (summarize_each) on group_by在 group_by 上计算平均值 (summarize_each) 时处理 NA
【发布时间】:2015-09-12 15:15:43
【问题描述】:

我有一个数据框 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 通过 device1 / device2 组合计算均值:

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))

【问题讨论】:

  • 您可能需要funs(mean= mean(., na.rm=TRUE))

标签: r dplyr mean na


【解决方案1】:

其他答案向您展示了将mean(., na.rm = TRUE) 传递给summarize/_each 的语法。

就我个人而言,我经常处理这个问题,这很烦人,我只是定义了以下方便的 NA 感知基本函数集(例如在我的 .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 之前的版本以来就不再维护。更多相关信息Setting Function Defaults R on a Project Specific Basis

【讨论】:

  • 我真的反对投票者,这是一个我花了几年痛苦才得出的解决方案;它紧凑、可读、优雅,您仍然可以使用 ... 传递参数覆盖默认值。如果唯一的反对意见是命名约定,那么已经提出了一个更好的建议。
  • @Jaap:因为正如我提到的,这在我的 ~/.Rprofile 和许多其他样板文件中都有,所以我更喜欢编写紧凑而不是冗长的代码。因此na.rm=T 而不是na.rm = TRUE。当您消除无意义的空白时,它实际上更清晰。
  • 好的,没问题;我认为让它更具可读性会更好
【解决方案2】:

尝试:

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

【讨论】:

    【解决方案3】:

    就这么简单:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-24
      • 1970-01-01
      • 2015-11-19
      • 2014-02-14
      • 1970-01-01
      • 2021-09-05
      相关资源
      最近更新 更多