вызов функции glm () в пользовательской функции - PullRequest
2 голосов
/ 28 февраля 2020

Я отчаянно пытался создать функцию, которая использует внутри нее glm (). Но я всегда получаю сообщение об ошибке. Похоже, что функция не получает значение переменной. Любая помощь будет очень оценена

set.seed(234)
sex <- sample(c("M", "F"), size=100, replace=TRUE)
age <- rnorm(n=100, mean=20 + 4*(sex=="F"), sd=0.1)
dsn <- data.frame(sex, age)
rm(sex, age) #remove sex and age from the global environment for reproducibility

to_analyze <- function(dep, indep, data){
  glm(dep~factor(indep), data=data)
}

to_analyze(dep=age, indep=sex, data=dsn)
#> Error in eval(predvars, data, env): object 'age' not found


Ответы [ 3 ]

3 голосов
/ 28 февраля 2020

Вы можете использовать любое из следующего:

Использование substitute:

to_analyze <- function(dep, indep, data){
  glm(substitute(dep ~ factor(indep)), data=data)
}

to_analyze(dep=age, indep=sex, data=dsn)

Преимущество: Можно написать независимое в виде формулы.

например,

 to_analyze(Petal.Width, Sepal.Length + Sepal.Width, data = iris)

Использование переформулировки, как указано @ NelsonGon

to_analyze <- function(dep, indep, data){ 
  glm(reformulate(sprintf("factor(%s)",indep), dep),  data = data) 
 }

Обратите внимание, что для вызова этой функции переменные должен иметь тип символа

 to_analyze(dep= "age", indep="sex", data=dsn)

Recall glm также может принимать строку, которая может быть проанализирована по формуле:

to_analyze <- function(dep, indep, data){ 
  glm(sprintf("%s~factor(%s)", dep, indep),  data = data) 
}

to_analyze("age", "sex", data=dsn)

или даже:

to_analyze <- function(dep, indep, data){ 
  glm(paste(dep,"~ factor(",indep,")"),  data = data) 
}

to_analyze("age", "sex", data=dsn)

LASTLY: для объединения и замены, и вставки:

to_analyze <- function(dep, indep, data){ 
  glm(paste(substitute(dep),"~ factor(",substitute(indep),")"),  data = data) 
}

будет работать как для символов, так и для символов. например:

to_analyze(age, sex, data=dsn)
to_analyze("age", "sex", data=dsn)
1 голос
/ 28 февраля 2020

Создайте "formula" объект в функции и передайте glm.

Чтобы получить переменные без ошибки, стандартным трюком будет deparse(substitute(.)).
Затем составьте формулу с paste.

to_analyze <- function(dep, indep, data){
  dep <- deparse(substitute(dep))
  indep <- deparse(substitute(indep))
  indep <- paste0("factor(", indep, ")")
  fmla <- paste(dep, indep, sep = " ~ ")
  fmla <- as.formula(fmla)
  glm(fmla, data = data)
}

to_analyze(dep=age, indep=sex, data=dsn)
#
#Call:  glm(formula = fmla, data = data)
#
#Coefficients:
# (Intercept)  factor(sex)M  
#      23.984        -3.984  
#
#Degrees of Freedom: 99 Total (i.e. Null);  98 Residual
#Null Deviance:     396.2 
#Residual Deviance: 0.837   AIC: -188.5
0 голосов
/ 29 февраля 2020

@ Онямбу и другие. Команда подстановки, кажется, работает хорошо только для одного вызова, поскольку она работает для to_analyze (). Однако, когда я вызываю другую функцию внутри, она снова жалуется. Любая помощь будет принята с благодарностью

to_analyze <- function(dep, indep, data){
  glm(substitute(dep ~ factor(indep)), data=data)
}

to_analyze(dep=age, indep=sex, data=dsn)
#> 
#> Call:  glm(formula = substitute(dep ~ factor(indep)), data = data)
#> 
#> Coefficients:
#>  (Intercept)  factor(sex)M  
#>       24.006        -4.034  
#> 
#> Degrees of Freedom: 99 Total (i.e. Null);  98 Residual
#> Null Deviance:       397.3 
#> Residual Deviance: 0.8152    AIC: -191.2

Однако я снова застрял, потому что я пытаюсь вызвать вывод этой модели в lsmeans::lsmeans(), чтобы предсказать предельные средние значения и вернуть результат, но это дает мне ошибка. Хотя это не требует смещения, я включаю его здесь, чтобы я мог получить более общий код, который я могу изменить позже. Любая помощь будет принята с благодарностью

to_predict_lsmeans <- function(dep, indep, data){
  model <- glm(substitute(dep ~ factor(indep)), data=data)
  pred <- lsmeans:: lsmeans(model, substitute(~ factor(indep)), offset=substitute(data)$log(age), type ="response" )
  return(pred)
}

pred <- to_predict_lsmeans(dep=age, indep=sex, data=dsn)
#> Error in ref_grid(object, ...): We are unable to reconstruct the data.
#> The variables needed are:
#>  sex
#> Are any of these actually constants? (specify via 'params = ')
#> The dataset name is:
#>  data
#> Does the data still exist? Or you can specify a dataset via 'data = '
pred
#> Error in eval(expr, envir, enclos): object 'pred' not found
...