Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R markdown: How to create a table with images and text which should be knitted as PDF?

I would like to include a table with 2 columns including images and text (image descriptions) in PDF report compiled with R markdown. In doing so, I have the following requirements for my table:

  • width: fixed column or table width

  • alignment: content alignment in columns

    • top center alignment of an image in column 1
    • top left alignment of text in column 2
  • text content: is at best easy and good to read also in code

  • text formatting:

    • text formatting required, at best using markdown syntax, i.e, bold
    • linebreaks required
  • image path: as images are stored in a subdirectory, at best use abbreviated image paths, like

    • figpath <- "Folder/Subfolder/" and then
    • fig1 <- paste0(figpath, "image1.png")
  • caption: table caption is required

  • citations: adding references to the table is required, i.e., like [@R-base]

  • referencing: the table elsewhere is required

In ideal, the table would look like this:

enter image description here

I made several attempts based on LaTex syntax, markdown syntax and R markdown syntax (with kable and kableExtra), see MWEs below. However, none of the approaches yield a satisfying result. The LaTex approach comes closest but does not allow to include citations.

The table with images should later be included in a report (thesis) compiled with huskydown, which is related to thesisdown/bookdown. Any help is greatly appreciated!

Table below summarizes my approaches, MWEs provided below (for improved LaTex MWE see reply by @samcarter)

enter image description here

Latex approach

YAML header:
header-includes:
  \usepackage{array}
  \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}}


\begin{table}[H]
\centering
\caption{My caption}
\begin{tabular}{@{} C{6cm} L{9cm} @{}}
\\
     \toprule
       Image & Description \\
     \toprule 
      \includegraphics[width=60mm]{Folder/Subfolder/image1.png} &
       \textbf{Lorem ipsum dolor sit amet} [@R-base] \linebreak mauris mauris sollicitudin malesuada amet.\\
      & \\
      \hline
      & \\
      \includegraphics[width=60mm]{Folder/Subfolder/image2.png} &
      \textbf{Lorem ipsum dolor} [@R-bookdown]\linebreak sit amet, mauris mauris sollicitudin malesuada amet. \
\end{tabular}
\end{table}
  • Pro:

    • vertical alignment: of column 1 working somehow correctly
    • caption: easy to add
    • text formatting: linebreaks feasible with "\linebreak" (but does not work so nicely due to block text)
    • generally versatile coding of tables in LaTex
  • Con:

    • vertical alignment: of column 2 not working correctly - SOLVED for LaTex and simple markdown file ONLY, NOT solved for bookdown/thesisdown
    • text content: adding text content to LaTex table is rather ugly
    • text formatting: only latex formatting works, i.e. "\textbf{}"
    • Simple markdown text formatting like **bold** (obviously) does not work in LaTex table
    • image path: can not include abbreviated image paths (SOLVED)
    • citations: do NOT work in LaTex table - NOT solved
    • referencing: how to reference the LaTex table? (SOLVED)

Markdown approach (NO SOLUTION YET)

Table: Caption of my table
<!-- Table: (\#tab:myTable-reference) Caption of my table -->

| Image | Description |
| :-------: | :----------- |
| ![](Folder/Subfolder/image1.png){#id .class height=50%} | **Image description** [@R-base]  <br/>Lorem ipsum dolor sit amet, ...          |
| ![](Folder/Subfolder/image2.png){#id .class height=50%} | **Image description** [@R-bookdown] <br/>Lorem ipsum dolor sit amet, ...           |
|                  |             |
  • Pro:

    • caption: easy to add
    • vertical alignment: of column 1 working correctly
    • text formatting: simple markdown text formatting like **bold** works well
    • citations: like [@R-bookdown] work well in markdown table
  • Con:

    • vertical alignment: of column 2 not working correctly
    • text content: adding text content to markdown table is rather ugly
    • text formatting: linebreaks NOT feasible with <br/>
    • image path: can not include abbreviated image paths
    • referencing: how to reference table in simple markdown file? In bookdown one can label the table with Table: (\#tab:md-table) My caption and reference it with \ref{tab:md-table}. But how about in a simple md file?

kable approach (NO SOLUTION YET)

Refer to this table with [foo] or  \@ref(tab:foo)  or \@ref(fig:foo).

(ref:foo-caption) caption
(ref:foo-scaption) short caption

```{r foo, echo=FALSE, out.width='90%', fig.align = "center", fig.cap='(ref:foo-caption)', fig.scap='(ref:foo-scaption)', results='asis'}
library(stringi)
some_text <- stri_rand_lipsum(1)
some_text <- paste("**Image description**", "[@R-bookdown]", "<br/>", some_text)
figpath <- "Folder/Subfolder/"
dat <- data.frame(
  Image = c(
    paste0("![](", figpath, "image1.png){#id .class height=120px}"),
    paste0("![](", figpath, "image2.png){#id .class height=120px}")
  ),
  Description = c(
  some_text, # TEXT IMAGE 1
  some_text  # TEXT IMAGE 2
  )
)
library(knitr)
kable(dat, format = 'pandoc')
```
  • Pro:

    • vertical alignment: of column 1 is working correctly
    • text content: adding text content to kable table is rather nice
    • image path: can include abbreviated image paths
    • referencing: easy to reference with label of code chunk
    • easy coding of tables in R markdown; md code of table is nicely structured/readable
    • text formatting: simple markdown text formatting like **bold** works well
    • citations: work well in kable table
  • Con:

    • width: of column 2 far too wide
    • vertical alignment: of column 2 not working correctly
    • text formatting: linebreaks NOT feasible with <br/>
    • caption: not working as usual

kableExtra approach (NO SOLUTION YET)

Refer to this table with [foo2] or  \@ref(tab:foo2)  or \@ref(fig:foo2).

(ref:foo2-caption) caption
(ref:foo2-scaption) short caption

```{r foo2, echo=FALSE, out.width='90%', fig.align = "center", fig.cap='(ref:foo2-caption)', fig.scap='(ref:foo2-scaption)', results='asis'}
library(kableExtra)
kable(dat) %>%
  kable_styling(full_width = F) %>%
  column_spec(1, width = "30em")
```
  • Con:
    • width: of column 2 far too wide
    • images: do not show

I am happy to provide an Rmd file with my approaches as well as the generated PDF if of any help.

like image 342
mavericks Avatar asked Oct 02 '19 15:10

mavericks


People also ask

How do I knit to PDF in R?

When you press “Knit to PDF” in RStudio, it converts your R Markdown document into LaTeX. Download MiKTeX from here: https://miktex.org/download • Run the installer, and restart your computer. Open an R Markdown file in RStudio, and try knitting to PDF. You may be prompted to install some packages.

How do I create a PDF in R Markdown?

To transform your markdown file into an HTML, PDF, or Word document, click the “Knit” icon that appears above your file in the scripts editor. A drop down menu will let you select the type of output that you want. When you click the button, rmarkdown will duplicate your text in the new file format.

How do I insert an image into R Markdown?

To add an image in markdown you must stop text editing, and you do this with the command [Alt text] precedeed by a ! Then you have to add the path to the image in brackets. The path to the image is the path from your directory to the image.


1 Answers

For your latex approach:

  • vertical alignment: of column 2 not working correctly

    you get your desired alignment by combining a p column (instead of the m column you used) and a top aligned image. For the top aligned image add \usepackage[export]{adjustbox} to your header includes and ,valign=t to the image options

  • image path: can not include abbreviated image paths

    Using image paths is easy with \graphicspath{{./older/Subfolder/}} in your header includes

other comments:

  • using [H] as floating specifier is usually not a good idea. This basically guarantees a suboptimal image placement. Instead use [htbp] to ensure that latex find the best possible locatiosn for your image.

  • don't use \toprule within the table, that's what \midrule is made for

  • don't use \hline when you load the booktabs package which provides alternatives with superior spacing



\documentclass{article}

\usepackage{booktabs}
\usepackage{graphicx}
\usepackage{array}
\usepackage[export]{adjustbox}
\newcolumntype{L}[1]{>{\raggedright\arraybackslash}p{#1}}


\graphicspath{{./older/Subfolder/}}

\begin{document}

\begin{table}[htbp]
\centering
\caption{My caption}
\label{foo}
\begin{tabular}{@{} L{6cm} L{8.5cm} @{}}
     \toprule
       Image & Description \\
     \midrule 
      \includegraphics[width=60mm,valign=t]{example-image-duck} &
       \textbf{Lorem ipsum dolor sit amet} [@R-base] \linebreak mauris mauris sollicitudin malesuada amet.\\
            \midrule
      \includegraphics[width=60mm,valign=t]{example-image-duck} &
      \textbf{Lorem ipsum dolor} [@R-bookdown]\linebreak sit amet, mauris mauris sollicitudin malesuada amet. \\
      \bottomrule
\end{tabular}
\end{table}

\ref{foo}

\end{document}

enter image description here

like image 85
samcarter_is_at_topanswers.xyz Avatar answered Oct 13 '22 07:10

samcarter_is_at_topanswers.xyz