flextable:嵌入 ggpplots 使用来自 2 列的数据和列表(用于比较)作为每行的单个图
flextable: embed ggpplots using data from 2 columns with lists (for comparing) as a single plot per row
关注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 列带图。
我想知道如何更改代码,以便生成一列而不是两列:每行一个 ggplot,叠加两个 geom(在本例中为“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, 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
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
关注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 列带图。
我想知道如何更改代码,以便生成一列而不是两列:每行一个 ggplot,叠加两个 geom(在本例中为“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, 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
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