Maria
Maria

Reputation: 319

Break line and bold caption in Kable

How can I break the caption of my PDF table generated with Kable and turn into bold the upper part?

This is the table I generated:

enter image description here

And I need the title to be: bold{Producte interior brut} \breaklinehere {(% de variació interanual, llevat dels casos indicats)}

Here's the dataset and code:

structure(list(...1 = c("Catalunya", "PIB", "Demanda interna1", 
"Demanda externa1", "Espanya", "PIB", "Demanda interna1", "Demanda externa1", 
"Zona euro", "PIB", "Demanda interna1", "Demanda externa1", "PIB d'Alemanya", 
"PIB de França", "PIB d'Itàlia", "Internacional", "PIB de la UE-27", 
"PIB dels EUA", "PIB del Japó"), `2020` = c(NA, -11.9, -7.4, 
-4.5, NA, -11.2, -9, -2.2, NA, -6.1, -5.57, -0.53, -3.8, -7.5, 
-9, NA, -5.6, -2.2, -4.3), `2021` = c(NA, 6.2, 3.8, 2.4, NA, 
6.4, 5.9, 0.5, NA, 5.6, 4.24, 1.36, 3.2, 6.4, 8.3, NA, 5.7, 5.8, 
2.1), `2022` = c(NA, 5.5, 2.7, 2.8, NA, 5.5, 5.12183164381576, 
0.378168356184236, NA, 3.6, 3.76, -0.16, 1.8, 2.5, 3.7, NA, 3.5, 
1.9, 1.1), `1r 2023` = c(NA, 3.2, 1.1, 2.1, NA, 4.1, 1.3, 2.8, 
NA, 1.2, 0.63, 0.57, -0.2, 1, 2.1, NA, 1.1, 1.71772942152937, 
2), `2n 2023` = c(NA, 2.1, 1.2, 0.9, NA, 2, 2.2, -0.2, NA, 0.5, 
0.46, 0.04, 0.1, 1.1, 0.3, NA, 0.4, 2.38237207285343, 1.7), `3r 2023` = c(NA, 
2.1, NA, NA, NA, 1.8, 1.6, 0.2, NA, 0.1, NA, NA, -0.4, 0.7, 0, 
NA, 0.1, 3, 1.2)), row.names = c(NA, -19L), class = c("tbl_df", 
"tbl", "data.frame"))

Table:

p3_1 <- read_xlsx("G:/SUBDIRECCIO-ESTUDIS/CONJUNTURA/INDICADORS MENSUALS/Automatitzacio_IC/proves R/IC_fitxer_RECULL_Maria.xlsx",
                  range = "B5:M24", 1, col_types = c("text", "numeric", "numeric", "numeric", "numeric", "numeric", "numeric", "numeric", "numeric", "numeric", "numeric", "numeric")) [, -c(2,4,5,7,9)] 


    options(knitr.kable.NA = "-")
    
    
    grp_nm <- c("Catalunya", "Espanya", "Zona euro", "Internacional")
    
    p3_1 <- 
      p3_1 %>% 
      mutate(grp = ifelse(...1 %in% grp_nm, ...1, NA),
             ...1 = case_when(str_detect(...1, "interna1") ~ "$\\text{Demanda interna}^1$",
                              str_detect(...1, "externa1") ~ "$\\text{Demanda externa}^1$",
                              TRUE ~ ...1))%>%
      fill(grp) %>% 
      filter(!...1 %in% grp_nm) %>% 
      select(grp, everything())
      
    
    kable(p3_1[, -1],
          align = "lrrrrrr",
          col.names = c("", names(p3_1[-(1:2)])),
          booktabs=TRUE,
          digits=1,
          format.args = list(big.mark="."),
          linesep = "" ,
          caption="Producte interior brut (\\% de variació interanual, llevat dels casos indicats)", escape = FALSE) %>%
      add_header_above(c("", "Any" = 3, "Trimestre" = 3), bold=T) %>%
      kable_styling(latex_options=c("HOLD_position","scale_down"), position="center") %>% 
      column_spec(1, width="4cm") %>% 
      column_spec(2:7, width="2cm") %>% 
      row_spec(0, bold = T) %>% 
      pack_rows(index = table(p3_1$grp), background = "#E0E0E0", latex_gap_space = "0pt") %>%
      footnote(general="Idescat; Eurostat; INE; BEA; ESRI; Agència Estatal d'Administració Tributària.", general_title = "Font:", footnote_as_chunk = T,)  %>%
      footnote(general="$^{A}$Dada avançada. $^{1}$Contribució al creixement. $^{2}$Sèrie original corregida d'efectes de calendari.
               $^{3}$En valors constants. Exclou estacions de servei.",  escape = F, general_title = "Nota:", threeparttable = TRUE, footnote_as_chunk = T,)

yaml:

output:
  pdf_document:
    number_sections: no
    toc: no
    toc_depth: 3
    df_print: paged
    fig_caption: yes
header-includes: 
    \usepackage{booktabs} 
    \usepackage{floatrow} 
    \floatsetup[figure]{capposition=top}
    \floatsetup[table]{capposition=top}
    \usepackage[document]{ragged2e}
    \usepackage[singlelinecheck=false]{caption}   

Upvotes: 0

Views: 514

Answers (2)

Peter
Peter

Reputation: 12739

I cannot replicate the errors you mention in the comments to the answer with a minimal example.

However, using your data and code in the question this seems to work.

The main differences are:

  1. use kbl not kable

  2. use \newline rather than \\\\

  3. change in the approach to making only the first part of the caption bold using latex textbf{...}.

    ---
     output:
       pdf_document:
         number_sections: no
         toc: no
         toc_depth: 3
         df_print: paged
         fig_caption: yes
     header-includes: 
         \usepackage{booktabs} 
         \usepackage{floatrow} 
         \floatsetup[figure]{capposition=top}
         \floatsetup[table]{capposition=top}
         \usepackage[document]{ragged2e}
         \usepackage[singlelinecheck=false]{caption} 
    
     ---
    
    
    library(kableExtra)
    library(dplyr)
    library(tidyr)
    library(stringr)
    
    
    
    # Note I have changed the cedilla in França to a c
    
    p3_1 <- 
      structure(list(...1 = c("Catalunya", "PIB", "Demanda interna1", 
    "Demanda externa1", "Espanya", "PIB", "Demanda interna1", "Demanda externa1", 
    "Zona euro", "PIB", "Demanda interna1", "Demanda externa1", "PIB d'Alemanya", 
    "PIB de Franca", "PIB d'Itàlia", "Internacional", "PIB de la UE-27", 
    "PIB dels EUA", "PIB del Japó"), `2020` = c(NA, -11.9, -7.4, 
    -4.5, NA, -11.2, -9, -2.2, NA, -6.1, -5.57, -0.53, -3.8, -7.5, 
    -9, NA, -5.6, -2.2, -4.3), `2021` = c(NA, 6.2, 3.8, 2.4, NA, 
    6.4, 5.9, 0.5, NA, 5.6, 4.24, 1.36, 3.2, 6.4, 8.3, NA, 5.7, 5.8, 
    2.1), `2022` = c(NA, 5.5, 2.7, 2.8, NA, 5.5, 5.12183164381576, 
    0.378168356184236, NA, 3.6, 3.76, -0.16, 1.8, 2.5, 3.7, NA, 3.5, 
    1.9, 1.1), `1r 2023` = c(NA, 3.2, 1.1, 2.1, NA, 4.1, 1.3, 2.8, 
    NA, 1.2, 0.63, 0.57, -0.2, 1, 2.1, NA, 1.1, 1.71772942152937, 
    2), `2n 2023` = c(NA, 2.1, 1.2, 0.9, NA, 2, 2.2, -0.2, NA, 0.5, 
    0.46, 0.04, 0.1, 1.1, 0.3, NA, 0.4, 2.38237207285343, 1.7), `3r 2023` = c(NA, 
    2.1, NA, NA, NA, 1.8, 1.6, 0.2, NA, 0.1, NA, NA, -0.4, 0.7, 0, 
    NA, 0.1, 3, 1.2)), row.names = c(NA, -19L), class = c("tbl_df", 
    "tbl", "data.frame"))
    
    
    
    
        options(knitr.kable.NA = "-")
    
    
        grp_nm <- c("Catalunya", "Espanya", "Zona euro", "Internacional")
    
        p3_1 <- 
          p3_1 |> 
          mutate(grp = ifelse(...1 %in% grp_nm, ...1, NA),
                 ...1 = case_when(str_detect(...1, "interna1") ~ "$\\text{Demanda interna}^1$",
                                  str_detect(...1, "externa1") ~ "$\\text{Demanda externa}^1$",
                                  TRUE ~ ...1))|>
          fill(grp) |> 
          filter(!...1 %in% grp_nm) |> 
          select(grp, everything())
    
    
        kbl(p3_1[, -1],
              align = "lrrrrrr",
              col.names = c("", names(p3_1[-(1:2)])),
              booktabs=TRUE,
              digits=1,
              format.args = list(big.mark="."),
              linesep = "" ,
              caption="\\textbf{Producte interior brut} \\newline (\\% de variació interanual, llevat dels casos indicats)", 
            escape = FALSE) |>
          add_header_above(c("", "Any" = 3, "Trimestre" = 3), bold=T) |>
          kable_styling(latex_options=c("HOLD_position","scale_down"), position="center") |> 
          column_spec(1, width="4cm") |> 
          column_spec(2:7, width="2cm") |> 
          row_spec(0, bold = T) |> 
          pack_rows(index = table(p3_1$grp), background = "#E0E0E0", latex_gap_space = "0pt") |>
          footnote(general="Idescat; Eurostat; INE; BEA; ESRI; Agència Estatal d'Administració Tributària.", general_title = "Font:")  |>
          footnote(general="$^{A}$Dada avançada. $^{1}$Contribució al creixement. $^{2}$Sèrie original corregida d'efectes de calendari.
                   $^{3}$En valors constants. Exclou estacions de servei.",  escape = F, general_title = "Nota:", threeparttable = TRUE)
    
    

Resulting in:

enter image description here

Upvotes: 1

Peter
Peter

Reputation: 12739

As @dufei suggests this can be done with setting arguments of the LaTeX caption package. For example:

---
output: pdf_document
header-includes:
  - \usepackage[font={bf}]{caption} 
  
---

```{r}

library(kableExtra)

    kbl(mtcars[1:3, 1:4],
        caption="Caption in bold. \\\\ With a line break for a second line",
        booktabs = TRUE)

```

The line break is achieved by using LaTeX \\; each backslash needs to be escaped hence \\\\ in the code.

Note the caption package defaults to centring the caption. There are arguments which allow for justification and indentation of the caption if that is preferable. Also the caption package allows you to edit the label and text of the caption separately if you want.

enter image description here

Following OP comment: first line in bold with the second line in plain text can be achieved with...

---
output: pdf_document
header-includes:
  - \usepackage[font={normalfont}]{caption} 
---

```{r}

    kbl(mtcars[1:3, 1:4],
        caption="\\textbf{Caption in bold.} \\\\ With a line break for a second plain text line",
        booktabs = TRUE)

```

enter image description here

Upvotes: 0

Related Questions