我试图编写一些函数来简化重新设计多个模型,但发现它很痛苦,因为当R更深入到评估树时,R无法找到正确的data
。
尽管已经努力将公式环境存储在模型中,但我认为没有办法毫不含糊地指向原始数据对象。
使用survfit
拟合生存曲线变得更加困难,其中没有terms
对象存储在其中。
我是否真的需要每次都重新输入数据/公式作为参数?
示例:
# 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)
答案 0 :(得分:3)
存储数据的变量应该与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)
答案 1 :(得分:1)
当您通过公式时,[&#39; model&#39;]子列表中存储的唯一项目就是那些需要的项目。
> names(fn_fit$model)
[1] "y" "x1"
但是,没有任何一个名称的数据&#39;或者&#39; fn_data&#39;在那个对象。 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