gpt4 book ai didi

r - eval(expr, envir, enclos) 错误 : could not find function - Nested Functions & Environments

转载 作者:行者123 更新时间:2023-12-02 15:26:36 26 4
gpt4 key购买 nike

下面显示的 R 代码是一个最小的工作示例,用于重现我不能说我理解的错误。运行脚本应该会产生错误,Error in eval(expr, envir, enclos) : could not find function "fitModel" .在 environments 上阅读一两件事后我想我明白为什么在这种情况下会发生这种情况,“fitModel”没有在“obscureFunction”的执行环境中定义。我通过对“myFormula”进行以下更改来修复此问题: myFormula <- "y ~ eval(fitModel(x, a), envir = environment(fitModel))"

当在“obscureFunction”的调用环境中找不到函数时,我不明白如何在“fitModel”的环境中评估“fitModel”,换句话说,我不明白为什么这段代码改变作品。我也不明白为什么如果“topFunction”的主体在不调用它的情况下运行,原始代码就可以正常工作,即如果我们在 R_GlobalEnv 中定义“fitModel”和“obscureFunction”并从控制台调用“obscureFunction”。

## Minimum Working Example to reproduce error
rm(list = ls())
library(minpack.lm)

topFunction <- function(){

fitModel <- function(x, a){
exp(-a * x)
}

## Create a function to use with lapply()
obscureFunction <- function(){

x <- seq(-1, 1, 0.01)
y <- exp(-0.5 * x)
Data <- data.frame(x, y)

init <- c(a = 1)
myFormula <- "y ~ fitModel(x, a)"
myFormula <- as.formula(myFormula)
nlsOutput <- nlsLM(formula = myFormula, start = init, data = Data)

return(nlsOutput)

}

## Function call
obscureFunction()

## Other calculations done with fitModel()
}

topFunction()

最佳答案

嗯,这里有两个问题。第一种是使用字符串作为公式。最好用

myFormula <- y ~ fitModel(x, a)

原因是公式会捕获它们的环境,而字符串不会。 (正如@BridieG 所指出的,as.formula() 将捕获环境;我在阅读代码时跳过了该行。我仍然认为直接创建公式更好。)环境使查找公式中使用的函数变得更加容易。因此,如果您使用的是 lm() 而不是 nlsLM,这将适用于这两个更改

# myFormula <- "y ~ fitModel(x, a)"  ... becomes
myFormula <- y ~ fitModel(x, 1)

#nlsOutput <- nlsLM(formula = myFormula, start = init, data = Data) ...becomes
nlsOutput <- lm(formula = myFormula, data = Data)

这适用于公式语法(未加引号的变量名称)而不是字符串,因为公式可以捕获环境。

至少它应该是这样的。程序包作者可以随意评估公式,nlsLM() 函数的作者决定忽略分配给公式的环境。他们在 nlsLM()

中的这个函数中这样做
FCT <- function(par) {
mf[m] <- par
rhs <- eval(formula[[3L]], envir = mf)
res <- lhs - rhs
res <- .swts * res
res
}

所以这是第二个问题。在这里,他们在 mf 对象中强制执行评估,该对象是由数据的协变量和参数估计组成的 data.frame。如果写成

rhs <- eval(formula[[3L]], envir = mf, environment(formula))

它会奏效的。这基本上就是 model.frame()lm() 中所做的,这使得它可以工作。我们可以制作我们自己的函数的“更正”版本

# tested with minpack.lm_1.1-8
nlsLM2<-nlsLM
body(nlsLM2)[[27]][[3]][[3]][[3]]<-quote(rhs<-eval(formula[[3L]], envir = mf, environment(formula)))

然后进行这些替换

# myFormula <- "y ~ fitModel(x, a)"  ... becomes
myFormula <- y ~ fitModel(x, a)

#nlsOutput <- nlsLM(formula = myFormula, start = init, data = Data) ...becomes
nlsOutput <- nlsLM2(formula = myFormula, start = init, data = Data)

它工作工作并返回

Nonlinear regression model
model: y ~ fitModel(x, a)
data: Data
a
0.5
residual sum-of-squares: 0

Number of iterations to convergence: 5
Achieved convergence tolerance: 1.49e-08

因此,关于所有 R 函数如何处理环境和作用域,您并没有太多可说的。此行为对于 nlsLM() 作者决定评估其参数的方式而言是独一无二的。

关于r - eval(expr, envir, enclos) 错误 : could not find function - Nested Functions & Environments,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30089698/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com