【问题标题】:data.table fcase versus dplyr case_whendata.table fcase 与 dplyr case_when
【发布时间】:2020-11-23 10:49:27
【问题描述】:

以下代码在使用 fcase 评估该行时会引发错误。

library(data.table)
library(dplyr)
tbl.test <- data.table(x = 0.5*(1:2))
tbl.test[, .(fcase(x < 1, x+1, 
                 default = x))]

tbl.test[, .(case_when(x < 1 ~ x+1, 
                        TRUE ~ x)
             )]

当我以这种方式使用 case_when 时(对于大多数复杂的东西..),我想切换到 fcase,希望能真正提高性能..

有没有人看到这种 fcase 用法的魔鬼藏在哪里? 关键是我不能将表格的一列用作 fcase 的默认值 ..

【问题讨论】:

标签: r dplyr data.table


【解决方案1】:

您没有明确提出问题,但我假设您想知道是否可以通过 fcase() 使用矢量化默认值。一种方法是构造一个与其他条件等长的TRUEs 向量作为最后一个元素,类似于case_when() 的工作方式:

library(data.table)
library(dplyr)

set.seed(123)

tbl.test <- data.table(x = rnorm(1e6))

bench::mark(
  fcase = tbl.test[, .(fcase(x < 1, x + 1, rep_len(TRUE, length(x)), x))],
  case_when = tbl.test[, .(case_when(x < 1 ~ x + 1, TRUE ~ x))]
)
#> Warning: Some expressions had a GC in every iteration; so filtering is disabled.
#> # A tibble: 2 x 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 fcase        16.5ms   24.3ms     33.3     36.1MB     43.1
#> 2 case_when   146.4ms  147.9ms      6.60   129.9MB     28.1

【讨论】:

  • 粘贴的基准结果可能会产生误导。您可以尝试以通用单位表示度量,或者只使用微基准。
  • @jangorecki 我不认为有人误读单位的可能性非常高,但我已经更新了结果。一般来说,我更喜欢 bench::mark() 而不是 microbenchmark,因为它还报告内存使用情况并检查结果是否匹配。我可以将time_units 设置为相等,但是没有用于控制内存单​​元的选项(这可能是一个有用的功能请求),所以我只是用更小的向量更新了结果以使两个单元匹配。
猜你喜欢
  • 2019-04-01
  • 2022-11-09
  • 2020-09-16
  • 2021-01-19
  • 1970-01-01
  • 1970-01-01
  • 2018-05-31
  • 1970-01-01
相关资源
最近更新 更多