#r
#r
Вопрос:
У меня есть несколько фреймов данных, и я хотел бы оценить (несколько) разных моделей для каждого. MWE
df1 <- data.frame(A3 = c(-5, 5, 1),
B3 = c(0, 10, 1))
df2 <- data.frame(A4 = c(5, 15, 1))
B4 = c(10, 20, 1))
myfun <- function(arg1, arg2){ # arg1 =1 or 2
if (arg2 == 1){
eqn <- paste0("A", arg1 2) ~ paste0("B", arg1 2) I(as.name(paste0("B", arg1 2))^2)
} else {
eqn <- paste0("A", arg1 2) ~ paste0("B", arg1 2) I(as.name(paste0("B", arg1 2))^2) I(as.name(paste0("B", arg1 2))^3)
}
return (lm(formula = eqn, data = eval(as.name(paste0("df", arg1)))
)
)
}
Например, если я запускаю myfun(1,2)
, я хотел бы получить lm(A4 ~ B4 I(B4^2) I(B4^3), data = df2)
. Но что бы я ни пытался, я получаю следующее сообщение об ошибке Error in (paste0("B", arg1 2))^2 : non-numeric argument to binary operator
. Из того, что я прочитал ?I
, я полагаю, это потому, что R изолирует все, что передается I()
, поэтому он не понимает, что я пытаюсь преобразовать переменную: это то, что происходит, и это что-то, что я могу исправить? Кроме того, есть ли лучший способ быстро оценить несколько моделей? Все подобные вопросы, которые я нашел, использовались одинаково data.frame
для разных моделей, в то время как я должен учитывать переменные ответа (и предиктора), поступающие из разных фреймов данных для разных моделей.
Ответ №1:
Может быть, это то, что вы ищете:
Проблема в том, что вы выполняете математическую операцию над строкой, то есть (paste0("B", arg1 2))^2
пытаетесь возвести строку в квадрат, вот почему вы получаете ошибку. Inytead вы можете просто склеить формулу в виде строки и преобразовать ее в формулу с помощью as.formula
:
df1 <- data.frame(A3 = c(-5, 5, 1),
B3 = c(0, 10, 1))
df2 <- data.frame(A4 = c(5, 15, 1))
B4 = c(10, 20, 1)
myfun <- function(arg1, arg2){ # arg1 =1 or 2
if (arg2 == 1){
eqn <- paste0("A", arg1 2, " ~ B", arg1 2," I(B", arg1 2, "^2)")
} else {
eqn <- paste0("A", arg1 2, " ~ B", arg1 2," I(B", arg1 2, "^2) I(B", arg1 2, "^3)")
}
return (lm(formula = as.formula(eqn), data = eval(as.name(paste0("df", arg1)))
)
)
}
myfun(2, 1)
#>
#> Call:
#> lm(formula = as.formula(eqn), data = eval(as.name(paste0("df",
#> arg1))))
#>
#> Coefficients:
#> (Intercept) B4 I(B4^2)
#> 0.84795 0.12281 0.02924
Ответ №2:
Также можно создать formula
с помощью glue
myfun <- function(arg1, arg2){
eqn <- switch(arg2,
`1` = glue::glue("A{arg1 2}~ B{arg1 2} I(B{arg1 2}^2)"),
glue::glue("A{arg1 2}~ B{arg1 2}",
" I(B{arg1 2}^2) I(B{arg1 2}^3)")
)
model <- lm(eqn, data = get(paste0('df', arg1), envir = .GlobalEnv))
model$call <- as.formula(eqn)
return(model)
}
myfun(2, 1)
#Call:
#A4 ~ B4 I(B4^2)
#Coefficients:
#(Intercept) B4 I(B4^2)
# 0.84795 0.12281 0.02924