简体   繁体   English

使用 knitr 和 Rstudio 自动调整 LaTeX 表格宽度以适合 pdf

[英]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.tabletable.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"
                )
            )
        )
    )    

```

Output:输出: 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM