data.table fcase 与 dplyr case_when

MrS*_*ton 4 r dplyr data.table

使用 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)
             )]

Run Code Online (Sandbox Code Playgroud)

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

有谁知道 fcase 的这种用法到底隐藏在哪里吗?关键是我不能使用表的列作为 fcase 的默认值..

Mik*_*ila 10

您没有明确提出问题,但我假设您想知道是否有办法将矢量化默认值与fcase(). 一种方法是构造一个TRUE与其他条件长度相等的 s 向量作为最后一个元素,类似于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
Run Code Online (Sandbox Code Playgroud)

  • @jangorecki 我不认为有人误读单位的可能性非常高,但我已经更新了结果。一般来说,我更喜欢 `bench::mark()` 而不是微基准测试,因为它还报告内存使用情况并检查结果是否匹配。我可以将“time_units”设置为相等,但没有控制内存单​​元的选项(这可能是一个有用的功能请求),因此我只是用较小的向量更新结果以使两个单元匹配。 (5认同)