r-内部函数从外部函数调用并导致错误



我使用的是库中的一个函数在另一个函数中跳转。有问题的跳跃函数的最后两行是:

rval$call <- sys.call(sys.parent())
rval

这显然导致对外部函数的调用被传递给rval$call。稍后需要对regsubsets函数的实际调用作为参数

下面的例子说明:

library(leaps)
#Create some sample data to perform a regression on
inda <- rnorm(100)
indb <- rnorm(100)
dep <- 2 + 0.1*inda + 0.2*indb + rnorm(100, sd = 0.3)
dfk <- data.frame(dep=dep, inda = inda, indb = indb)
#Create some arbitrary outer function
test <-  function(dependent, data){
best.fit <- regsubsets(as.formula(paste0(dependent, " ~ .")), data = data, nvmax = 2)
return(best.fit)
}
#Call outer function
best <- test("dep", dfk)
best$call #Returns "test("dep", dfk)"

因此,best$call将包含对外部函数(test)的调用,而不是对内部函数(regsubsets)的调用。由于改变内部功能并不是一个真正的选择,有什么方法可以避免这个问题吗?

编辑:

解决问题的一种方法可能是这样的:

test <-  function(dependent, data){
thecall <- 'regsubsets(as.formula(paste0(dependent, " ~ .")), data = data, nvmax = 2)'
best.fit <- eval(parse(text = thecall))
#best.fit$call <- [some transformation of thecall
return(best.fit)
}

第2版:我需要访问$call内部的内容的原因是,它是我从静态学习导论:中复制的预测函数中所需要的

predict.regsubsets <- function(regsubset_model, newdata, id, ...){
form <- as.formula(regsubset_model$call[[2]])
mat <- model.matrix(form, newdata)
coefi <- coef(regsubset_model, id = id)
xvars <- names(coefi)
mat[, xvars] %*% coefi
}

在第二行中,它使用$call

我还不完全清楚如何使用它,但在test函数的情况下,您可以编写以下代码:

test = function (dependent, data) {
regsubsets_call = bquote(regsubsets(.(as.formula(paste0(dependent, " ~ ."))),
data = .(substitute(data)), nvmax = 2))
best_fit = eval(regsubsets_call)
best_fit$call = regsubsets_call
best_fit
}

然而,结果可能无法与包提供的下游函数一起使用(不过,实际上,它可能会起作用;我猜summary.regsubsets只使用它来打印调用)。

这是怎么回事

CCD_ 8构建未赋值的R表达式;它类似于quote,但它允许您对值进行插值(与substitute类似)。substitute(data)意味着,它不是将实际的data.frame放入调用中(这将导致非常笨拙的输出),而是将用户传递给test的变量名(或表达式)放入调用中。因此,如果用户将其称为test('mpg', mtcars),那么得到的表达式将是

regsubsets(mpg ~ ., data = mtcars, nvmax = 2)    

然后(a)经由eval来评估所得到的调用对象,并且(b)将其存储在所得到的$call中。

顺便说一句,公式可以(就我而言,应该)以同样的方式构建;无需解析字符串:

as.formula(bquote(.(as.name(dependent)) ~ .))

综合起来,整个表达式将变成:

formula = as.formula(bquote(.(as.name(dependent)) ~ .))
regsubsets_call = bquote(regsubsets(.(formula), data = .(substitute(data)), nvmax = 2))

最新更新