使用 dplyr 进行快速聚合 - 更好的方法?

Fast aggregation using dplyr - better way?

我有一个大型数据框,其中有一个分组变量,然后是许多其他变量列。我想按组计算每个变量的平均值 - 但我想考虑缺失数据的比例。如果有 >75% 的数据则计算平均值,如果不是 return NA.

我的实际数据比下面的测试数据多了很多列。这种方法似乎很快。我的问题是有没有更快的方法?

# number of groups
n <- 100000
dat <- data.frame(grp = factor(rep(1:n, each = 10)),
              var1 = rep(c(1:8, NA, NA), times = n),
              var2 = rep(c(1:7, NA, NA, NA), times = n)
              )

# summarise by group, calculate mean if enough data
res <- dat %>% 
  group_by(grp) %>% 
  summarise_each(funs(ifelse(length(na.omit(.)) / length(.) > 0.75, 
                         mean(., na.rm = TRUE), NA)))

谢谢

大卫

这是一个几乎快 5 倍的选项:

system.time(
  res0 <- dat %>% 
    group_by(grp) %>% 
    summarise_each(
      funs(
        ifelse(
          length(na.omit(.)) / length(.) > 0.75, 
          mean(., na.rm = TRUE), NA)
      ) )
)
#   user  system elapsed 
#   7.27    0.00    7.29 
system.time(
  res1 <- dat %>% 
    group_by(grp) %>% 
    summarise_each(
      funs(
        if(sum(is.na(.)) / length(.) < 0.25) mean(., na.rm=TRUE) 
        else NA
    ) )
)
#   user  system elapsed 
#   1.59    0.00    1.60 
all.equal(res0, res1)
#  [1] TRUE

并且 data.table 速度提高了 2 倍:

system.time(
  res2 <- setDT(dat)[, 
    lapply(
      .SD, 
      function(x) 
        if(sum(is.na(x)) / .N < 0.25) mean(x, na.rm=TRUE) else NA
    ), 
  by=grp]
)
#   user  system elapsed 
#   0.76    0.00    0.76 
all.equal(res0, setDF(res2))
#  [1] TRUE