使用R的bench包测试tidytable时出现结果不匹配错误
问题
我尝试把tidytable包加入性能测试的基准测试中,在bench::mark里添加tidytable相关测试项后,弹出错误:
Error: Each result must equal the first result:
t_tidytabledoes not equalt_dplyr
对应的R代码如下:
library(dtplyr) library(tidyverse) library(profvis) library(bench) library(vctrs) #> #> Attaching package: 'vctrs' #> The following object is masked from 'package:dplyr': #> #> data_frame #> The following object is masked from 'package:tibble': #> #> data_frame library(data.table) #> #> Attaching package: 'data.table' #> The following objects are masked from 'package:lubridate': #> #> hour, isoweek, mday, minute, month, quarter, second, wday, week, #> yday, year #> The following objects are masked from 'package:dplyr': #> #> between, first, last #> The following object is masked from 'package:purrr': #> #> transpose mtcars_tbl = tibble::as_tibble(mtcars, rownames = "make_model") res = bench::mark( t_dplyr = dplyr::filter(mtcars_tbl, hp > 100), t_vctr = vec_slice(mtcars_tbl, mtcars_tbl$hp > 100), t_datatable = mtcars_tbl[mtcars_tbl$hp > 100, ] ) %>% select(expression, median) res = bench::mark( t_tidytable = tidytable::filter(mtcars_tbl, hp > 100), t_dplyr = dplyr::filter(mtcars_tbl, hp > 100), t_vctr = vec_slice(mtcars_tbl, mtcars_tbl$hp > 100), t_datatable = mtcars_tbl[mtcars_tbl$hp > 100, ] ) %>% select(expression, median) #> Error: Each result must equal the first result: #> `t_tidytable` does not equal `t_dplyr`
Created on 2023-04-29 with reprex v2.0.2
解决办法
这个错误本质是bench::mark默认会强制校验所有测试项的输出结果和第一个结果完全一致,但tidytable返回的是tidytable类对象,dplyr返回的是tibble类对象,二者的对象类型不同,导致校验失败。
有两种简单的解决途径:
1. 跳过一致性检查
直接在bench::mark里加check = FALSE参数,关闭结果相等性校验:
res = bench::mark( t_tidytable = tidytable::filter(mtcars_tbl, hp > 100), t_dplyr = dplyr::filter(mtcars_tbl, hp > 100), t_vctr = vec_slice(mtcars_tbl, mtcars_tbl$hp > 100), t_datatable = mtcars_tbl[mtcars_tbl$hp > 100, ], check = FALSE # 新增参数 ) %>% select(expression, median)
2. 统一输出对象类型
把不同方法返回的对象转换成同一种类型,比如把tidytable的结果转成tibble,或者反过来:
- 将tidytable结果转为tibble:
res = bench::mark( t_tidytable = as_tibble(tidytable::filter(mtcars_tbl, hp > 100)), t_dplyr = dplyr::filter(mtcars_tbl, hp > 100), t_vctr = vec_slice(mtcars_tbl, mtcars_tbl$hp > 100), t_datatable = mtcars_tbl[mtcars_tbl$hp > 100, ] ) %>% select(expression, median)
- 或者将所有结果转为tidytable:
res = bench::mark( t_tidytable = tidytable::filter(mtcars_tbl, hp > 100), t_dplyr = as_tidytable(dplyr::filter(mtcars_tbl, hp > 100)), t_vctr = as_tidytable(vec_slice(mtcars_tbl, mtcars_tbl$hp > 100)), t_datatable = as_tidytable(mtcars_tbl[mtcars_tbl$hp > 100, ]) ) %>% select(expression, median)
额外验证
如果担心数据内容不一致,可以用all.equal()手动检查,忽略对象属性差异只看数据:
all.equal( tidytable::filter(mtcars_tbl, hp > 100), dplyr::filter(mtcars_tbl, hp > 100), check.attributes = FALSE )
内容的提问来源于stack exchange,提问作者abalter
相关产品推荐
相关产品推荐

