【问题标题】:Evaluation in dplyr::case_when()dplyr::case_when() 中的评估
【发布时间】:2018-05-31 09:20:05
【问题描述】:

遵循dplyr::case_when() 文档中给出的示例:

x <- 1:50
case_when(x %% 35 == 0 ~ "fizz buzz",
          x %% 5 == 0 ~ "fizz",
          x %% 7 == 0 ~ "buzz",
          TRUE ~ as.character(x))

我希望数字 35 会产生 "buzz" 但它会产生 "fizz buzz"

我的理由是case_when() 会逐一评估所有语句,无论前一个语句是否为真(因为它确实评估了最后一个语句 TRUE ~ as.character(x))并且35 %% 7 显然是 0。

我错过了什么?

【问题讨论】:

  • 语句按顺序求值,任何与第一个语句匹配的都会得到第一个结果,不会被后面的结果覆盖。
  • 我仍然对为什么最后一条语句 TRUE ~ as.character(x) 被评估感到困惑。
  • x 值不能被 35、5 或 7 整除 - 因此在处理前 3 个语句后仍有值需要处理。如果您仍然感到困惑,您可以尝试更详细地解释为什么您认为应该发生其他事情吗?
  • @Marius 我对这个 TRUE ~ as.character(x) 感到困惑,因为在我看来它适用于整个 x。我知道这是一种拥有“其他”条款的方式。
  • 它适用于整个x 除了,其他情况胜出。当多个案例为真时,第一个列出“获胜”。所以当使用TRUE ~时,重要的是它被列在最后,否则它之后列出的案例永远不会赢。

标签: r dplyr case-when


【解决方案1】:

case_when() 会一一评估所有语句,无论前一个语句是否为真(因为它确实评估 TRUE ~ as.character(x) 是最后一个语句)

这是误导,case_when() 的输出是基于第一个正确的陈述。

TRUE ~ as.character(x) 表示如果 x 不能被 5 或 7 整除,则 x 将作为字符串返回,即对于 x = 5,将返回 "5"。

如果 x 可以被 5 或 7 整除,casewhen() 不会评估后续情况。 “fizz”和“buzz”没有传递给as.character(x),它们也不必传递,因为它们已经是字符串。

【讨论】:

  • 你说得对,case_when 从第一个真实案例中获取值,但实际上后续案例仍在评估中,可以看出它们是否有副作用。例如,这将返回 "foo",但您仍然会收到来自第二种情况的警告:case_when(TRUE ~ "foo", TRUE ~ warning("bar"))
  • 同样,这将返回2,但之后x3,因为它增加了两次:x &lt;- 1; case_when(TRUE ~ (x &lt;- x + 1), TRUE ~ (x &lt;- x + 1))。 (需要说明的是,我不建议在实际代码中使用这样的副作用——这只是一个示例。)
  • @TimGoodman 谢谢,这是一个很好的观点,我应该知道的。我经常被设置为 TRUE ~ NA,而不是适当的 NA_[class]_,即使在我认为 TRUE ~ 从未被评估的情况下收到错误,我也没有加入这些点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
  • 2020-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多