【问题标题】:dplyr::if_else() doesn't run a function correctly as an outcome, whereas base ifelse() does perfectly. Why?dplyr::if_else() 没有正确运行函数作为结果,而基本 ifelse() 则完美。为什么?
【发布时间】: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_elsechoose_number()true 选项将返回一个整数,false 选项也是如此。所以在我看来if_else的类型检查功能应该是满足的。

【问题讨论】:

  • 您在始终单一的向量上使用if_else?这只是不必要的,为什么不使用if
  • 不管您选择更简单的if 的理由是什么,您都不能依赖矢量化的ifelsedplyr::if_elsedata.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_elsepickFALSE 时首先调用choose_number()

标签: r dplyr


【解决方案1】:

原因是因为dplyr::if_else()ifelse() 更严格。

dplyr::if_else() 需要检查truefalse 是否是相同的类型和类才能执行。由于choose_number() 是一个函数,因此需要先解决它才能进行此类检查,因此即使您的condition 为FALSE,它也会运行。

更多信息在这里: https://rdrr.io/cran/dplyr/man/if_else.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-11
    • 2017-03-14
    • 2019-03-12
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多