[英]Automatically adjust LaTeX table width to fit pdf using knitr and Rstudio
Using Rstudio and knitr to produce latex-tables in pdf, how do I make wide tables fit the page?使用 Rstudio 和 knitr 生成 pdf 格式的乳胶表,如何使宽表适合页面? I'm basically looking for at way to shrink the tables.
我基本上是在寻找缩小表格的方法。
With figures, it is really easy in Knitr using out.width=, but with tables I can't seem find a way to do it.对于数字,在 Knitr 中使用 out.width= 真的很容易,但是对于表格,我似乎找不到办法做到这一点。
Any suggestions?有什么建议么?
\documentclass{article}
\begin{document}
The following tables are too wide to fit the pdf.以下表格太宽,无法容纳 pdf。 I hope there is a simple way to shrink them to fit.
我希望有一种简单的方法可以缩小它们以适应。 In this example I've used tables generated from the xtable(), stargazer() and latex() functions.
在这个例子中,我使用了从 xtable()、stargazer() 和 latex() 函数生成的表。
<<message=FALSE>>=
library(xtable)
library(stargazer)
library(Hmisc)
library(tables)
wide.df <- cbind(iris[1:10,],iris[1:10,],iris[1:10,])
@
<<results='asis'>>=
xtable(wide.df)
@
<<results='asis'>>=
stargazer(wide.df,summary=FALSE)
@
<<results='asis'>>=
latex( tabular( Species ~ (Sepal.Length +Sepal.Length + Sepal.Width + Petal.Length + Petal.Width )*(mean + sd + mean + mean ) , data=iris) )
@
\end{document}
Following Stat-R's suggestions I've tried to use resizebox but can't get it to work:按照 Stat-R 的建议,我尝试使用 resizebox 但无法使其正常工作:
\documentclass{article}
\usepackage{graphicx}
\begin{document}
I've tried to use reshapebox but I am really clueless on how to get it to work in Rstudio/knitr:我试过使用 reshapebox,但我真的不知道如何让它在 Rstudio/knitr 中工作:
<<message=FALSE>>=
library(xtable)
wide.df <- cbind(iris[1:10,],iris[1:10,],iris[1:10,])
@
\resizebox{0.75\textwidth}{!}{%
<<results='asis'>>=
xtable(wide.df)
@
%}
\end{document}
I get this error:我收到此错误:
! File ended while scanning use of \Gscale@box@dd.
sessioninfo()
R version 3.0.0 (2013-04-03)
Platform: i386-w64-mingw32/i386 (32-bit)
locale:
[1] LC_COLLATE=Danish_Denmark.1252 LC_CTYPE=Danish_Denmark.1252 LC_MONETARY=Danish_Denmark.1252 LC_NUMERIC=C
[5] LC_TIME=Danish_Denmark.1252
attached base packages:
[1] splines grid stats graphics grDevices utils datasets methods base
other attached packages:
[1] tables_0.7 Hmisc_3.10-1 survival_2.37-4 stargazer_3.0.1 pgirmess_1.5.7 splancs_2.01-32 spdep_0.5-56 coda_0.16-1 deldir_0.0-22
[10] maptools_0.8-23 foreign_0.8-53 MASS_7.3-26 Matrix_1.0-12 lattice_0.20-15 rgdal_0.8-9 sp_1.0-9 nlme_3.1-109 boot_1.3-9
[19] xtable_1.7-1 scales_0.2.3 plyr_1.8 reshape2_1.2.2 ggplot2_0.9.3.1
loaded via a namespace (and not attached):
[1] cluster_1.14.4 colorspace_1.2-2 dichromat_2.0-0 digest_0.6.3 evaluate_0.4.3 formatR_0.7 gtable_0.1.2 knitr_1.2
[9] labeling_0.1 LearnBayes_2.12 munsell_0.4 proto_0.3-10 RColorBrewer_1.0-5 stringr_0.6.2 tools_3.0.0
You can pass a scalebox
argument to print.xtable
like so你可以通过一个
scalebox
参数print.xtable
像这样
<<results='asis'>>=
print(xtable(wide.df), scalebox='0.75')
@
That doesn't automatically resize the table to fit the page (unfortunately xtable
doesn't support a resizebox
argument) but for many applications the above might be good enough.这不会自动调整表格的大小以适应页面(不幸的是
xtable
不支持resizebox
参数)但对于许多应用程序来说,上述可能已经足够了。
The problem with your code is that xtable
returns the table wrapped in a table
environment and not just a tabular.您的代码的问题在于
xtable
返回包装在table
环境中的table
,而不仅仅是表格。 What you have to wrap in the resizebox
, however, is the tabular
.但是,您必须包装在
resizebox
中的是tabular
。 The only way I can see to get this to work as you want it is to let xtable return only the tabular
, like so:我可以看到让它按照您的意愿工作的唯一方法是让 xtable 只返回
tabular
,如下所示:
\begin{table}
\resizebox{\textwidth}{!} {
<<results='asis'>>=
print(xtable(wide.df), floating=FALSE)
@
}
\end{table}
and then to write the LaTeX code around it manually.然后手动编写围绕它的 LaTeX 代码。
Updating to reflect the changes in code past few years, and the preference for people to typically work in .RMarkdown instead of Rnw file format.更新以反映过去几年代码的变化,以及人们通常使用 .RMarkdown 而不是 Rnw 文件格式工作的偏好。
The kableExtra
package in R is the easiest way for adjusting the size of tables. R 中的
kableExtra
包是调整表大小的最简单方法。 You can scale the width of the table using the function kable_styling(latex_options = "scale_down")
.您可以使用函数
kable_styling(latex_options = "scale_down")
缩放表格的宽度。 This will force the table to the width of the page.这将强制表格达到页面的宽度。
kable(iris[1:5,],
format = "latex", booktabs = TRUE) %>%
kable_styling(latex_options = "scale_down")
For more examples of the kableExtra package, check out the package here:https://haozhu233.github.io/kableExtra/awesome_table_in_pdf.pdf
有关 kableExtra 包的更多示例,请在此处查看该包:https ://haozhu233.github.io/kableExtra/awesome_table_in_pdf.pdf
Here is an example MWE:这是一个示例 MWE:
---
title: "MWE"
author: "Mikey Harper"
date: "7 November 2017"
output: pdf_document
---
```{r setup, include=FALSE}
library(kableExtra)
library(magrittr)
knitr::opts_chunk$set(echo = TRUE)
```
```{r}
# Build the dataframe
wide.df <- cbind(iris[1:10,],iris[1:10,],iris[1:10,])
```
```{r}
# Basic table
knitr::kable(wide.df)
```
```{r}
# Scaled Table
knitr::kable(wide.df, format = "latex", booktabs = TRUE) %>%
kable_styling(latex_options = "scale_down")
```
The following are some typical steps that you can take to shrink the table size.以下是一些可以用来缩小表大小的典型步骤。
\setlength{\tabcolsep}{1pt}
\resizebox{\linewidth}{!}{ %% <-- The most effective way to fit a table / figure
\begin{tabular}
...
...
\end{tabular}
} %resizebox
For text use \\sf
mode to make the text more visible.对于文本,使用
\\sf
模式使文本更加可见。
What about automatically splitting the wide tables to parts just like on the good old 80 character wide VT100 terminals?像在旧的 80 字符宽 VT100 终端上一样自动将宽表拆分为多个部分怎么样? This is usually a good practice for LaTex/docx/odt tables and set by default in pander :
这对于 LaTex/docx/odt 表通常是一个很好的做法,默认情况下在pander 中设置:
> set.caption('Hello Fisher!')
> pander(wide.df)
---------------------------------------------------------
Sepal.Length Sepal.Width Petal.Length Petal.Width
-------------- ------------- -------------- -------------
5.1 3.5 1.4 0.2
4.9 3 1.4 0.2
4.7 3.2 1.3 0.2
4.6 3.1 1.5 0.2
5 3.6 1.4 0.2
5.4 3.9 1.7 0.4
4.6 3.4 1.4 0.3
5 3.4 1.5 0.2
4.4 2.9 1.4 0.2
4.9 3.1 1.5 0.1
---------------------------------------------------------
Table: Hello Fisher! (continued below)
-----------------------------------------------------
Species Sepal.Length Sepal.Width Petal.Length
--------- -------------- ------------- --------------
setosa 5.1 3.5 1.4
setosa 4.9 3 1.4
setosa 4.7 3.2 1.3
setosa 4.6 3.1 1.5
setosa 5 3.6 1.4
setosa 5.4 3.9 1.7
setosa 4.6 3.4 1.4
setosa 5 3.4 1.5
setosa 4.4 2.9 1.4
setosa 4.9 3.1 1.5
-----------------------------------------------------
Table: Table continues below
----------------------------------------------------
Petal.Width Species Sepal.Length Sepal.Width
------------- --------- -------------- -------------
0.2 setosa 5.1 3.5
0.2 setosa 4.9 3
0.2 setosa 4.7 3.2
0.2 setosa 4.6 3.1
0.2 setosa 5 3.6
0.4 setosa 5.4 3.9
0.3 setosa 4.6 3.4
0.2 setosa 5 3.4
0.2 setosa 4.4 2.9
0.1 setosa 4.9 3.1
----------------------------------------------------
Table: Table continues below
--------------------------------------
Petal.Length Petal.Width Species
-------------- ------------- ---------
1.4 0.2 setosa
1.4 0.2 setosa
1.3 0.2 setosa
1.5 0.2 setosa
1.4 0.2 setosa
1.7 0.4 setosa
1.4 0.3 setosa
1.5 0.2 setosa
1.4 0.2 setosa
1.5 0.1 setosa
--------------------------------------
Please see ?pandoc.table
and table.split.table
in ?panderOptions
for more details.请参阅
?pandoc.table
和table.split.table
在?panderOptions
了解更多详情。
The LaTeX package tabulary
is better in fitting a table to the page width. LaTeX 包
tabulary
更适合将表格拟合到页面宽度。 It can be told to break lines for example.例如,它可以被告知要断线。 But I don't know if you can use it with xtable.
但我不知道你是否可以将它与 xtable 一起使用。
Another option might be something like:另一种选择可能是这样的:
my_wrap <- function(x, width) {
x_split <- strwrap(x, width = width, simplify = FALSE)
x_split <- lapply(x_split, paste, collapse = " \\\\ ")
vapply(x_split, function(s) sprintf("\\begin{tabular}[x]{@{}c@{}}%s\\end{tabular}", s),
character(1))
}
applied to all columns that are to wide应用于所有太宽的列
The following works fine for me:以下对我来说很好用:
print(xtable(wide.df), scalebox='0.75', floating=FALSE)
This is especially useful for tables in R Markdown.这对于 R Markdown 中的表格特别有用。
A huxtable
-based solution (my package):一个基于
huxtable
的解决方案(我的包):
library(huxtable)
h <- as_hux(iris)
width(h) <- 0.5
This doesn't guarantee the table won't exceed the specified width, and if so it will overrun.这并不能保证表格不会超过指定的宽度,如果超过,它会溢出。 Possible solutions include changing the font size:
可能的解决方案包括更改字体大小:
font_size(h) <- 8
Or splitting the table:或者拆分表格:
h1 <- h[, 1:5]
h2 <- h[, -(1:5)]
I have an ugly but effective method for doing this in Stargazer.我有一个丑陋但有效的方法来在 Stargazer 中做到这一点。 It looks like it is longer than the approaches above, but if you are reporting regression output, this may be an easier workflow for you as it was for me.
看起来它比上面的方法更长,但是如果您报告回归输出,这对您来说可能是一个更简单的工作流程,就像对我一样。
The function "WrapPageWidthLatex " appends / prepends the resize box code to stargazer output.函数“WrapPageWidthLatex”将调整大小框代码附加到观星者输出中。 It assumes that you've set float = FALSE and I've set up a number of other options to conserve space in my table.
它假定您已经设置了 float = FALSE,并且我已经设置了许多其他选项来节省表中的空间。 The rest is just to clean up the resulting output.
剩下的就是清理结果输出。 "include=FALSE" helps suppress the annoying stargazer citation information in your document.
“include=FALSE”有助于抑制文档中烦人的观星引文信息。 "float = FALSE" helps suppress the latex code that would otherwise make this into a float.
“float = FALSE”有助于抑制乳胶代码,否则会使其成为浮动。 This makes it much easier to append the needed code.
这使得附加所需代码变得更加容易。 "column.sep.width = "0pt"" and "font.size="tiny"" help with get the columns narrower and therefore reducing the need for rescaling.
"column.sep.width = "0pt"" 和 "font.size="tiny"" 有助于使列更窄,从而减少重新缩放的需要。
title: "StackOverflow Example"
author: "Bkay"
date: "6/15/2020"
output:
beamer_presentation:
keep_tex: true
header-includes:
- \usepackage{dcolumn}
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(stargazer)
```
## Slide with R Output
```{r rcodehere, results='asis', warning = FALSE, echo=FALSE}
WrapPageWidthLatex <- function(InputCode){
OutputCode = append("\\resizebox{\\textwidth}{!}{", InputCode)
OutputCode = rlang::prepend("}", OutputCode)
return(OutputCode)
}
x = -10:10
xsqr = x^2
y = 2 + x*3 + 0.2 * xsqr + rnorm(length(x))
model1 = lm(y ~ x)
model2 = lm(y ~ x + xsqr)
cat(
WrapPageWidthLatex(
capture.output(
stargazer(
model1, model2,
align=TRUE,
omit.stat=c("adj.rsq", "ser", "f"),
font.size="tiny",
header=FALSE,
column.sep.width = "0pt",
float = FALSE,
type="latex"
)
)
)
)
```
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.