【问题标题】:Summary statistics for simple linear regressions stored in a list using lapply使用 lapply 存储在列表中的简单线性回归的汇总统计
【发布时间】:2020-05-10 16:29:40
【问题描述】:

我有一系列简单的线性回归,形式为 y ~ x1、y ~x2、y~ x3 等。

我已经能够运行我所有的线性回归并存储了输出,但是我无法以矢量化方式访问汇总统计信息,例如为每个模型调整 R 平方。

我可以通过 for 循环来完成并遍历每个模型,但我认为必须有更简单的方法来使用 lapply(或 sapply?)并更快地获得结果。

一个可重现的例子如下:

library(tidyverse)
library(broom)

set.seed(6)

DF <- data.frame(Y=rnorm(50, 100, 3),
                 X1=rnorm(50, 100, 3),
                 X2=rnorm(50, 100, 3),
                 X3=rnorm(50, 100, 3),
                 X4=rnorm(50, 100, 3))

DF_longer = pivot_longer(DF, -Y, names_to = "variable", values_to = "value", values_ptypes = list(val = 'numeric'))

lm1 = DF_longer %>% group_by(variable) %>% do(tidy(lm(Y ~ value, data=.)))
lm2 = DF_longer %>% group_by(variable) %>% do(mod = lm(Y ~ value, data=.))

我想优化的部分如下,我想将每个模型的调整后的 R 平方存储在没有 for 循环的向量中。

lm2_data = summary(lm2$mod[[1]])
lm2_data$adj.r.squared

lm2_data = summary(lm2$mod[[2]])
lm2_data$adj.r.squared

lm2_data = summary(lm2$mod[[3]])
lm2_data$adj.r.squared

lm2_data = summary(lm2$mod[[4]])
lm2_data$adj.r.squared

【问题讨论】:

    标签: r regression lapply


    【解决方案1】:

    这是一个使用 mtcars 数据的示例:

    regModels <- c("mpg ~ am", "mpg ~ am + wt", "mpg ~ wt + am + disp")
    
    results <- lapply(regModels,function(x){
         y <- summary(lm(x,data = mtcars))$adj.r.squared
    
    })
    
    names(results) <- regModels
    
    results
    

    ...和输出:

    > results
    $`mpg ~ am`
    [1] 0.3384589
    
    $`mpg ~ am + wt`
    [1] 0.7357889
    
    $`mpg ~ wt + am + disp`
    [1] 0.757583
    
    > 
    

    使用原始帖子中的数据...

    library(tidyverse)
    library(broom)
    set.seed(6)
    
    DF <- data.frame(Y=rnorm(50, 100, 3),
                     X1=rnorm(50, 100, 3),
                     X2=rnorm(50, 100, 3),
                     X3=rnorm(50, 100, 3),
                     X4=rnorm(50, 100, 3))
    
    DF_longer = pivot_longer(DF, -Y, names_to = "variable", values_to = "value", values_ptypes = list(val = 'numeric'))
    
    lm1 = DF_longer %>% group_by(variable) %>% do(tidy(lm(Y ~ value, data=.)))
    lm2 = DF_longer %>% group_by(variable) %>% do(mod = lm(Y ~ value, data=.))
    
    adjRsquared <- lapply(lm2$mod,function(x){
         y <- summary(x)$adj.r.squared
    })
    names(adjRsquared) <- lm2$variable
    adjRsquared
    

    ...和输出:

    > adjRsquared
    $X1
    [1] -0.007637371
    
    $X2
    [1] 0.007729944
    
    $X3
    [1] 0.04993542
    
    $X4
    [1] -0.02026235
    

    【讨论】:

    • 我想避免定义模型 regModels,因为我有几个不同的模型要运行(总共 13 个),所以我想尽量保持它的效率。
    • @AveshenPillay - 我更新了我的答案以包含您的数据的解决方案。
    【解决方案2】:

    sapply() 函数对列表的每个元素执行一个函数并为您提供一个向量:

    sapply(lm2$mod, function(x) summary(x)$adj.r.squared)

    【讨论】:

      【解决方案3】:

      在基础 R 中,您可以使用 reformulate 获得公式向量 fov,在此向量上进行回归并同时提取 adj。 R2sapply

      fov <- lapply(names(DF)[2:5], reformulate, "Y")
      res <- sapply(fov, function(x) summary(lm(x, data=DF))$adj)
      res
      # [1] -0.007637371  0.007729944  0.049935424 -0.020262353
      

      一步完成:

      sapply(lapply(names(DF)[2:5], reformulate, "Y"), function(x) summary(lm(x, data=DF))$adj)
      # [1] -0.007637371  0.007729944  0.049935424 -0.020262353
      

      注意:你说你想要一个向量,如果你想要一个列表,只需将 sapply 替换为 lapply

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-12-13
        • 1970-01-01
        • 2016-04-14
        • 2013-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多