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

时间:2015-01-29 16:52:00

标签: r dplyr

我有一个大型数据框,其中我有一个分组变量,然后是许多其他变量列。我想按组计算每个变量的平均值 - 但我想考虑丢失数据的比例。如果有> 75%的数据,则计算均值,如果不是则返回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)))

由于

大卫

1 个答案:

答案 0 :(得分:3)

这是一个快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