gpt4 book ai didi

r - `if` 比 ifelse 快吗?

转载 作者:行者123 更新时间:2023-12-02 19:47:49 26 4
gpt4 key购买 nike

当我最近重读 Hadley 的 Advanced R 时,我注意到他在第 6 章中说 `if` 可以用作函数,例如
`if`(i == 1, print("是"), print("否"))
(如果您手上有实体书,则位于第 80 页)

我们知道 ifelse 很慢 ( Does ifelse really calculate both of its vectors every time? Is it slow? ),因为它评估所有参数。 `if` 会是一个很好的替代方案吗,因为 if 似乎只评估 TRUE 参数(这只是我的假设)?

<小时/>

更新:根据@Benjamin和@Roman的回答以及@Gregor和其他许多人的评论,ifelse似乎是矢量化计算的更好解决方案。我在这里接受@Benjamin的答案,因为它提供了更全面的比较和社区健康。然而,这两个答案(和评论)都值得一读。

最佳答案

这更多的是基于 Roman 答案的扩展评论,但我需要代码实用程序来阐述:

Roman 是正确的,ififelse 更快,但我的印象是 if 的速度提升并不是特别明显有趣的是,它不是可以通过矢量化轻松利用的东西。也就是说,仅当 cond/test 参数长度为 1 时,if 才比 ifelse 有利。

考虑以下函数,该函数在向量化 if 方面无疑是一次较弱的尝试,且不会产生评估 yesno 条件的副作用正如 ifelse 所做的那样。

ifelse2 <- function(test, yes, no){
result <- rep(NA, length(test))
for (i in seq_along(test)){
result[i] <- `if`(test[i], yes[i], no[i])
}
result
}

ifelse2a <- function(test, yes, no){
sapply(seq_along(test),
function(i) `if`(test[i], yes[i], no[i]))
}

ifelse3 <- function(test, yes, no){
result <- rep(NA, length(test))
logic <- test
result[logic] <- yes[logic]
result[!logic] <- no[!logic]
result
}


set.seed(pi)
x <- rnorm(1000)

library(microbenchmark)
microbenchmark(
standard = ifelse(x < 0, x^2, x),
modified = ifelse2(x < 0, x^2, x),
modified_apply = ifelse2a(x < 0, x^2, x),
third = ifelse3(x < 0, x^2, x),
fourth = c(x, x^2)[1L + ( x < 0 )],
fourth_modified = c(x, x^2)[seq_along(x) + length(x) * (x < 0)]
)

Unit: microseconds
expr min lq mean median uq max neval cld
standard 52.198 56.011 97.54633 58.357 68.7675 1707.291 100 ab
modified 91.787 93.254 131.34023 94.133 98.3850 3601.967 100 b
modified_apply 645.146 653.797 718.20309 661.568 676.0840 3703.138 100 c
third 20.528 22.873 76.29753 25.513 27.4190 3294.350 100 ab
fourth 15.249 16.129 19.10237 16.715 20.9675 43.695 100 a
fourth_modified 19.061 19.941 22.66834 20.528 22.4335 40.468 100 a

一些编辑:感谢弗兰克和理查德·斯克里文注意到我的缺点。

如您所见,将向量分解为适合传递给 if 的过程是一个耗时的过程,最终比运行 ifelse 慢(这可能就是为什么没有人费心实现我的解决方案的原因)。

如果您确实迫切需要提高速度,可以使用上面的 ifelse3 方法。或者更好的是,弗兰克的不太明显*但出色的解决方案。

  • 我所说的“不太明显”是指,我花了两秒钟才意识到他做了什么。根据下面 nicola 的评论,请注意,这仅在 yesno 长度为 1 时有效,否则您将需要坚持使用 ifelse3

关于r - `if` 比 ifelse 快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34005423/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com