【发布时间】:2021-10-26 11:30:05
【问题描述】:
{collapse} 是一个R 包,可以加快数据操作和描述性统计的处理时间。一些功能intentionally echoes {dplyr}。例如,比较以下dplyr 代码与collapse 代码。它们在语法上非常相似,并且产生相同的输出。
library(ggplot2)
library(dplyr, warn.conflicts = FALSE)
library(collapse, warn.conflicts = FALSE)
#> collapse 1.6.5, see ?`collapse-package` or ?`collapse-documentation`
#> Note: stats::D -> D.expression, D.call, D.name
using_dplyr <-
mpg |>
group_by(manufacturer) |>
summarise(mean_hwy = mean(hwy))
using_collapse <-
mpg |>
collapse::fgroup_by(manufacturer) |>
collapse::fsummarise(mean_hwy = mean(hwy))
identical(using_collapse, using_dplyr)
#> [1] TRUE
但是{collapse} 更快
bench::mark(dplyr =
mpg |>
group_by(manufacturer) |>
summarise(mean_hwy = mean(hwy)),
collapse =
mpg |>
fgroup_by(manufacturer) |>
fsummarise(mean_hwy = mean(hwy))) |>
autoplot()
由reprex package (v2.0.0) 于 2021 年 8 月 26 日创建
我的问题:
而以下表达式是类似的并且有效:
group_by() |> summarise() = fgroup_by() |> fsummrise(),
以下类比不起作用:
group_by() |> mutate() |> != fgroup_by() |> ftransform()。 (ftransform() 是 collapse 等价于 dplyr::mutate())。
证明问题
让我们用两种等效的语法来显示相同的管道:
library(ggplot2)
library(dplyr, warn.conflicts = FALSE)
library(collapse, warn.conflicts = FALSE)
#> collapse 1.6.5, see ?`collapse-package` or ?`collapse-documentation`
#> Note: stats::D -> D.expression, D.call, D.name
is_bigger_than_mean <- function(x) {
x > mean(x)
}
## dplyr syntax
mutate_using_dplyr <-
mpg |>
select(manufacturer, hwy) |>
group_by(manufacturer) |>
mutate(hwy_bigger_than_mean = is_bigger_than_mean(hwy))
## collapse syntax
mutate_using_collapse <-
mpg |>
fselect(manufacturer, hwy) |>
fgroup_by(manufacturer) |>
ftransform(hwy_bigger_than_mean = is_bigger_than_mean(hwy))
比较hwy_bigger_than_mean列中的结果
mutate_using_dplyr ## correct
#> # A tibble: 234 x 3
#> # Groups: manufacturer [15]
#> manufacturer hwy hwy_bigger_than_mean
#> <chr> <int> <lgl>
#> 1 audi 29 TRUE
#> 2 audi 29 TRUE
#> 3 audi 31 TRUE
#> 4 audi 30 TRUE
#> 5 audi 26 FALSE
#> 6 audi 26 FALSE
#> 7 audi 27 TRUE
#> 8 audi 26 FALSE
#> 9 audi 25 FALSE
#> 10 audi 28 TRUE
#> # ... with 224 more rows
mutate_using_collapse ## incorrect
#> # A tibble: 234 x 3
#> manufacturer hwy hwy_bigger_than_mean
#> * <chr> <int> <lgl>
#> 1 audi 29 TRUE
#> 2 audi 29 TRUE
#> 3 audi 31 TRUE
#> 4 audi 30 TRUE
#> 5 audi 26 TRUE
#> 6 audi 26 TRUE
#> 7 audi 27 TRUE
#> 8 audi 26 TRUE
#> 9 audi 25 TRUE
#> 10 audi 28 TRUE
#> # ... with 224 more rows
#>
#> Grouped by: manufacturer [15 | 16 (11)]
由reprex package (v2.0.0) 于 2021 年 8 月 26 日创建
造成这种差异的原因是什么?是否有可能实现正确的输出,使mutate_using_collapse 提供与mutate_using_dplyr 相同的输出?
注意:类似问题讨论了类似问题here
【问题讨论】:
-
根据文档:“请注意,与 dplyr::mutate 不同,ftransform 本身不会对分组数据帧执行任何操作。” — 我的猜测是该软件包通过删除功能购买了更高的性能。
-
刚读到这个问题。我认为我犯的一个错误是在文档中提及
dplyr::mutate。顾名思义,ftransform是base::transform的更快、更通用的替代品。从工程的角度来看,很难按组优化mutate的功能,因为表达式可能是任意的,例如mutate(newcol = col1 - FUN(col2) + FUN2(col3)) requiresFUN1` 和FUN2为每个组执行。一般来说,{collapse} 不会按组执行任何 R 函数,所有分组操作都是通过快速统计函数在 C++ 中实现的。 -
就通用的“split-apply-combine”计算机制而言,我推荐
data.table,它具有非常快速的机制,可以按组执行任意表达式。请注意,data.table仅对其内部优化的功能达到非常高的速度,请参阅?GForce,并且这些优化中的大多数也仅可用于聚合。 {collapse} 的任务是提供类似的优化函数和一些可应用于向量矩阵和杂项的支持语法。表格数据,支持计量经济学所需的加权计算和数据转换。