【问题标题】:How to correctly select dependent variable and controls in lm() in R?如何在 R 的 lm() 中正确选择因变量和控件?
【发布时间】:2022-01-31 04:48:56
【问题描述】:

我正在寻找一种方法来构造一个函数,该函数允许用户在给定数据框的情况下:

  1. 选择作为因变量的变量;
  2. 选择某个控件(只有一个变量);
  3. 根据这些选择,运行几个不同的回归;

理想情况下,我想要这样的东西:

df <- mtcars

myreg <- function(dv, control) {
  mod1 <- lm(dv ~ control + mpg, data = df)
  mod2 <- lm(dv ~ control + wt, data = df)
  mod3 <- lm(dv ~ control + wt + mpg, data = df)
  return(list("reg1" = mod1, "reg2" = mod2, "reg3" = mod3))
}

我的第一个猜测是提供带有列名的字符串会起作用。但是R 会引发错误。它告诉我变量的长度不匹配。此外,不传递字符串而只传递名称也不起作用。

我尝试了一些基于get 函数的解决方案。但是,它不能正确解析控件,老实说,我还不明白它是如何工作的。

在函数中实现这些选择的正确方法是什么?

【问题讨论】:

    标签: r regression lm


    【解决方案1】:

    您要做的是为回归创建一个包装函数。理想情况下,您应该对此进行编程,以便该函数可以接收任意数据集和指定的响应变量、控制变量和其他模型项,然后生成所有感兴趣的模型。

    通常我们希望用户输入不带引号的变量名,并且我们使用deparse(substitute(...)) 将此输入的名称提取为“未计算的表达式”。对于回归中的其他模型项,由于可以有任意多个,因此合理的输入应该是字符向量列表。当您创建包装函数时,它通常会为感兴趣的模型构造一个“内部调用”,这可能与这些模型的标准调用不同。因此,您通常还需要修改模型的调用,使它们看起来像标准调用。所以,使用这种语法,你会写这样的东西:

    myreg <- function(response, control, other.terms = NULL, data) {
      
      #Get variable names and other terms
      DATA.NAME     <- deparse(substitute(data))
      RESPONSE.NAME <- deparse(substitute(response))
      CONTROL.NAME  <- deparse(substitute(control))
      if (is.null(other.terms)) {
        OTHER <- vector(mode = 'list', length = 1) } else {
        OTHER <- other.terms }
    
      #Set formula and model objects
      m <- length(OTHER)
      FORMULAE <- vector(mode = 'list', length = m)
      MODELS   <- vector(mode = 'list', length = m)
      names(MODELS) <- sprintf('MODEL%s', 1:m)
      FORM     <- paste(RESPONSE.NAME, '~', CONTROL.NAME)
      
      #Fit models
      for (i in 1:m) {
        
        #Set the formula
        if (is.null(OTHER[[i]])) {
          FORMULAE[[i]] <- FORM } else {
          FORMULAE[[i]] <- paste(FORM, '+', paste(OTHER[[i]], collapse = '+')) }
        
        #Fit the model and substitute the call
        MODELS[[i]] <- lm(formula(FORMULAE[[i]]), data = data)
        CALL <- paste0('lm(formula = ', FORMULAE[[i]], ', data = ', DATA.NAME, ')')
        MODELS[[i]]$call <- parse(text = CALL)[[1]] }
      
      #Return the models
      MODELS }
    

    然后,您可以使用该函数生成具有指定变量的多个回归模型列表。这是一个示例,您生成了三个不同的模型,每个模型都具有相同的响应和控制变量,但模型中的附加项不同:

    (MODELS <- myreg(response    = hp, 
                     control     = cyl,
                     other.terms = list('mpg', 'wt', c('mpg', 'wt')), 
                     data        = mtcars))
    
    $MODEL1
    
    Call:
    lm(formula = hp ~ cyl + mpg, data = mtcars)
    
    Coefficients:
    (Intercept)          cyl          mpg  
         54.067       23.979       -2.775  
    
    $MODEL2
    
    Call:
    lm(formula = hp ~ cyl + wt, data = mtcars)
    
    Coefficients:
    (Intercept)          cyl           wt  
         -51.81        31.39         1.33  
    
    $MODEL3
    
    Call:
    lm(formula = hp ~ cyl + mpg + wt, data = mtcars)
    
    Coefficients:
    (Intercept)          cyl          mpg           wt  
         115.66        25.03        -4.22       -12.13
    

    【讨论】:

      【解决方案2】:

      您应该使用字符串替换。下面的 sn-p 提供了如何调整函数的简单概述。将数据集 df 作为函数中的附加参数传递也是一种好习惯。

      df <- mtcars
      
      ## these would be function inputs
      dv              <- "mpg"
      control         <- "cyl"
      
      ## this would form the function body 
      tmpl            <- "dv ~ control" # create a template formula 
      tmpl.dv         <- gsub("dv", dv, tmpl) # insert the dv
      tmpl.dv.control <- gsub("control", control, tmpl.dv) # insert the control
      form            <- as.formula(tmpl.dv.control) # create the formula to use in lm
      
      ## fit the model
      mod <- lm(form, data = df)
      

      【讨论】:

        猜你喜欢
        • 2013-07-28
        • 1970-01-01
        • 2020-12-30
        • 1970-01-01
        • 2016-05-15
        • 1970-01-01
        • 2022-10-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多