在R数据框中按条件修改行时为何出现NaNs produced警告?
解决
qlogis结合ifelse产生NaNs警告的问题 我在处理R语言的Data数据框时,想实现:当dv等于"B"时,把y列的值转成qlogis(y),但运行代码后出现了"NaNs produced"的警告。B组的y值是0.5和0.6,都在0到1之间,理论上不该产生NaN,想问下警告的原因。用的代码如下:
library(dplyr) Data = read.table(text= "id dv y 1 A 2 1 B .5 1 C 11 2 A 4 2 B .6 2 C 19", h=TRUE) mutate(Data, y = ifelse(dv=="B", qlogis(y), y))
警告原因
问题出在ifelse的计算逻辑上:它会先完整计算所有参数的表达式,再根据条件选择结果。也就是说,这里qlogis(y)会对整个y列执行计算,包括A、C组那些大于1的y值(比如2、11、4、19)。而qlogis()的定义域是(0,1),输入大于1或小于0时会返回NaN,所以计算过程中就产生了这些NaN,触发了警告——哪怕最后ifelse只保留了符合条件的B组结果,计算阶段的NaN已经生成了。
解决方案
用dplyr::case_when代替ifelse,它会按条件分支逐个计算,只对满足对应条件的行执行表达式,不会提前计算所有值:
mutate(Data, y = case_when( dv == "B" ~ qlogis(y), TRUE ~ y ))
或者也可以用基础R的行筛选方式修改,同样只处理目标行:
Data$y[Data$dv == "B"] <- qlogis(Data$y[Data$dv == "B"])
这两种方式都只会对dv=="B"的行调用qlogis(),不会碰其他超出定义域的y值,也就不会产生NaN警告了。
内容的提问来源于stack exchange,提问作者Simon Harmel
相关产品推荐
相关产品推荐

