Я пытаюсь создать функцию R для пакета, который будет принимать пользовательские данные и (с правой стороны) формулы, выполнять некоторую обработку и возвращать модель. Но у меня возникают проблемы, когда пользовательские данные или формулы содержат переменные с тем же именем, что и для внутреннего использования. Воспроизводимый пример,
(Обратите внимание, что обновление среды формулы требуется, чтобы R не смотрел в R_GlobalEnv пользователя для моей переменной y.)
# R Version 3.6.2
my_function <- function(user_data, user_formula){
y <- as.numeric(user_data[,1] > mean(user_data[,1]))
my_formula <- update.formula(user_formula, y ~ .)
environment(my_formula) <- environment()
my_model <- lm(my_formula, data = user_data, model = TRUE)
return(my_model)
}
some_data <- data.frame(x1 = c(1,2,3,3))
some_formula <- response ~ x1
my_function(some_data, some_formula)
Выше приведено то, что я хочу запустить, и это работает, пока нет переменных в user_formula или user_data с именем "y". Но когда user_data содержит переменную с тем же именем, модель будет использовать эту переменную вместо моей.
some_data <- data.frame(x1 = c(1,2,3,3), y = c(6,7,5,6))
some_formula <- response ~ x1 + y
my_function(some_data, some_formula)$model
# y x1
# 1 6 1
# 2 7 2
# 3 5 3
# 4 6 3
# Warning messages:
# 1: In model.matrix.default(mt, mf, contrasts) :
# the response appeared on the right-hand side and was dropped
# 2: In model.matrix.default(mt, mf, contrasts) :
# problem with term 2 in model.matrix: no columns are assigned
Я попытался заставить R выполнить поиск в среде функции y, используя get (),
my_function <- function(user_data, user_formula){
y <- as.numeric(user_data[,1] > mean(user_data[,1]))
e1 <- environment()
my_formula <- update.formula(user_formula, get("y", e1) ~ .)
environment(my_formula) <- environment()
my_model <- lm(my_formula, data = user_data, model = TRUE)
return(my_model)
}
some_data <- data.frame(x1 = c(1,2,3,3), y = c(6,7,5,6))
some_formula <- response ~ x1 + y
my_function(some_data, some_formula)$model
# get("y", e1) x1 y
# 1 0 1 6
# 2 0 2 7
# 3 1 3 5
# 4 1 3 6
Но это также не удается, если в пользовательских данных есть переменная с тем же именем как мое имя внутренней среды,
some_data <- data.frame(x1 = c(1,2,3,3), y = c(6,7,5,6), e1 = c(1,2,3,4))
some_formula <- response ~ x1 + y + e1
my_function(some_data, some_formula)$model
# Error in get("y", e1) : invalid 'envir' argument
Как правильно избежать наложения моих внутренних переменных на предоставленные пользователем имена переменных? Я бы предпочел метод для базы R, если это возможно.