Имея объект lm
, мне нужно создать функцию на основе ее переменных, представленных в виде символьного вектора. Я попытался использовать комбинацию eval
и expr
для создания функции f
, которая в дальнейшем будет использоваться при оптимизации obj
и nlm
последней.
library(tidyverse)
df <- drop_na(airquality)
model <- lm(Ozone~. - Temp, data = df, x=TRUE, y=TRUE)
base_vars <- all.vars(formula(model)[-2])
k <- length(base_vars)
f <- function(base_df, x, y, parms) {
with(base_df, parms[1] +
eval(expr(paste(paste(paste0('parms[', 2:(k+1), ']'), base_vars, sep = '*'), collapse = '+'))) +
log(parms[k+2] * (x - parms[k+3] ^ 2)))
}
obj <- function(parms, y, x) mean((residuals(model) - f(df, x, y, parms))^2)
fit <- with(data, nlm(obj, c(0, 0, 0, 0, 0, 0, 0), y = e, x = x))
Но вызов f(model$x, df$Temp, model$y, c(0, 0, 0, 0, 0, 0, 0))
приводит к следующей ошибке:
Error in eval(substitute(expr), data, enclos = parent.frame()) :
numeric 'envir' arg not of length one
4.
eval(substitute(expr), data, enclos = parent.frame())
3.
with.default(base_df, parms[1] + eval(expr(paste(paste(paste0("parms[",
2:(k + 1), "]"), base_vars, sep = "*"), collapse = "+"))) +
log(parms[k + 2] * (x - parms[k + 3]^2)))
2.
with(base_df, parms[1] + eval(expr(paste(paste(paste0("parms[",
2:(k + 1), "]"), base_vars, sep = "*"), collapse = "+"))) +
log(parms[k + 2] * (x - parms[k + 3]^2)))
1.
f(model$x, df$Temp, model$y, c(0, 0, 0, 0, 0, 0, 0))
Я полагаю, что может быть конфликт между средой eval
и средой, подразумеваемой функцией with
, но не могу понять, почему. Любые идеи, как я могу создать пользовательскую функцию f
для переменных моделей?
Ожидаемый результат для f(model$x, df$Temp, model$y, c(0, 0, 0, 0, 0, 0, 0))
будет:
with(base_df, parms[1]+parms[2]*Solar.R+parms[3]*Wind+parms[4]*Temp+parms[5]*Month+
parms[6]*Day+log(parms[7] * (Temp - parms[8] ^ 2)))
, но для другой модели это может быть что-то вроде :
with(base_df,
parms[1]+parms[2]*var1+parms[3]*var2+log(parms[4]*(var3-parms[5]^2)))
, поэтому число переменных и параметров различается при каждом вызове.