R函数未对stan_glm()输入触发停止:原因排查求助
问题原因与解决方案
首先,你的代码没有按预期工作,主要有三个核心问题:
1. 类型不匹配的错误比较
fit$call[1]返回的是符号(symbol/name)类型的对象,而你直接把它和字符串"lm()"、"aov()"比较。在R中,不同类型的对象做相等性判断时,行为和你预期的不一样——比如quote(stan_glm) != "lm()"确实会返回TRUE,但这里更关键的是第二个问题:
2. 错误的字符串匹配格式
fit$call[1]对应的是不带括号的函数名(比如lm、aov),但你用了带括号的字符串"lm()"、"aov()"做比较。这意味着即使是合法的lm或aov对象,你的代码也会错误触发stop()——比如你输入fit2(aov对象)时,fit2$call[1]是符号aov,和"aov()"比较结果为TRUE,所以条件成立,执行stop(),这完全和你的初衷相反!
3. stan_glm对象的命名空间问题
rstanarm::stan_glm返回的stanreg对象,其call元素中的函数名是带命名空间的(比如rstanarm::stan_glm),虽然你的比较逻辑理论上应该触发stop(),但因为前面的格式错误,导致整个判断逻辑混乱,最终出现不符合预期的结果。
修正后的函数
我们需要先把函数名转换为纯字符串,去掉命名空间前缀,再判断是否属于允许的函数列表:
bb <- function(fit = NA){ if(!any(is.na(fit))){ # 提取函数名,处理带命名空间的情况 func_name <- deparse(fit$call[[1]]) # 移除命名空间前缀(比如rstanarm::) func_name <- sub(".*::", "", func_name) # 判断是否是允许的函数 if(!(func_name %in% c("lm", "aov"))){ stop("Error: Input must be an object generated by lm() or aov()") } else { "OK" } } }
测试结果:
bb(fit2):返回"OK"(符合预期)bb(fit3):触发stop()(符合预期)bb(fit4):触发stop()(符合预期)bb(lm(mpg~wt, mtcars)):返回"OK"(符合预期)
内容的提问来源于stack exchange,提问作者rnorouzian
相关产品推荐
相关产品推荐

