开始前的两个注意事项:
- 您想要一个漂亮的“自定义”表,因此几乎不可避免地需要进行一些手动操作。
- 我的答案依赖于 的开发版本
modelsummary
,您可以像这样安装它:
library(remotes)
install_github("vincentarelbundock/modelsummary")
我们将需要 4 个概念,其中许多与broom
包相关:
broom::tidy
一个函数,它采用统计模型并返回每个系数一行的估计的 data.frame。
broom::glance
一个采用统计模型并返回具有模型特征(例如,观察次数)的单行数据帧的函数
modelsummary_list
一个包含 2 个元素的列表,称为“tidy”和“glance”,类名称为“modelsummary_list”。
该modelsummary
软件包允许您绘制回归表。在后台,它使用broom::tidy
并broom::glance
从这些模型中提取信息。用户还可以通过提供我们分配类的列表来提供他们自己的模型信息modelsummary_list
,如此处所述。
编辑:推荐的方法modelsummary
是现在使用group
参数。滚动到本文末尾以获取说明性代码。
带有有用讨论的过时示例
该modelsummary_wide
函数最初设计用于“堆叠”具有多组系数的多个模型的结果。这对于多项式模型之类的东西很有用,但它也有助于我们在您的情况下,您在多个组中拥有多个模型(这里:年)。
首先,我们加载包、调整数据并估计我们的模型:
library(modelsummary)
library(broom)
library(dplyr)
mtcars2010 <- mtcars
mtcars2010$cyl <- mtcars$cyl * runif(1)
models <- list(
"A" = list(
lm(mpg ~ cyl, data = mtcars),
lm(mpg ~ cyl, data = mtcars2010)),
"B" = list(
lm(mpg ~ cyl + wt, data = mtcars),
lm(mpg ~ cyl + wt, data = mtcars2010)),
"C" = list(
lm(mpg ~ cyl + wt + disp, data = mtcars),
lm(mpg ~ cyl + wt + disp, data = mtcars2010)))
请注意,我们将模型保存在三组列表中。
然后,我们定义一个tidy_model
函数,它接受两个模型的列表(每年一个),结合这两个模型的信息,并创建一个modelsummary_list
对象(再次,请参阅文档)。请注意,我们将“年份”信息分配给tidy
对象中的“组”列。
我们将这个函数应用到我们使用lapply
.
tidy_model <- function(model_list) {
# tidy estimates
tidy_2000 <- broom::tidy(model_list[[1]])
tidy_2010 <- broom::tidy(model_list[[2]])
# create a "group" column
tidy_2000$group <- 2000
tidy_2010$group <- 2010
ti <- bind_rows(tidy_2000, tidy_2010)
# glance estimates
gl <- data.frame("N" = stats::nobs(model_list[[1]]))
# output
out <- list(tidy = ti, glance = gl)
class(out) <- "modelsummary_list"
return(out)
}
models <- lapply(models, tidy_model)
最后,我们modelsummary_wide
用stacking="vertical"
参数调用 来获取这个表:
modelsummary_wide(models, stacking = "vertical")
当然,可以使用modelsummary_wide
函数的其他参数或参数kableExtra
支持的其他包来调整表、重命名系数等output
。
更现代的例子,没有详细的解释
library("modelsummary")
library("broom")
library("quantreg")
mtcars2010 <- mtcars
mtcars2010$cyl <- mtcars$cyl * runif(1)
models <- list(
"A" = list(
"2000" = rq(mpg ~ cyl, data = mtcars),
"2010" = rq(mpg ~ cyl, data = mtcars2010)),
"B" = list(
"2000" = rq(mpg ~ cyl + wt, data = mtcars),
"2010" = rq(mpg ~ cyl + wt, data = mtcars2010)),
"C" = list(
"2000" = rq(mpg ~ cyl + wt + disp, data = mtcars),
"2010" = rq(mpg ~ cyl + wt + disp, data = mtcars2010)))
tidy_model <- function(model_list) {
# tidy estimates
tidy_2000 <- broom::tidy(model_list[[1]])
tidy_2010 <- broom::tidy(model_list[[2]])
# create a "group" column
tidy_2000$group <- "2000"
tidy_2010$group <- "2010"
ti <- bind_rows(tidy_2000, tidy_2010)
# output
out <- list(tidy = ti, glance = data.frame("nobs 2010" = length(model_list[[1]]$fitted.values)))
class(out) <- "modelsummary_list"
return(out)
}
models <- lapply(models, tidy_model)
modelsummary(models,
group = model + term ~ group,
statistic = "conf.int")
|
|
2000 |
2010 |
一个 |
(截距) |
36.800 |
36.800 |
|
|
[30.034, 42.403] |
[30.034, 42.403] |
|
圆柱体 |
-2.700 |
-67.944 |
|
|
[-3.465, -1.792] |
[-87.204,-45.102] |
乙 |
(截距) |
38.871 |
38.871 |
|
|
[30.972, 42.896] |
[30.972, 42.896] |
|
圆柱体 |
-1.743 |
-43.858 |
|
|
[-2.154, -0.535] |
[-54.215,-13.472] |
|
重量 |
-2.679 |
-2.679 |
|
|
[-5.313,-1.531] |
[-5.313,-1.531] |
C |
(截距) |
40.683 |
40.683 |
|
|
[31.235, 47.507] |
[31.235, 47.507] |
|
圆柱体 |
-1.993 |
-50.162 |
|
|
[-3.137,-1.322] |
[-78.948, -33.258] |
|
重量 |
-2.937 |
-2.937 |
|
|
[-5.443, -1.362] |
[-5.443, -1.362] |
|
显示 |
0.003 |
0.003 |
|
|
[-0.009, 0.035] |
[-0.009, 0.035] |