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

1

8

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.

Ammonic answered 2/10, 2019 at 15:6 Comment(1)
See this SO question for a more refined/detailed version. Any advice is greatly appreciated!Ammonic
K
1

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

Katz answered 2/10, 2019 at 16:1 Comment(12)
Thanks for your LaTex reprex: graphics path, caption and referencing now work fine! As in tex.stackexchange.com/questions/272475/… I tried citing as \cite{R-base}. In a simple markdown document, adding \bibliography{references.bib} works, but then show [?] in PDF. Compiling the keep_texed .tex-file with pdflatex did not solve this. Also, adding additionally \bibliographystyle{apa} results in error: ! Undefined control sequence. <argument> \protect \astroncite {{R CoreTeam}}{2018}. Do you have any recommendations?Ammonic
The new column alignment works well in a simple markdown file, but not in a report with thesisdown: ,valign=t yields error "tlmgr search --file --global '/biblatex-dm.cfg' ! Package xkeyval Error: valign' undefined in families Gin'." and adding \begin{tabular}{@{} L{6cm} L{8.5cm} @{}} yields error "tlmgr search --file --global '/biblatex-dm.cfg' ! Package array Error: Illegal pream-token (L): `c' used." Any ideas how to solve?Ammonic
@Ammonic Can you share a .tex file that reproduces your problems? (I'm not a markdown person, but I could have a look at the problems from the tex side)Katz
the issue seems to be at the interplay between markdown/bookdown and LaTex, so LaTex does not seem much of the problem here. Even for a tabular environment as simple as \begin{tabular}{@{} c m{9cm} @{}} bookdown yields the following error: ! LaTeX Error: Illegal character in array arg. See the LaTeX manual or LaTeX Companion for explanation. Type H <return> for immediate help. ... l.201 \begin{tabular}{@{} c m{9cm} @{}}Ammonic
@Ammonic Can you nevertheless share the .tex file to find out where the problem comes from?Katz
sure, any advice on how to easiest share the index.tex and index.log with you? many thanksAmmonic
@Ammonic if the .tex file is too long to add it to your question, you could share it via pastebin.com or similar services.Katz
index.tex pastebin.com/G3S5zKBL . index.log pastebin.com/7sJPXZdmAmmonic
@Ammonic Thanks. The array package seems not to be loaded in your code, this causes the error messageKatz
Thank you for your hint. array package is loaded in the YAML header in the top of the markdown document, see here please: pastebin.com/0HYhqi6vAmmonic
@Ammonic No idea about the markdown, just that the package is missing from pastebin.com/raw/G3S5zKBLKatz
please see a more elaborate version of this question here: #60059192 many thanks for any help you can provide!Ammonic

© 2022 - 2024 — McMap. All rights reserved.