I create MS Word documents using Rmarkdown and officer/officedown packages. My output is officdown::rdocx_document
.
I have code like this in my Rmarkdown file:
library(flextable)
library(officer)
tables <- list(
flextable(iris),
flextable(mtcars)
# and potentially more tables, the list is dynamic
)
I want to toggle portrait/landscape layout depending on the number of columns of each table. For example, if the number of columns is greater than 5 the page orientation should be landscape, otherwise portrait.
I know that officer
package provides block_section
function, but I don't know how to use it dynamically. Please notice that I don't know how many tables will be there, the list is dynamic.
I tried this, according to the help page of block_section function:
orients <- calculate_page_orient(tables) # a helper that will determine the orientation based on the number of columns in a table
for (i in seq_len(lenght(tables))) {
block_section(prop_section(type = "continuous")
tables[[i]]
block_section(prop_section(page_size = page_size(orient = orients[i])))
}
But it doesn't work. How I can dynamically set the page layout using officer package?
Here is one possible implementation which instead of using block_section
uses !---BLOCK_LANDSCAPE_START/END--->
to set the page layout to landscape and which uses chunk option results='asis'
to dynamically render your tables within a for
loop. Also note that I loop directly over the datasets and do the conversion to a flextable
inside the loop.
---
output: officedown::rdocx_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, fig.cap = TRUE)
library(officedown)
library(officer)
library(flextable)
```
```{r}
tables <- list(
iris,
mtcars
) |>
lapply(head)
```
```{r}
calculate_page_orient <- function(x) {
if (ncol(x) > 5) "landscape" else "portrait"
}
```
```{r results='asis'}
for (tbl in tables) {
orient <- calculate_page_orient(tbl)
if (orient == "landscape") cat("\n\n<!---BLOCK_LANDSCAPE_START--->\n\n")
ft <- flextable(tbl)
ft <- autofit(ft)
flextable_to_rmd(ft)
if (orient == "landscape") cat("\n\n<!---BLOCK_LANDSCAPE_STOP--->\n")
cat("\\newpage\n\n")
}
```