R中ifelse()的奇怪behevior:什么时候评估值?[重复]

问题描述 投票:2回答:4

我有以下数据。

df = data.frame(
  stat = c('mean', 'var'),
  value = c(-9, 10))

假设我想取 "value "的平方 如果 "stat "是 "var",如果不是,就什么都不做。

df %>% 
  mutate(
   value = ifelse(stat=='var', sqrt(value), value))

我得到一个警告。

Warning message:
In sqrt(-9) : NaNs produced

为什么我会收到警告?值sqrt(-9)不应该被计算,因为'value'是 "平均值"。

r if-statement nan sqrt
4个回答
1
投票

根据 ifelse 文件

 If ‘yes’ or ‘no’ are too short, their elements are recycled.
 ‘yes’ will be evaluated if and only if any element of ‘test’ is
 true, and analogously for ‘no’.

你把这句话解释为,是或否将被绕过。元素 的方式。

然而,这似乎不是该文件的意思。它的意思是,除非 测试中的元素要么是真,要么是假,那么就会进行评价。

意思是说,只要你的测试中至少有一个true,至少有一个false,那么测试中的每个元素都会被预先计算出yes和no,只有在该元素被评估后,才会选择合适的响应。


1
投票

你的问题 "什么时候评估值?"的答案是:这取决于。

如果所有的元素都是 TRUE,那么第三个参数就根本不会被评估。如果所有的参数都是 FALSE,那么第二个参数将不会被评估。

然而,如果至少有一个 TRUE 和一个 FALSE那么他们都是 充分 评估。

ifelse(c(TRUE, TRUE), "good", stop("error"))
#> [1] "good" "good"

ifelse(c(FALSE, FALSE), "good", stop("error"))
#> Error in ifelse(c(FALSE, FALSE), "good", stop("error")) : error

ifelse(c(TRUE, FALSE), "good", stop("error"))
#> Error in ifelse(c(TRUE, FALSE), "good", stop("error")) : error

0
投票

你不需要一个包来做这件事。

df = data.frame(stat = c('mean', 'var'),
                value = c(-9, 10))
computed = df[df$stat == 'var','value'] %>% sqrt

如果你想让原始值被覆盖,那么就用第二行代替,

df[df$stat == 'var','value'] = df[df$stat == 'var','value'] %>% sqrt

如果你想使用本地的 ifelse 那么。

ifelse(df$stat =="var",sqrt(df$value),df$value)

0
投票

有人在评论中提到了这个问题。

在R中使用ifelse时,其中一个选项会产生NAs?

引用作者的话:"发生的情况是,我们对整个向量都进行计算,并根据测试条件替换'p'的值。对于sqrt,负值肯定会给出警告,并输出为NaN。虽然NaN元素没有出现在输出中,但警告已经打印出来了。这个警告是一个友好的警告,但可以用suppressWarnings来抑制"

© www.soinside.com 2019 - 2024. All rights reserved.