【问题标题】:How to decimal-align regression coefficients in Latex table output in rmarkdown document如何在 rmarkdown 文档中对 Latex 表输出中的回归系数进行小数对齐
【发布时间】:2016-08-15 23:35:50
【问题描述】:

rmarkdown 文档中,我正在创建一个包含标准误差的回归系数的 Latex 表,以比较单个表中的多个回归模型。我想垂直对齐每个模型的系数,以便系数的小数点垂直排列在一列。

我正在使用texreg 创建表。默认情况下,系数不是小数对齐的(相反,每个字符串都在其列中居中),我正在寻找一种方法来让系数小数对齐。我不喜欢texreg,所以如果您有使用xtablepanderstargazer 或任何其他方法的解决方案,我也会对此感兴趣。理想情况下,我想要一个可以在rmarkdown 文档中以编程方式实现的解决方案,而不是在将文档呈现为.tex 文件后调整latex 标记。

作为奖励,我还希望能够在表格标题中添加换行符。例如,在texreg 中,您可以使用custom.model.names 参数来设置每个回归模型的列名。在下面的示例中,我希望将"Add Horsepower and AM" 分成两行,这样列就不需要那么宽了。我试过"Add Horsepower \newline and AM",但这只是在最后的列标题中添加了“ewline”,而“\n”被忽略了。

这是一个可重现的例子:

---
title: "Regression Table"
author: "eipi10"
date: "August 15, 2016"
header-includes:
    - \usepackage{dcolumn}
output: pdf_document
---

```{r, echo=FALSE, message=FALSE, results="asis"}
library(texreg)

m1 = glm(mpg ~ wt + factor(cyl), data=mtcars)
m2 = glm(mpg ~ wt + factor(cyl) + hp + factor(am), data=mtcars)

texreg(list(m1,m2),
       single.row=TRUE, 
       custom.model.names=c("Base Model", "Add Horsepower and AM"),
       custom.coef.names=c("Intercept", "Weight","Cyl: 6", "Cyl: 8", "Horsepower","AM: 1"))
```

输出表如下所示:

【问题讨论】:

  • 您在插入换行符时可能需要一些额外的反斜杠,例如"\\newline"
  • 那也行不通。我得到“添加马力和 AM”。我还尝试了`\\`,它只是在“Horsepower”和“and”之间添加了一个额外的空格。
  • 嗯,开始在 tex.stackexchange.com 中查找,但没有走那么远。
  • 你试过dcolumn = TRUE 参数吗?这使用dcolumn 包提供小数点对齐。您可能希望将它与参数use.packages = FALSE 结合使用,以避免在表浮动之前出现任何前导命令。这些都记录在帮助文件和 JSS 文章中。
  • 我用这个方法! Misplaced \noalign. \hline ->\noalign {\ifnum 0=`}\fi \hrule \@height \arrayrulewidth \futurelet... l.403 D\{)\}\{)\}\{11)3\} \} \hline得到一个Pandoc错误。

标签: r latex regression r-markdown texreg


【解决方案1】:

这需要相当多的争论,但我认为它可以让你接近你想要的。我用xtable。主要思想是为每个模型创建两列,一列右对齐(系数),另一列左对齐(标准误差)。所以对于一个有两个模型的表,我们有五列。标题和汇总统计信息显示在跨两列的单元格中。

首先,我们有header.tex,借鉴p. 27 of the xtable vignette

\usepackage{array}
\usepackage{tabularx}
\newcolumntype{L}[1]{>{\raggedright\let\newline\\
\arraybackslash\hspace{0pt}}m{#1}}
\newcolumntype{C}[1]{>{\centering\let\newline\\
\arraybackslash\hspace{0pt}}m{#1}}
\newcolumntype{R}[1]{>{\raggedleft\let\newline\\
\arraybackslash\hspace{0pt}}m{#1}}
\newcolumntype{P}[1]{>{\raggedright\tabularxbackslash}p{#1}}

.Rmd 文件。我从this answer 了解到add.to.row

---
title: "Regression Table"
author: "eipi10"
date: "August 15, 2016"
header-includes:
    - \usepackage{dcolumn}
output: 
  pdf_document:
    includes:
      in_header: header.tex
---

```{r, echo=FALSE, message=FALSE, results="asis"}
library(xtable)
library(broom)   

m1 = glm(mpg ~ wt + factor(cyl), data=mtcars)
m2 = glm(mpg ~ wt + factor(cyl) + hp + factor(am), data=mtcars)

p_val <- c(0, 0.001, 0.01, 0.05, 1)
stars <- sapply(3:0, function(x) paste0(rep("*", x), collapse=""))

make_tbl <- function(model) {
  coefs <- summary(model)$coefficients
  coef_col <- round(coefs[,1], 2)
  se_col <- round(coefs[,2], 2)
  star_col <- stars[findInterval(coefs[,4], p_val)]
  tbl <- data.frame(coef=coef_col)
  tbl$se <- sprintf("(%0.2f)%s", se_col, star_col)
  tbl
}

make_addtorow <- function(row.name, terms) {
  # xtable allows the addition of custom rows. This function
  # makes a row with a one column (which is used for the row
  # names for the model statistics), 
  # followed by two columns that each span two columns.
  paste0(row.name, 
  paste0('& \\multicolumn{2}{C{3cm}}{', 
         terms, 
         '}', 
        collapse=''), 
  '\\\\')
}

tbl1 <- make_tbl(m1)
tbl2 <- make_tbl(m2)
combo <- merge(tbl1, tbl2, by = "row.names", all = TRUE)[,-1]
rownames(combo) <- c("Intercept", "AM: 1", "Cyl: 6", "Cyl: 8", "Horsepower", "Weight")
sum_stats <- round(rbind(glance(m1), glance(m2)), 2)

addtorow <- list()
addtorow$pos <- list(0, 6, 6, 6, 6, 6)
addtorow$command <- c(
  make_addtorow("", c("Base model", "Add Horsepower and AM")),
  make_addtorow("\\hline AIC", sum_stats$AIC), # Draw a line after coefficients
  make_addtorow("BIC", sum_stats$BIC),
  make_addtorow("Log Likelihood", sum_stats$logLik),
  make_addtorow("Deviance", sum_stats$deviance),
  make_addtorow("Num. obs.", sum_stats$df.null + 1)
  )

xtbl <- xtable(combo, add.to.row = addtorow, include.colnames = FALSE,  
               comment = FALSE)
# Specify column alignment for tabularx environment
# We're using the custom column types we created in header.tex
# \hskip specifies the width between columns
align(xtbl) <- c("L{2.5cm}", "R{1.5cm}@{\\hskip 0.1cm}", "L{1.5cm}", 
                           "R{1.5cm}@{\\hskip 0.1cm}","L{1.5cm}")

print(xtbl, 
      tabular.environment = "tabularx", # tabularx takes two arguments
      width = ".60\\textwidth",         # width, and alignment (specified above)
      add.to.row = addtorow, 
      include.colnames = FALSE,
      comment = FALSE)
```

【讨论】:

  • This took quite a bit of wrangling...我担心会是这样。感谢您的回答。对于我们当中的乳胶挑战者(包括我),您能否添加一些文本来解释所有乳胶标记背后的逻辑以及它们如何在xtable 代码中组合在一起?
  • 有什么特别不清楚的部分吗? header.tex 位是我从 xtable 小插图中取出的,老实说,我自己也不太确定那里发生了什么,所以我愿意接受启蒙!我将在代码中添加一些 cmets。
  • 这不是一个清晰的问题。我只是希望对你所做的事情背后的逻辑有一些一般性的cmet。当我尝试在我的实际回归表中实现它并返回任何具体问题时,我将研究代码。
  • tabularx 列类型的一个特性是它们根据列的宽度包装其内容(我编辑了答案以反映这一点)。所以这也可以解决你的换行问题。
  • 感谢您为此所做的工作。我能够在我的实际用例中实现它,并且表格看起来不错。
【解决方案2】:

这是使用broom 的尝试。不过,您仍然需要清理标签。

library(broom)
library(dplyr)
library(pander)
library(tidyr)

m1 = glm(mpg ~ wt + factor(cyl), data=mtcars)
m2 = glm(mpg ~ wt + factor(cyl) + hp + factor(am), data=mtcars)
base <- tidy(m1) %>% select(term, estimate) %>% mutate(type = "base_model")
with_am_hp <- tidy(m2) %>% select(term, estimate) %>% mutate(type = "Add_Horsepower_and_AM")
models <- bind_rows(base, with_am_hp)
formatted_models <- models  %>% spread(type, estimate)

m1_glance <- glance(m1) %>% mutate(type = "base_model")
m2_glance <- glance(m2) %>% mutate(type = "Add_Horsepower_and_AM")
glance_table <- data.frame("Add_Horsepower_and_AM" = unlist(glance(m2)), "base_model" = unlist(glance(m1))) %>% mutate(term = row.names(.))

full_results <- bind_rows(formatted_models, glance_table)
pandoc.table(full_results, justify = "left")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    • 2015-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多