Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flextable: embed ggpplots using data from 2 columns with lists (for comparing) as a single plot per row

Following https://ardata-fr.github.io/flextable-book/cell-content-1.html#base-plots-and-ggplot-objects I would like to have small plots.

   gg_line <- function(z) {
  z <- scale(z)
  z <- na.omit(z)
  z <- data.frame(x = seq_along(z), z = z)
  ggplot(z, aes(x = x, y = z)) +
    geom_line(show.legend = FALSE) +
    theme_void()
}

Build a dataset, embed a list with data.

  dat <- as.data.table(mtcars)
z <- dat[,
         lapply(.SD, function(x) list(gg_line(x))),
         by = c("vs", "am"), .SDcols = c("mpg", "disp")
]

Replace ggplot data in cells with plots.

  ft <- flextable(z)
ft <- compose(ft, 
              j = c("mpg", "disp", "drat"),
              value = as_paragraph(gg_chunk(value = ., height = .15, width = 1)),
              use_dot = TRUE
)
ft

As a result I have 2 columns with plots.

enter image description here

I am wondering how to change the code so that instead of two columns one is produced: one ggplot per row with superimposed two geoms (in this case for "mpg" and "disp" but this could be two groups present in the dataset like two companies, two species). I wish I could plot side by side in each cell two boxplots or two violin plots in one cell. Is there an easy way to combine two lists, from two columns, to generate one column with a single plot per each record that shows data from two lists (two layers)?

like image 925
Jacek Kotowski Avatar asked Oct 28 '25 12:10

Jacek Kotowski


1 Answers

Unfortunately I lack the data.table skills to do the data wrangling via data.table but making use of the tidyverse this could be achieved like so:

library(flextable)
library(ggplot2)
library(tidyr)
library(dplyr)

gg <- function(z, cols, type = "box") {
  z <- z[, cols]
  z <- dplyr::mutate(z, dplyr::across(all_of(cols), scale), x = seq(nrow(z)))
  z <- na.omit(z)
  z <- tidyr::pivot_longer(z, -x)
  
  geom <- switch(type,
                 line = geom_line(aes(x = x), show.legend = FALSE),
                 box = geom_boxplot(aes(x = name), show.legend = FALSE, size = .1))
  ggplot(z, aes(y = value, color = name)) +
    geom +
    theme_void()
}

dat <- mtcars
dat <- dat %>% 
  tidyr::nest(data = -c(vs, am)) %>% 
  dplyr::mutate(
    line = lapply(data, function(x) gg(x, cols = c("mpg", "disp"), "line")),
    box = lapply(data, function(x) gg(x, cols = c("mpg", "disp"), "box"))) %>% 
  dplyr::select(-data)

ft <- flextable(dat[, c("vs", "am", "line")])
ft <- compose(ft, 
              j = c("line"),
              value = as_paragraph(gg_chunk(value = ., height = .15, width = 1)),
              use_dot = TRUE
)
ft

enter image description here

ft <- flextable(dat[, c("vs", "am", "box")])
ft <- compose(ft, 
              j = c("box"),
              value = as_paragraph(gg_chunk(value = ., height = .15, width = 1)),
              use_dot = TRUE
)
ft

enter image description here

like image 117
stefan Avatar answered Oct 30 '25 02:10

stefan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!