R 操作/更新拟合模型时如何访问源数据

R 操作/更新拟合模型时如何访问源数据,r,functional-programming,regression,nse,R,Functional Programming,Regression,Nse,我试图编写一些函数来简化重新安装多个模型的过程,但发现这很痛苦,因为R在深入评估树时无法定位正确的数据。 尽管已经努力将公式环境存储在模型中,但我想确实没有办法明确地指向原始数据对象。 对于使用survfit拟合生存曲线来说,这变得更加困难,因为在survfit中没有存储任何对象 我真的需要每次都将数据/公式作为参数重新键入吗 例如: # model-fitting wrapper function fn <- function(fn_formula, fn_data) { lm(

我试图编写一些函数来简化重新安装多个模型的过程,但发现这很痛苦,因为R在深入评估树时无法定位正确的数据。 尽管已经努力将公式环境存储在模型中,但我想确实没有办法明确地指向原始数据对象。 对于使用survfit拟合生存曲线来说,这变得更加困难,因为在survfit中没有存储任何对象

我真的需要每次都将数据/公式作为参数重新键入吗

例如:

# model-fitting wrapper function
fn <- function(fn_formula, fn_data) {
    lm(formula = fn_formula, data = fn_data)
}
# specify exemplary data and formula
data <- data.frame(
    y = rnorm(100),
    x1 = rnorm(100),
    x2 = rnorm(100))
formula <- y ~ x1

# try to create and update the fit with different parameters
fn_fit <- fn(formula, data)
update(fn_fit, ~ x2)
# Error in is.data.frame(data) : object 'fn_data' not found
terms(fn_fit) %>% attr('.Environment')
# <environment: R_GlobalEnv>
terms(fn_fit$model) %>% attr('.Environment')
# <environment: R_GlobalEnv>
getCall(fn_fit)
# lm(formula = fn_formula, data = fn_data)

存储数据的变量应在lm和update的相同范围内,并具有相同的名称。不确定您真正想要完成的是什么,如果您想要一个创建签名的函数,您可以在全局环境中使用,您可以这样做

fn <- function(fn_formula, fn_data) {
  do.call("lm", list(fn_formula, data=substitute(fn_data)))
}
fn_fit <- fn(formula, data)
update(fn_fit, ~ x2)
否则,如果您真的想在本地函数作用域中捕获该变量,您可以创建一个帮助器,以便在正确的环境中进行更新

fn <- function(fn_formula, fn_data) {
  environment(fn_formula) <- environment()
  lm(formula = fn_formula, data = fn_data)
}

fn_update <- function(object, ...) {
  mc<-match.call(definition = update)
  mc[[1]] <- quote(update)
  eval(mc, envir=environment(terms(object)))
}

fn_fit <- fn(formula, data)
fn_update(fn_fit, ~x2)

存储数据的变量应在lm和update的相同范围内,并具有相同的名称。不确定您真正想要完成的是什么,如果您想要一个创建签名的函数,您可以在全局环境中使用,您可以这样做

fn <- function(fn_formula, fn_data) {
  do.call("lm", list(fn_formula, data=substitute(fn_data)))
}
fn_fit <- fn(formula, data)
update(fn_fit, ~ x2)
否则,如果您真的想在本地函数作用域中捕获该变量,您可以创建一个帮助器,以便在正确的环境中进行更新

fn <- function(fn_formula, fn_data) {
  environment(fn_formula) <- environment()
  lm(formula = fn_formula, data = fn_data)
}

fn_update <- function(object, ...) {
  mc<-match.call(definition = update)
  mc[[1]] <- quote(update)
  eval(mc, envir=environment(terms(object)))
}

fn_fit <- fn(formula, data)
fn_update(fn_fit, ~x2)

传递公式时,['model']子列表中存储的唯一项是需要的项

> names(fn_fit$model)
[1] "y"  "x1"
但在这个对象中没有任何名称“data”或“fn_data”。MrFlick第二个建议对调用帧树中的修改更具弹性:

> fn <- function(fn_formula, fn_data) {
+   do.call("lm", list(fn_formula, data=substitute(fn_data)))
+ }
> fn_fit <- fn(formula, data); rm(data)  # mess with the calling environment
> update(fn_fit, ~ x2)
Error in terms.formula(formula, data = data) : 
  'data' argument is of the wrong type
发生该错误是因为R解释器只找到名为data的函数;相反,如果您部署第二个选项,您将获得:

> data <- data.frame(
+     y = rnorm(100),
+     x1 = rnorm(100),
+     x2 = rnorm(100))

> fn <- function(fn_formula, fn_data) {
+   environment(fn_formula) <- environment()
+   lm(formula = fn_formula, data = fn_data)
+ }
> 
> fn_update <- function(object, ...) {
+   mc<-match.call(definition = update)
+   mc[[1]] <- quote(update)
+   eval(mc, envir=environment(terms(object)))
+ }

> 
> fn_fit <- fn(formula, data) ; rm(data)
> fn_update(fn_fit, ~x2)

Call:
lm(formula = y ~ x2, data = fn_data)

Coefficients:
(Intercept)           x2  
    0.01117     -0.13004  

传递公式时,['model']子列表中存储的唯一项是需要的项

> names(fn_fit$model)
[1] "y"  "x1"
但在这个对象中没有任何名称“data”或“fn_data”。MrFlick第二个建议对调用帧树中的修改更具弹性:

> fn <- function(fn_formula, fn_data) {
+   do.call("lm", list(fn_formula, data=substitute(fn_data)))
+ }
> fn_fit <- fn(formula, data); rm(data)  # mess with the calling environment
> update(fn_fit, ~ x2)
Error in terms.formula(formula, data = data) : 
  'data' argument is of the wrong type
发生该错误是因为R解释器只找到名为data的函数;相反,如果您部署第二个选项,您将获得:

> data <- data.frame(
+     y = rnorm(100),
+     x1 = rnorm(100),
+     x2 = rnorm(100))

> fn <- function(fn_formula, fn_data) {
+   environment(fn_formula) <- environment()
+   lm(formula = fn_formula, data = fn_data)
+ }
> 
> fn_update <- function(object, ...) {
+   mc<-match.call(definition = update)
+   mc[[1]] <- quote(update)
+   eval(mc, envir=environment(terms(object)))
+ }

> 
> fn_fit <- fn(formula, data) ; rm(data)
> fn_update(fn_fit, ~x2)

Call:
lm(formula = y ~ x2, data = fn_data)

Coefficients:
(Intercept)           x2  
    0.01117     -0.13004  

我知道可以通过非标准的求值和操作调用捕获相关变量,但我发现它不直观,因为它需要多个包装器,假设模型还没有使用标准调用进行拟合,并且高度依赖于实际的调用堆栈。我真正不明白的是维护y~x1调用的整个调用环境的意义,它不保证存储原始数据,但是可能包括在包装器函数的同一调用期间创建的其他内存消耗变量-有什么简单的解释吗?我知道可以通过非标准求值和操纵调用捕获相关变量,但我发现它不直观,因为它需要多个包装器,假设模型尚未使用标准调用进行拟合,并且高度依赖于实际调用堆栈。我真正不明白的是,维护y~x1调用的整个调用环境的意义,它不保证存储原始数据,但可能包括在包装函数的同一调用过程中创建的其他内存消耗变量——有什么简单的解释吗?