【问题标题】:performing all possible linear regressions between 1 variable and a list of variables在 1 个变量和变量列表之间执行所有可能的线性回归
【发布时间】:2019-12-25 22:09:01
【问题描述】:

我正在使用以下代码(由 in a previous post 开发)执行以下任务:在第一个变量和其他变量之间执行所有可能的线性回归,并将结果保存在新的数据框中。

library(broom)
library(dplyr)
x <- names(data[,-1])
out <- unlist(lapply(1, function(n) combn(x, 1, FUN=function(row) 
          paste0("tlv ~ ", paste0(row, collapse = "+")))))
## get the regression coefficients
tmp1 = bind_rows(lapply(out, function(frml) {
      a = tidy(lm(frml, data=data))
      a$frml = frml
      return(a)
    }))
reg_coeff2 <- tmp1
 ## Get regression results i.e. R2, AIC, BIC
 tmp2 = bind_rows(lapply(out, function(frml) {
      a = glance(lm(frml, data=data))
      a$frml = frml
      return(a)
    }))
 reg_results2 <- tmp2
 reg_results2$frml <- sub("tlv ~ ", "", reg_results2$frml)

代码运行良好,但我想实现它以执行以下操作。

我有如下数据框(data)

structure(list(id = c(5309039, 5284969, 5300279, 5270289, 5259957, 
5267086, 5173196), var1 = c(0, 0, 0, 0, 0, 0, 0), var2 = c(23, 
24, 20, 32, 31, 37, 43), var3 = c(162, 154, 156, 154, 151.5, 
171, 154), var4 = c(62.8, 52.7, 64.5, 70.9, 63, 66.2, 60.3), 
    tlv = c(1049, 978, 1131, 1292, 1228, 1593, 1265), form20 = c(1674.12110392683, 
    1517.06018080512, 1666.03606715029, 1726.99450999549, 1627.94506984781, 
    1754.74878787639, 1608.54623766777), form19 = c(1062.84280028848, 
    902.364998653641, 1054.58187260355, 1116.8664734097, 1015.66220125765, 
    1145.22454880977, 995.841345244203), form18 = c(1050.91941325579, 
    891.3634649201, 1026.84722464179, 1073.58291322486, 980.997498562542, 
    1147.23019335865, 971.271632531001), form17 = c(1404.10436829839, 
    1220.98291088203, 1419.72032143583, 1517.11065788694, 1386.31581471687, 
    1477.21675910098, 1347.52393410332), form16 = c(1248.12292187059, 
    1126.73082253566, 1229.80850901466, 1265.36558733196, 1194.92548170827, 
    1321.39733067342, 1187.52592495257), form15 = c(990.132, 
    866.003, 1011.025, 1089.681, 992.59, 1031.918, 959.407), 
    form14 = c(1590.6052, 1436.4718, 1582.993, 1830.3706, 1688.692, 
    1812.3808, 1786.5202), form13 = c(1300.81321145176, 1130.23869905075, 
    1292.03253463863, 1358.23586808642, 1250.66417156907, 1388.37813595599, 
    1277.89625553694), form12 = c(1329.6, 1104.4, 1272, 1322.8, 
    1195.5, 1487.4, 1195.6)), row.names = c(NA, -7L), class = c("tbl_df", 
"tbl", "data.frame"))

我需要在变量 tlv 和名称以前缀 "form" 开头的所有变量之间执行线性回归,因此不包括其他变量(即 var1var2var3、. ..)

【问题讨论】:

  • 在您的代码中,您使用的是combn(x, 1) 不清楚您为什么需要它

标签: r


【解决方案1】:

考虑 apply 系列来构建所有可能组合的所需公式,然后迭代地传递到 lm。除了broom 函数,下面演示了base R:

indvar_list <- lapply(1:9, function(x) combn(paste0("form", 12:20), x, simplify = FALSE)) 

formulas_list <- rapply(indvar_list, function(x) as.formula(paste("tlv ~", paste(x, collapse="+")))) 

tmp1 <- do.call(rbind, lapply(formulas_list, function(f)
   transform(tidy(lm(f, data=data)), frml = f)
))

tmp2 <- do.call(rbind, (lapply(formulas_list, function(f)
   transform(glance(lm(f, data=data)), frml = f)
))

【讨论】:

    【解决方案2】:

    我们可以使用map 来缩短它

    library(purrr)
    tmp1 <- map_dfr(set_names(out, out),  ~ lm(.x, data = data) %>% tidy, .id = 'fmla')
    tmp2 <- map_dfr(set_names(out, out),  ~ lm(.x, data = data) %>% glance, .id = 'fmla')
    

    或者如果我们只需要form 变量,则获取startsWith "form" 的列的名称,将其传递给reformulate 以在lm 中创建公式,tidy 输出并创建“Var”列表示列名(或者如果我们需要公式本身,请将reformulate 输出分配给一个对象并稍后调用它

    startsWith(names(data), "form") %>%
        magrittr::extract(names(data), .) %>%
        map_dfr(~  lm(reformulate(.x, 'tlv'), data = data) %>% 
                      tidy %>%
                      mutate(Var = .x))
    

    同样将tidy改为glance

    【讨论】:

      【解决方案3】:

      我们假设获取子集的目标是找到最好的变量,所以不要像那样继续,让我们使用逐步回归来找到“最好的”变量。

      由于data 的行数少于列数且var1 全为0,因此我们使用下面显示的数据框data2 作为示例。

      首先创建完整模型 fm0 并使用逐步回归指定 var 变量作为下限,即每个模型都必须包含它们。

      这会在这些数据上快速运行,并且不使用任何包。

      data2 <- data[c("var2", "var3", "tlv", "form20", "form19")]
      
      fm0 <- lm(tlv ~., data2)
      varnames <- grep("var", names(data2), value = TRUE)
      step(fm0, list(lower = reformulate(varnames)))
      

      给出这个模型:

      Call:
      lm(formula = tlv ~ var2 + var3 + form20, data = data2)
      
      Coefficients:
      (Intercept)         var2         var3       form20  
        -2235.694       13.881        6.728        1.197  
      

      【讨论】:

        猜你喜欢
        • 2020-03-06
        • 2019-09-03
        • 2020-05-20
        • 1970-01-01
        • 2021-11-28
        • 2019-05-19
        • 2020-09-19
        • 1970-01-01
        • 2022-08-03
        相关资源
        最近更新 更多