Search code examples
rr-forestplot

How to make multiple elements italic in foresplot()


Similar questions have been asked multiple times (here, here and here). However, I don't get it to work in my case.

So I have this code (see below) and I want to make all elements from the "column" Gene italic, except the header (Gene) and the summary(Cancer).

Using expression(italic()) raises an could not find function "italic" Error. I guess, I have to use fp_txt_italic() or txt_gp here somehow, but I just don't get how they work. Maybe someone could enlighten me :).

My code (simplified, since the original is a bit more complex):

library(forestplot)
library(dplyr)


mean <- c(0.9, 1.0, 1.1, 1.0 )
lower <- c(0.8, 0.9, 1.0, 0.9 )
upper <- c(1.0, 1.1, 1.2, 1.1 )
gene <- c("TP53", "KRAS", "CBP", "Cancer")
p_value <- c(0.06, 0.05, 0.01, 0.05 )
n_pos <- c(30, 40, 35, 50)
n_neg  <- c(470, 460, 465, 450)


base_data <- tibble(mean = mean,
                    lower = lower,
                    upper = upper,
                    gene = gene,
                    n_pos = n_pos,
                    n_neg = n_neg,
                    p_value = p_value)


base_data |>
  filter(gene != "Cancer") |>
  forestplot(labeltext = c(gene, n_pos, n_neg, p_value),
             xlog = TRUE,
             vertices = TRUE,
             txt_gp = fpTxtGp(
               label = list(
                 grid::gpar(fontface = "italic"),
                 grid::gpar()))) |>
  fp_append_row(mean  = filter(base_data, gene == "Cancer")$mean,
                lower = filter(base_data, gene == "Cancer")$lower,
                upper = filter(base_data, gene == "Cancer")$upper,
                gene = filter(base_data, gene == "Cancer")$gene,
                n_pos = filter(base_data, gene == "Cancer")$n_pos,
                n_neg = filter(base_data, gene == "Cancer")$n_neg,
                p_value = filter(base_data, gene == "Cancer")$p_value,
                is.summary = TRUE) |>
  fp_add_header(gene = c("Gene\n"),
                n_pos = c("n(mutated)\n"),
                n_neg = c("n(wildtype)\n"),
                p_value = c("p\n")) |>
  fp_set_zebra_style("#EFEFEF") |>
  fp_add_lines() |>
  fp_decorate_graph(graph.pos = 2)

Solution

  • Following this answer you can use the txt_gp= argument of forestplot to

    Set the fonts etc for all text elements.

    using an object of class fpTxtGp. To create this object you can use the fpTxtGp() function which via the label= argument allows to set the fonts etc. for the text labels using grid::gpar(). Besides setting one font etc. for all text labels you can set the fonts individually for each column or for each element.

    In the code below I target the columns by passing a 2 element list, i.e. for the first column I set fontface = "italic" while for the second column I use the defaults.

    library(forestplot)
    library(tidyverse)
    
    base_data |>
      filter(gene != "Cancer") |>
      forestplot(
        labeltext = c(gene, p_value),
        xlog = TRUE,
        vertices = TRUE,
        txt_gp = fpTxtGp(
          label = list(
            grid::gpar(fontface = "italic"),
            grid::gpar()
          )
        )
      ) |>
      fp_append_row(
        mean = filter(base_data, gene == "Cancer")$mean,
        lower = filter(base_data, gene == "Cancer")$lower,
        upper = filter(base_data, gene == "Cancer")$upper,
        gene = filter(base_data, gene == "Cancer")$gene,
        p_value = filter(base_data, gene == "Cancer")$p_value,
        is.summary = TRUE
      ) |>
      fp_add_header(
        gene = c("Gene\n"),
        p_value = c("p\n")
      ) |>
      fp_set_zebra_style("#EFEFEF") |>
      fp_add_lines() |>
      fp_decorate_graph(graph.pos = 2)