R: анализировать и оценивать имена переменных внутри функции

У меня довольно большой набор предикторов для выбора модели, однако для простоты этот пример будет работать с mtcars набор данных. Я с некоторой неохотой принимаю dredge()-подход, так как я хочу повысить свою осведомленность о том, какие предикторы выбираются и почему.

Я написал функцию, чтобы пройти через все предикторы (через update()) для одного шага выбора, чтобы иметь возможность оценить их размер эффекта (оценка) и р-значение. Предполагается, что вывод будет data.frame, где я могу видеть все довольно быстро.

Это кажется немного неловким для меня. При запуске цикла for - после определения model а также variables (и все вокруг) вручную - все вроде бы нормально, и получается ожидаемый результат (см. ниже). При запуске функции, update/eval/parse кажется, не признает, что variables был определен и поэтому не может вычислить обновленную модель.

  1. Что я здесь не так делаю?
  2. Любые предложения по улучшению кода помимо этого?

функциональное тело

find_effects <- function(model, variables=NULL){
  require(car)
  estim <- NULL; p_val <- NULL; stars <- NULL; names <- NULL

  for(i in 1:length(variables)){
    original <- model
    if(is.null(variables)){
      cat("'variables' is NULL")
    } else {
      cat(paste("'variables' is not NULL, it has ", length(variables), " elements"))
    }
    updated <- update(model, . ~ . + eval(parse(text=variables[i])))
    if(length(rownames(summary(original)$coef))==length(rownames(summary(updated)$coef))){
      next
    }
    df.summary <- data.frame(estim=summary(updated)$coef[,1], names=rownames(summary(updated)$coef))
    df.Anova <- data.frame(p_val=Anova(updated, type="III")[,3], names=rownames(Anova(updated, type="III")))
    estim <- c(estim, df.summary$estim[df.summary$names=="eval(parse(text = variables[i]))"])
    p_val <- c(p_val, df.Anova$p_val[df.Anova$names=="eval(parse(text = variables[i]))"])
    stars <- symnum(p_val, corr = FALSE,
                    cutpoints = c(0, .001, .01, .05, .1, 1),
                    symbols = c("***", "**", "*", ".", " "))
    names <- c(names, variables[i])

  }
  df <- noquote(cbind(Estimate=format(estim), "Pr(>Chisq)"=format(p_val), " "=stars))
  rownames(df) <- names
  return(df)

}

library(lme4)
mpgs <- lmer(mpg ~ hp + (1|cyl), data=mtcars, REML=F)

find_effects(mpgs, colnames(mtcars[c(3, 5:11)]))

ожидаемый результат

         Estimate    Pr(>Chisq)      
    disp -0.02942650 7.331371e-05 ***
    drat  4.69815776 3.449956e-05 ***
    wt   -3.78335019 4.098811e-10 ***
    qsec -0.98805796 1.505408e-02 *  
    vs    0.04636047 9.798979e-01    
    am    5.00527293 1.506875e-06 ***
    gear  3.08916264 5.346748e-05 ***
    carb  0.33074245 6.094443e-01    

1 ответ

Решение

Формула для обновления при вызове функции будет выглядеть примерно так:

mpg ~ hp + (1|cyl) + eval(parse(text = variables[i]))

Выражение вычисляется только после его передачи в функцию обновления, где объект переменных не определен. Отсюда и ошибка.

создайте формулу и затем передайте ее функции обновления.

updated <- paste(". ~ . + ", variables[i], sep="")
updated <- update(model, updated)
Другие вопросы по тегам