【发布时间】:2021-08-22 09:29:38
【问题描述】:
我正在尝试使用两个向量之间的所有可能组合来加速表的创建。当我们使用expand.grid() 时,我们可以从base R 获得此功能。但是,我想知道我们是否可以使用 {collapse} 包中的工具更快地完成相同的结果。
有一个 StackOverflow 线程关于此主题 here。但是,即使我们采用那里提供的最快解决方案,在以下情况下它也是最慢的。虽然tidyr::expand_grid() 比base R 更快,但我仍然希望利用collapse 包我们可以获得更快的处理时间。
#library(collapse)
#library(tidyr)
library(babynames)
year <- collapse::funique(babynames$year, sort = TRUE)
names <- collapse::funique(babynames$name)
expand.grid.jc <- function(seq1,seq2) { ## from https://stackoverflow.com/a/10407457/6105259
as.data.frame(cbind(Var1 = rep.int(seq1, length(seq2)),
Var2 = rep.int(seq2, rep.int(length(seq1),length(seq2)))))
}
my_benchmarking <-
bench::mark(base = expand.grid(year, names),
jc = expand.grid.jc(year, names),
tidyr = tidyr::expand_grid(year, names), check = FALSE, iterations = 10)
#> Warning: Some expressions had a GC in every iteration; so filtering is disabled.
my_benchmarking
#> # A tibble: 3 x 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 base 965.3ms 1.06s 0.938 701MB 2.35
#> 2 jc 13.1s 13.39s 0.0747 820MB 0.120
#> 3 tidyr 541.2ms 656.71ms 1.55 316MB 1.24
由reprex package (v2.0.0) 于 2021 年 8 月 22 日创建
很高兴了解这项任务是否可以更快地计算。
【问题讨论】:
-
永远不要像.data.frame(cbind(...))那样做。使用 data.frame(...)。
-
不知道
collapse有没有类似的功能,但是你可以试试data.table::CJ也就是fast。此外,使用更大的数据(例如V1 = 1:1e4和V2 = 1:1e4)发现base::expand.grid比tidyr::expand_grid快(亚秒级数据的基准测试很少相关)。 -
@Henrik,谢谢。我对您对基准测试时使用的数据类型的评论很感兴趣。我真实情况下的数据更类似于
babynames而不是1:1e4,因为我有字符数据而不是整数。 -
@Emman 感谢您的反馈。我理解我的评论是否会让人觉得不清楚/不相关。我的观点(如果有的话)更多的是关于用于计时的两个输入向量的组合总数,而不是字符与整数。很可能是我使用的尺寸不太能代表您的数据。干杯。
标签: r performance