"object not found" 函数内:nlmer 版本
"object not found" within function: nlmer edition
在过去的几个小时里,我在这里发现了几个关于 R 脚本的问题,该脚本在函数之外工作得很好,但是 returns 一次参数出现 "object not found" 错误代码被重构以包含函数。不幸的是,这些错误的解决方案似乎是高度特定于程序包和上下文的,因此我不得不将我自己的特定于 nlmer 的问题投入到争论中。
总结:我想 运行 一个 nlmer 模型好几次,但每次的模型规格都略有不同。我已确保该模型在任何函数之外都按照指定的方式工作。我写了一个函数,它接受一个 data.table 和一个公式(以字符串形式)和 运行 模型,但是它 returns 一个错误,我的模型公式是 "not found",即使 'model_formula' 变量肯定在函数的命名空间中。
示例:
# set up toy dataset
data <- data.table(patient_id=c(rep("pat_1", 10), rep("pat_2", 10), rep("pat_3", 10)),
agesero=c(rep(25,10), rep(19, 10), rep(34, 10)))
data$row <- as.numeric(rownames(data))
data[, variable:= ifelse(row%%10==0, "observed_survival", "vl")]
data[, M_visit_time:= ifelse(variable=="vl", row/6 + 0.25, 0)]
data[, value:= ifelse(variable=="vl", 3 + exp(-4*M_visit_time), row/10 + 2)]
data[, M_agesero:= ifelse(variable=="vl", agesero, 0)]
data[, D_intercept:= ifelse(variable=="observed_survival", 1, 0)]
data[, D_agesero:= ifelse(variable=="observed_survival", agesero, 0)]
data[, row:=NULL]
example_formula <- "value~ModelGradient(time=M_visit_time,b0,b2,b3)~M_agesero + D_intercept + D_agesero + (b0|patient_id)"
#this works, outside of a function:
Model<- ~b0+b2*exp(-b3*time)
ModelGradient<-deriv(Model,namevec=c("b0","b2","b3"),
function.arg=c("time","b0","b2","b3"))
out<-nlmer(as.formula(example_formula), data=data,
start = c(b0=3,b2=1,b3=4),
control=nlmerControl(optimizer="bobyqa", optCtrl=list(maxfun=200000)))
#but when I write a function:
run_nonlin<- function(model_formula, data){
Model<- ~b0+b2*exp(-b3*time)
ModelGradient<-deriv(Model,namevec=c("b0","b2","b3"),
function.arg=c("time","b0","b2","b3"))
print(paste("hello I am the model formula and I exist in this namespace! I am:",
model_formula))
out<-nlmer(as.formula(model_formula), data=data,
start = c(b0=3,b2=1,b3=4),
control=nlmerControl(optimizer="bobyqa",
optCtrl=list(maxfun=200000)))
return(out)
}
#and call:
function_output <- run_nonlin(model_formula=example_formula, data=data)
# I get the error:
# Error in as.formula(model_formula) : object 'model_formula' not found
作为旁注,我在 glmer 中做了与此非常相似的事情,没有问题。
非常感谢任何建议。
(编辑以包含错误消息)
似乎 nlmer
解析传递给函数的公式的方式很奇怪。您显然不能传递未在全局环境中定义的变量。这似乎是因为 nlformula
在作为公式传递的未计算符号上调用 as.formula
。这意味着词法范围用于解析符号,因此它在 stats
命名空间中搜索 model_formula
,然后在全局环境中搜索,而不是在您的函数定义的范围中。
解决方法是评估该参数,然后通过 do.call()
传递该值,例如
run_nonlin<- function(model_formula, data){
Model<- ~b0+b2*exp(-b3*time)
ModelGradient<-deriv(Model,namevec=c("b0","b2","b3"),
function.arg=c("time","b0","b2","b3"))
out <- do.call('nlmer', list(as.formula(model_formula),
data=quote(data),
start = c(b0=3,b2=1,b3=4),
control=nlmerControl(optimizer="bobyqa",
optCtrl=list(maxfun=200000))))
return(out)
}
在过去的几个小时里,我在这里发现了几个关于 R 脚本的问题,该脚本在函数之外工作得很好,但是 returns 一次参数出现 "object not found" 错误代码被重构以包含函数。不幸的是,这些错误的解决方案似乎是高度特定于程序包和上下文的,因此我不得不将我自己的特定于 nlmer 的问题投入到争论中。
总结:我想 运行 一个 nlmer 模型好几次,但每次的模型规格都略有不同。我已确保该模型在任何函数之外都按照指定的方式工作。我写了一个函数,它接受一个 data.table 和一个公式(以字符串形式)和 运行 模型,但是它 returns 一个错误,我的模型公式是 "not found",即使 'model_formula' 变量肯定在函数的命名空间中。
示例:
# set up toy dataset
data <- data.table(patient_id=c(rep("pat_1", 10), rep("pat_2", 10), rep("pat_3", 10)),
agesero=c(rep(25,10), rep(19, 10), rep(34, 10)))
data$row <- as.numeric(rownames(data))
data[, variable:= ifelse(row%%10==0, "observed_survival", "vl")]
data[, M_visit_time:= ifelse(variable=="vl", row/6 + 0.25, 0)]
data[, value:= ifelse(variable=="vl", 3 + exp(-4*M_visit_time), row/10 + 2)]
data[, M_agesero:= ifelse(variable=="vl", agesero, 0)]
data[, D_intercept:= ifelse(variable=="observed_survival", 1, 0)]
data[, D_agesero:= ifelse(variable=="observed_survival", agesero, 0)]
data[, row:=NULL]
example_formula <- "value~ModelGradient(time=M_visit_time,b0,b2,b3)~M_agesero + D_intercept + D_agesero + (b0|patient_id)"
#this works, outside of a function:
Model<- ~b0+b2*exp(-b3*time)
ModelGradient<-deriv(Model,namevec=c("b0","b2","b3"),
function.arg=c("time","b0","b2","b3"))
out<-nlmer(as.formula(example_formula), data=data,
start = c(b0=3,b2=1,b3=4),
control=nlmerControl(optimizer="bobyqa", optCtrl=list(maxfun=200000)))
#but when I write a function:
run_nonlin<- function(model_formula, data){
Model<- ~b0+b2*exp(-b3*time)
ModelGradient<-deriv(Model,namevec=c("b0","b2","b3"),
function.arg=c("time","b0","b2","b3"))
print(paste("hello I am the model formula and I exist in this namespace! I am:",
model_formula))
out<-nlmer(as.formula(model_formula), data=data,
start = c(b0=3,b2=1,b3=4),
control=nlmerControl(optimizer="bobyqa",
optCtrl=list(maxfun=200000)))
return(out)
}
#and call:
function_output <- run_nonlin(model_formula=example_formula, data=data)
# I get the error:
# Error in as.formula(model_formula) : object 'model_formula' not found
作为旁注,我在 glmer 中做了与此非常相似的事情,没有问题。
非常感谢任何建议。
(编辑以包含错误消息)
似乎 nlmer
解析传递给函数的公式的方式很奇怪。您显然不能传递未在全局环境中定义的变量。这似乎是因为 nlformula
在作为公式传递的未计算符号上调用 as.formula
。这意味着词法范围用于解析符号,因此它在 stats
命名空间中搜索 model_formula
,然后在全局环境中搜索,而不是在您的函数定义的范围中。
解决方法是评估该参数,然后通过 do.call()
传递该值,例如
run_nonlin<- function(model_formula, data){
Model<- ~b0+b2*exp(-b3*time)
ModelGradient<-deriv(Model,namevec=c("b0","b2","b3"),
function.arg=c("time","b0","b2","b3"))
out <- do.call('nlmer', list(as.formula(model_formula),
data=quote(data),
start = c(b0=3,b2=1,b3=4),
control=nlmerControl(optimizer="bobyqa",
optCtrl=list(maxfun=200000))))
return(out)
}