flextable:使用来自 2 列的数据和列表用于比较嵌入 ggpplots 作为每行的单个图

问题描述

https://ardata-fr.github.io/flextable-book/cell-content-1.html#base-plots-and-ggplot-objects 之后,我想要小块地。

   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()
}

构建数据集,嵌入数据列表。

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

用绘图替换单元格中的 ggplot 数据。

  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

因此,我有 2 列带图。

enter image description here

我想知道如何更改代码,以便生成一列而不是两列:每行一个 ggplot,叠加了两个几何体在这种情况下为“mpg”和“disp”,但这可能数据集中存在两个群体,例如两家公司、两个物种)。我希望我可以在每个单元格中并排绘制两个箱线图或在一个单元格中并排绘制两个小提琴图。是否有一种简单的方法可以将两列中的两个列表组合起来,以生成一列,每个记录都有一个图,显示来自两个列表(两层)的数据?

解决方法

不幸的是,我缺乏通过 data.table 进行数据整理的 data.table 技能,但是利用 tidyverse 可以这样实现:

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,"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[,"box")])
ft <- compose(ft,j = c("box"),use_dot = TRUE
)
ft

enter image description here