【发布时间】:2020-03-05 23:05:56
【问题描述】:
我了解dplyr::if_else() 和基础ifelse() 之间的主要区别:前者对真假结果进行严格的类型检查。
但是我注意到另一个不同之处,我想知道这是预期的行为还是我做错了。
下面是一些简单的代码:
library(dplyr)
choose_number <- function() {
n <- readline("Choose a number between 1 and 4: ")
n <- as.integer(n)
if (between(n, 1, 4)) { return(n) }
else { return(NA_integer_) }
}
# base ifelse() - works perfectly
get_answer <- function(pick = FALSE, n = 2) {
n <- ifelse(pick, choose_number(), as.integer(n))
return(n)
}
# dplyr::if_else() - does not work in the same way
get_answer <- function(pick = FALSE, n = 2) {
n <- if_else(pick, choose_number(), as.integer(n))
return(n)
}
我希望 get_answer() 仅在 pick 参数为 TRUE 时调用 choose_number()。否则它应该只返回n 的值。上面代码中的基本ifelse() 可以完美地做到这一点,但dplyr 版本则不行。
dplyr 版本不会返回错误或警告,但是;它仍然调用choose_number(),但忽略结果,只返回n的默认值。
if_else、choose_number() 的 true 选项将返回一个整数,false 选项也是如此。所以在我看来if_else的类型检查功能应该是满足的。
【问题讨论】:
-
您在始终单一的向量上使用
if_else?这只是不必要的,为什么不使用if? -
不管您选择更简单的
if的理由是什么,您都不能依赖矢量化的ifelse或dplyr::if_else或data.table::fifelse来短路您的逻辑;假设无论您可能的外在条件如何,都将计算所有两个向量通常会更安全。 (事实上,基地ifelse正在这样做并不意味着if_else是错误的,imo。) -
@r2evans 因为又蠢又累!谢谢 - 我想我刚刚开始使用 dplyr (obv 我正在使用的代码更复杂 - 这只是一个抽象的例子)。我同意你关于条件满足的外在性的观点。我可以轻松地使用 if 和 else 重写。我想我只是对为什么它不能与 dplyr 版本一起使用感兴趣。除非您建议删除,否则我会留下问题。
-
基础
ifelse的某些事情错误(或很差或不一致)。其中一些是(imo)dplyr::if_else的推动力。 (举两个例子,试试ifelse(T,Sys.time(),Sys.time())和ifelse(T,1,"A")。第一个剥离属性,第二个从数据角度来看是不一致的。) -
我认为主要问题是为什么
dplyr::if_else在pick是FALSE时首先调用choose_number()。