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