在Rmarkdown转Word文档时,使用flextable自适应调整表格大小会导致表格超出页面边距。

21

嗨,我正在尝试在Rmarkdown .doc文档中使用flextable来格式化表格。我喜欢flextable提供的简单格式选项(但也接受其他类似的包),但发现某些基本功能并不总是可用。

我希望将表格适应Word文档的宽度,以便如果需要,文本将在列内换行以适应,但如果页面上有可用的空间,则会使列变宽,但不至于使列太宽以至于无法显示所有数据。

我制作了一个示例以展示我的问题。默认情况下,所有列都具有相同的宽度,并且文本被换行以适合,但因此浪费了空间。我想通过autofit将列调整到数据大小,但这样会使列变得太宽而超出屏幕。我希望在mpgvscarb更宽但仍然发生一些文本换行的中间状态。例如,我想要这个:

Desired output

显然,我可以使用flextable::width手动更改宽度,但我的表格是通过自动化过程生成的,因此我不知道每列应该有多宽。

以下是展示问题的示例,无论使用还是不使用autofit都会出现问题。

---
title: "TestTable"
output: word_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)


suppressWarnings(suppressPackageStartupMessages({library(knitr)
  library(pander)
  library(flextable)
  library(tidyverse)
library(flextable)}))
```

## Normal Table
Without extra formatting, wraps text so that it fits on the page, but there is no need for column widths to be equal and could be wider on the page

```{r, echo=FALSE, results = 'asis' }
mydata <- mtcars %>% head(3) %>% select(mpg, cyl, hp,vs, gear, carb) %>%
  mutate(mpg = paste0(mpg, "with extra stuff to make long"),
         vs = paste0(vs, "+ extra stuff"),
         carb = paste0(carb, "also with extra stuff to make longer"))

mytable <- mydata  %>% flextable(theme_fun = theme_box)

mytable

```
## Table With autofit  
But table with autofit goes off the edges of the page


```{r, echo=FALSE, results = 'asis' }

mytable %>% autofit()

```


## Table With autofit and manual breaks
And if manual breaks are inserted into the column autofit makes the columns too wide an they still go off the edges of the page

```{r, echo=FALSE, results = 'asis' }

mydataWithBreaks <- mtcars %>% head() %>% select(mpg, cyl, hp,vs, gear, carb) %>%
  mutate(mpg = paste0(mpg, "\nwith extra stuff\n to make long"),
         vs = paste0(vs, "+\n extra stuff"),
         carb = paste0(carb, "\nalso with extra stuff\n to make longer"))

mydataWithBreaks  %>% flextable(theme_fun = theme_box)%>% autofit()



```
3个回答

40

我已经编写了一个适应页面的表格的函数,目前运行良好。但是我仍然有些惊讶,没有内置函数可以执行此操作,例如,自动获取页面宽度等信息。因此,如果有人知道任何方法,请尽管告诉我。

FitFlextableToPage <- function(ft, pgwidth = 6){

  ft_out <- ft %>% autofit()

  ft_out <- width(ft_out, width = dim(ft_out)$widths*pgwidth /(flextable_dim(ft_out)$widths))
  return(ft_out)
}

3
我希望早些时候就找到了这个答案,因为这是唯一对我始终有效的解决方案。 - LumpyGrads
这里也是一样的。最好的解决方案。 - José

11
FYI - 今天我也遇到了同样的问题,并使用了您的代码(谢谢)。但是它仍然困扰着我,因为我不能完全理解它。我注意到在Officedown包的网站上(同一作者; https://github.com/davidgohel/officedown)他们使用了set_table_properties(layout = "autofit"),所以我尝试了这个方法。出于某种原因,它按照预期工作了!我还使用了默认设置的officedown,所以也许两者很好地配合使用。

1
欢迎来到StackOverflow;这是一个回答还是评论?请查看SO指南[回答]。 - Peter
1
在我看来,这应该是被接受的答案,因为它是内置的,不需要定义额外的函数。 - rempsyc

9
我遇到了类似的问题,使用autofit()函数后出现错误。当在管道的末尾添加fit_to_width()函数时,问题得到解决。
使用上述示例中的部分内容,以下代码将自适应列宽,然后调整为适合第二个参数中给定的最大表格宽度(这里我选取1/2英寸文档边距):

mytable %>% autofit() %>% fit_to_width(7.5)

其中一点需要注意的是,对于我的某些表格而言,添加 fit_to_width() 函数会大幅减慢渲染过程。

对于这些表格,我使用了 @bumbledore 建议的 set_table_properties(layout = "autofit") ,效果非常好(值得一提的是,我还使用了默认设置的 officedown)。


5
fit_to_width()将缩放字体大小,set_table_properties(layout = "autofit")将文本包装以适应表格。 - Alpi Murányi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接