Вопрос или проблема
Привет! Я делаю много графиков и задумался, делаю ли я это быстро и эффективно. Мне часто нужно создавать визуализации длиной около ~2000 страниц (по одной для каждого единицы анализа).
Я попытался создать простой пример, который записывает в временную директорию.
library(ggplot2)
library(furrr)
library(dplyr)
plan("multisession")
# определяем функцию для построения графиков
plot_graph <- function(dt) {
dt |> ggplot(aes(x = x, y = y)) +
geom_point()
}
# создаем набор данных
a <- 2e3
b <- 1e3
dt <- data.frame(
id = rep(1:a, each = b),
x = runif(a*b),
y = runif(a*b)
)
# создаем список графиков
list_plots <- dt |>
split(f = "id") |>
purrr::map(plot_graph)
# настраиваем временную директорию
dir_out_tmp <- tempdir()
filename_out <- "temp"
# сохраняем графики во временной директории
furrr::future_iwalk(
list_plots,
~withr::with_pdf(
new = fs::path(dir_out_tmp, paste(filename_out, .y, sep = "-"), ext = "pdf"),
width = 15,
height = 8,
code = plot(.x)
)
)
# проверяем наличие файлов
files_temp <- fs::path(dir_out_tmp, paste(filename_out, names(list_plots), sep = "-"), ext = "pdf")
stopifnot(all(fs::file_exists(files_temp)))
# комбинируем графики
qpdf::pdf_combine(
input = files_temp,
output = fs::path(dir_out_tmp, filename_out, ext = "pdf")
)
В основном, код сохраняет отдельные графики в временной директории, а в реальных приложениях объединяет их, чтобы сохранить в фактической выходной папке.
Это довольно быстро, но меня интересует, существуют ли инструменты, чтобы просто сохранить многостраничный pdf непосредственно из списка графиков?
Ответ или решение
Вопрос о том, как эффективно сохранять многостраничные графики в R, действительно актуален, особенно когда требуется создать множество графиков, таких как в вашем примере на 2000 страниц. Ваш подход с использованием furrr
для параллельной обработки и сохранения отдельных графиков в формате PDF вполне разумен. Тем не менее, есть несколько альтернативных подходов, которые помогут упростить процесс и снизить количество промежуточных файлов.
Вот улучшенный способ сохранения многостраничного PDF документа непосредственно из списка графиков, минуя необходимость сохранения отдельных файлов:
1. Использование gridExtra
и pdf()
:
Вы можете использовать пакет gridExtra
, чтобы объединить все графики в одном PDF-файле. Вот пример, как это можно сделать:
library(ggplot2)
library(gridExtra)
# Определим функцию рисования графиков
plot_graph <- function(dt) {
ggplot(dt, aes(x = x, y = y)) +
geom_point()
}
# Создаем датасет
a <- 2e3
b <- 1e3
dt <- data.frame(
id = rep(1:a, each = b),
x = runif(a * b),
y = runif(a * b)
)
# Создаем список графиков
list_plots <- split(dt, f = dt$id) %>%
lapply(plot_graph)
# Путь для сохранения итогового PDF
output_pdf <- file.path(tempdir(), "combined_plots.pdf")
# Создаем PDF напрямую с использованием pdf()
pdf(output_pdf, width = 15, height = 8)
# Проходим по всем графикам из списка и выводим их на PDF
for (plot in list_plots) {
print(plot)
}
# Закрываем PDF устройство
dev.off()
2. Альтернатива с пакетом ggpubr
:
Пакет ggpubr
также предоставляет удобные функции для создания многостраничных графиков, что может значительно упростить задачу.
library(ggplot2)
library(ggpubr)
# Предположим, что list_plots уже создан
ggsave("combined_plots.pdf",
arrange_plots(list_plots, ncol = 1),
width = 15, height = 8)
3. Использование patchwork
:
Пакет patchwork
позволяет комбинировать графики более гибким образом. Вы также можете использовать этот подход, чтобы создать многостраничный PDF:
library(ggplot2)
library(patchwork)
# Предположим, что list_plots уже создан
final_plot <- wrap_plots(list_plots, ncol = 1)
ggsave("combined_plots.pdf", plot = final_plot, width = 15, height = 8)
Заключение
Выбор метода остается за вами и зависит от конкретных требований по визуализации. Если ваша задача – просто сохранить графики в формате PDF, то использование функций pdf()
и print()
в комбинации с циклом будет наиболее простым и эффективным решением. Если необходима более сложная компоновка графиков, тогда подойдут gridExtra
, ggpubr
или patchwork
.
Не забудьте протестировать различные методы и выбрать тот, который лучшим образом соответствует вашим потребностям!