modelsummary/kableExtra 使用同名模型进行回归 table
modelsummary/kableExtra regression table with models of the same name
我使用 modelsummary()
和 kableExtra()
在 Rmd 文件中生成回归 table(最终输出格式:LaTex 和 HTML)。
I 运行 几个变量组合和模型规范的回归。
通过 kable::add_header_above()
.
变量组合将回归分组在 table 中
对于不同的变量组合,我运行相同的模型(例如OLS & Poisson,或其他)。
因此,为了提高可读性,我想简单地命名模型,例如
names(models) <- c("OLS", "Poisson", "OLS", "Poisson", ...)
而不是
names(models) <- c("OLS 1", "Poisson 1", "OLS 2", "Poisson 2", ...)
但是,modelsummary()
以某种方式不允许回归命名相同,导致以下错误:
Error: Can't bind data because some arguments have the same name
Backtrace:
1. modelsummary::msummary(...)
2. modelsummary::extract(...)
10. dplyr::mutate(., group = "gof")
12. dplyr:::mutate_cols(.data, ...)
13. DataMask$new(.data, caller_env())
14. .subset2(public_bind_env, "initialize")(...)
17. rlang::env_bind_lazy(...)
18. rlang:::env_bind_impl(.env, exprs, "env_bind_lazy()", TRUE, binder)
和
Error in htmlTable_add_header_above(kable_input, header, bold, italic, :
The new header row you provided has a different total number of columns with the original `kabel()` output.
MWE:
library(modelsummary)
library(kableExtra)
url <- 'https://vincentarelbundock.github.io/Rdatasets/csv/HistData/Guerry.csv'
dat <- read.csv(url)
models <- list()
models[['OLS']] <- lm(Crime_prop ~ Literacy, data = dat)
models[['Poisson']] <- glm(Crime_prop ~ Literacy + Clergy, family = poisson, data = dat)
models[['OLS']] <- lm(Crime_pers ~ Literacy, data = dat)
models[['Poisson']] <- glm(Crime_pers ~ Literacy + Clergy, family = poisson, data = dat)
# build table with `modelsummary`
cm <- c( '(Intercept)' = 'Constant', 'Literacy' = 'Literacy (%)', 'Clergy' = 'Priests/capita')
cap <- 'A modelsummary table customized with kableExtra'
tab <- msummary(models, output = 'kableExtra',
coef_map = cm, stars = TRUE,
title = cap, gof_omit = 'IC|Log|Adj')
# customize table with `kableExtra`
tab %>%
# column labels
add_header_above(c(" " = 1, "Crimes (property)" = 2, "Crimes (person)" = 2))
插件:
一种解决方法是在模型名称中添加 space " "
,然后再使用 modelsummary
:
构建 table
names(models) <- c("OLS", "Poisson", "OLS ", "Poisson ", ...)
对于少数模型规格和变量组合,手动这很容易实现。
但是,首选可以动态适应给定设置的解决方案,即也适用于以下情况:
names(models) <- c("OLS", "Poisson", "GLM", "Poisson", ...)
而不是
names(models) <- c("OLS 1", "Poisson 1", "GLM 2", "Poisson 2", ...)
更新:
使用@Vincent 提供的更新包版本,对于存储在嵌套列表中的模型,例如如果它们在循环中或通过 lapply(..., FUN).
添加到子列表
models <- NA
models <- list()
models[["a"]][["OLS"]] <- lm(Crime_prop ~ Literacy, data = dat)
models[["a"]][["Poisson"]] <- glm(Crime_prop ~ Literacy + Clergy, family = poisson, data = dat)
models[["b"]][["OLS"]] <- lm(Crime_pers ~ Literacy, data = dat)
models[["b"]][["Poisson"]] <- glm(Crime_pers ~ Literacy + Clergy, family = poisson, data = day)
# ...
models_unlisted <- unlist(models, recursive=FALSE)
names(models_unlisted) <- c('ols', 'poisson', 'ols', 'poisson')
cm <- c( '(Intercept)' = 'Constant', 'Literacy' = 'Literacy (%)', 'Clergy' = 'Priests/capita')
msummary(models_unlisted, output = 'kableExtra', statistic_vertical = FALSE,
coef_map = cm, stars = TRUE, gof_omit = 'IC|Log|Adj') %>%
add_header_above(c(" " = 1, "Crimes (property)" = 2, "Crimes (person)" = 2))
目前,您的 MWE 中的第 3 个和第 4 个模型覆盖了前两个,因此 models
列表中只有两个元素,这会给您带来 different total number of columns
错误。
如果只是为了提高可读性,您可以在第 3 和第 4 个模型的名称后添加 space,其余部分应该可以很好地显示。
models[['OLS ']] <- lm(Crime_pers ~ Literacy, data = dat)
models[['Poisson ']] <- glm(Crime_pers ~ Literacy + Clergy, family = poisson, data = dat)
感谢提问。另一位发帖人是对的:您在 MWE 下的解决方案将永远行不通,因为它涉及 R
语言的基本功能。分配给列表中的相同名称会覆盖以前的值。参见:
a <- list()
a['blah'] <- 1
a['blah'] <- 2
a
我知道的最简单的技巧是已经提出的那个:在名称后添加 space。这有一个主要缺点:它使按名称使用 select 列以使用 gt
或 kableExtra
自定义它们变得更加困难。但除此之外,它是无害的,因为所有 table 制作的软件包在显示 table.
之前都会去掉白色的 space
阅读您的问题后,我在 modelsummary
中添加了一行代码以自动“填充”模型名称。如果你从 Github 安装(我很快就会发布到 CRAN),你应该可以 运行 这个:
library(remotes)
install_github('vincentarelbundock/modelsummary')
library(modelsummary)
library(kableExtra)
url <- 'https://vincentarelbundock.github.io/Rdatasets/csv/HistData/Guerry.csv'
dat <- read.csv(url)
models <- list()
models[[1]] <- lm(Crime_prop ~ Literacy, data = dat)
models[[2]] <- glm(Crime_prop ~ Literacy + Clergy, family = poisson, data = dat)
models[[3]] <- lm(Crime_pers ~ Literacy, data = dat)
models[[4]] <- glm(Crime_pers ~ Literacy + Clergy, family = poisson, data = dat)
names(models) <- c('ols', 'poisson', 'ols', 'poisson')
cm <- c( '(Intercept)' = 'Constant', 'Literacy' = 'Literacy (%)', 'Clergy' = 'Priests/capita')
cap <- 'A modelsummary table customized with kableExtra'
msummary(models, output = 'kableExtra',
coef_map = cm, stars = TRUE,
title = cap, gof_omit = 'IC|Log|Adj') %>%
add_header_above(c(" " = 1, "Crimes (property)" = 2, "Crimes (person)" = 2))
PS:如果您有功能请求,请在 Github 上提出问题:https://github.com/vincentarelbundock/modelsummary/issues
我使用 modelsummary()
和 kableExtra()
在 Rmd 文件中生成回归 table(最终输出格式:LaTex 和 HTML)。
I 运行 几个变量组合和模型规范的回归。
通过 kable::add_header_above()
.
对于不同的变量组合,我运行相同的模型(例如OLS & Poisson,或其他)。 因此,为了提高可读性,我想简单地命名模型,例如
names(models) <- c("OLS", "Poisson", "OLS", "Poisson", ...)
而不是
names(models) <- c("OLS 1", "Poisson 1", "OLS 2", "Poisson 2", ...)
但是,modelsummary()
以某种方式不允许回归命名相同,导致以下错误:
Error: Can't bind data because some arguments have the same name
Backtrace:
1. modelsummary::msummary(...)
2. modelsummary::extract(...)
10. dplyr::mutate(., group = "gof")
12. dplyr:::mutate_cols(.data, ...)
13. DataMask$new(.data, caller_env())
14. .subset2(public_bind_env, "initialize")(...)
17. rlang::env_bind_lazy(...)
18. rlang:::env_bind_impl(.env, exprs, "env_bind_lazy()", TRUE, binder)
和
Error in htmlTable_add_header_above(kable_input, header, bold, italic, :
The new header row you provided has a different total number of columns with the original `kabel()` output.
MWE:
library(modelsummary)
library(kableExtra)
url <- 'https://vincentarelbundock.github.io/Rdatasets/csv/HistData/Guerry.csv'
dat <- read.csv(url)
models <- list()
models[['OLS']] <- lm(Crime_prop ~ Literacy, data = dat)
models[['Poisson']] <- glm(Crime_prop ~ Literacy + Clergy, family = poisson, data = dat)
models[['OLS']] <- lm(Crime_pers ~ Literacy, data = dat)
models[['Poisson']] <- glm(Crime_pers ~ Literacy + Clergy, family = poisson, data = dat)
# build table with `modelsummary`
cm <- c( '(Intercept)' = 'Constant', 'Literacy' = 'Literacy (%)', 'Clergy' = 'Priests/capita')
cap <- 'A modelsummary table customized with kableExtra'
tab <- msummary(models, output = 'kableExtra',
coef_map = cm, stars = TRUE,
title = cap, gof_omit = 'IC|Log|Adj')
# customize table with `kableExtra`
tab %>%
# column labels
add_header_above(c(" " = 1, "Crimes (property)" = 2, "Crimes (person)" = 2))
插件:
一种解决方法是在模型名称中添加 space " "
,然后再使用 modelsummary
:
names(models) <- c("OLS", "Poisson", "OLS ", "Poisson ", ...)
对于少数模型规格和变量组合,手动这很容易实现。 但是,首选可以动态适应给定设置的解决方案,即也适用于以下情况:
names(models) <- c("OLS", "Poisson", "GLM", "Poisson", ...)
而不是
names(models) <- c("OLS 1", "Poisson 1", "GLM 2", "Poisson 2", ...)
更新:
使用@Vincent 提供的更新包版本,对于存储在嵌套列表中的模型,例如如果它们在循环中或通过 lapply(..., FUN).
添加到子列表models <- NA
models <- list()
models[["a"]][["OLS"]] <- lm(Crime_prop ~ Literacy, data = dat)
models[["a"]][["Poisson"]] <- glm(Crime_prop ~ Literacy + Clergy, family = poisson, data = dat)
models[["b"]][["OLS"]] <- lm(Crime_pers ~ Literacy, data = dat)
models[["b"]][["Poisson"]] <- glm(Crime_pers ~ Literacy + Clergy, family = poisson, data = day)
# ...
models_unlisted <- unlist(models, recursive=FALSE)
names(models_unlisted) <- c('ols', 'poisson', 'ols', 'poisson')
cm <- c( '(Intercept)' = 'Constant', 'Literacy' = 'Literacy (%)', 'Clergy' = 'Priests/capita')
msummary(models_unlisted, output = 'kableExtra', statistic_vertical = FALSE,
coef_map = cm, stars = TRUE, gof_omit = 'IC|Log|Adj') %>%
add_header_above(c(" " = 1, "Crimes (property)" = 2, "Crimes (person)" = 2))
目前,您的 MWE 中的第 3 个和第 4 个模型覆盖了前两个,因此 models
列表中只有两个元素,这会给您带来 different total number of columns
错误。
如果只是为了提高可读性,您可以在第 3 和第 4 个模型的名称后添加 space,其余部分应该可以很好地显示。
models[['OLS ']] <- lm(Crime_pers ~ Literacy, data = dat)
models[['Poisson ']] <- glm(Crime_pers ~ Literacy + Clergy, family = poisson, data = dat)
感谢提问。另一位发帖人是对的:您在 MWE 下的解决方案将永远行不通,因为它涉及 R
语言的基本功能。分配给列表中的相同名称会覆盖以前的值。参见:
a <- list()
a['blah'] <- 1
a['blah'] <- 2
a
我知道的最简单的技巧是已经提出的那个:在名称后添加 space。这有一个主要缺点:它使按名称使用 select 列以使用 gt
或 kableExtra
自定义它们变得更加困难。但除此之外,它是无害的,因为所有 table 制作的软件包在显示 table.
阅读您的问题后,我在 modelsummary
中添加了一行代码以自动“填充”模型名称。如果你从 Github 安装(我很快就会发布到 CRAN),你应该可以 运行 这个:
library(remotes)
install_github('vincentarelbundock/modelsummary')
library(modelsummary)
library(kableExtra)
url <- 'https://vincentarelbundock.github.io/Rdatasets/csv/HistData/Guerry.csv'
dat <- read.csv(url)
models <- list()
models[[1]] <- lm(Crime_prop ~ Literacy, data = dat)
models[[2]] <- glm(Crime_prop ~ Literacy + Clergy, family = poisson, data = dat)
models[[3]] <- lm(Crime_pers ~ Literacy, data = dat)
models[[4]] <- glm(Crime_pers ~ Literacy + Clergy, family = poisson, data = dat)
names(models) <- c('ols', 'poisson', 'ols', 'poisson')
cm <- c( '(Intercept)' = 'Constant', 'Literacy' = 'Literacy (%)', 'Clergy' = 'Priests/capita')
cap <- 'A modelsummary table customized with kableExtra'
msummary(models, output = 'kableExtra',
coef_map = cm, stars = TRUE,
title = cap, gof_omit = 'IC|Log|Adj') %>%
add_header_above(c(" " = 1, "Crimes (property)" = 2, "Crimes (person)" = 2))
PS:如果您有功能请求,请在 Github 上提出问题:https://github.com/vincentarelbundock/modelsummary/issues