【问题标题】:R: parse and evaluate variable names within a functionR:解析和评估函数中的变量名
【发布时间】:2015-09-11 10:03:20
【问题描述】:

我有一组相当多的预测变量来进行模型选择,为了简单起见,这个例子将适用于mtcars 数据集。 我有点不愿意采用dredge()-方法,因为我想提高我对选择哪些预测器以及为什么选择的认识。

我编写了一个函数来遍历所有预测变量(通过update())进行一步选择,以便能够评估它们的影响大小(估计)和 p 值。输出应该是一个 data.frame,我可以在其中快速查看所有内容。

这对我来说似乎有点尴尬。运行 for 循环时 - 在手动定义 modelvariables(及其周围的所有内容)之后 - 一切似乎都很好,并且产生了预期的输出(见下文)。运行该函数时,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    

【问题讨论】:

    标签: r parsing for-loop eval updatemodel


    【解决方案1】:

    调用函数时的更新公式如下:

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

    表达式仅在传递给更新函数后才被评估,其中未定义变量对象。因此出现错误。

    创建公式,然后将其传递给更新函数。

    updated <- paste(". ~ . + ", variables[i], sep="")
    updated <- update(model, updated)
    

    【讨论】:

    • 谢谢。这对我有用。但是,它并没有解释为什么手动运行 for 循环会起作用,而将其包装到函数中会导致函数不起作用...
    • 我的猜测是在函数中调用函数时环境的变化。当您手动运行它时,eval 在 update 函数中被调用,它可以访问定义“变量”的全局环境,而在函数内部调用它时,eval 无法访问其中的环境变量已定义.....阅读有关 R 环境以了解更多信息..
    猜你喜欢
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多