Ich habe eine Liste, p
, in der jedes Element von p
eine Liste von Plot-Objekten von ggplot2 ist.
Ich möchte ein einzelnes PDF mit allen Plots in p
ausgeben, so dass die Plots in p[[1]]
auf Seite 1, die Plots in p[[2]]
auf Seite 2 usw. sind. Wie kann ich das tun?
Hier ist ein Beispielcode, mit dem Sie die Datenstruktur angeben können, mit der ich arbeite. Ich entschuldige mich für die langweiligen Diagramme und wählte zufällig Variablen aus.
require(ggplot2)
p <- list()
cuts <- unique(diamonds$cut)
for(i in 1:length(cuts)){
p[[i]] <- list()
dat <- subset(diamonds, cut==cuts[i])
p[[i]][[1]] <- ggplot(dat, aes(price,table)) + geom_point() +
opts(title=cuts[i])
p[[i]][[2]] <- ggplot(dat, aes(price,depth)) + geom_point() +
opts(title=cuts[i])
}
Diese Lösung ist unabhängig davon, ob die Länge der Listen in der Liste p
unterschiedlich ist.
library(gridExtra)
pdf("plots.pdf", onefile = TRUE)
for (i in seq(length(p))) {
do.call("grid.arrange", p[[i]])
}
dev.off()
Aufgrund von onefile = TRUE
speichert die Funktion pdf
alle Grafiken, die nacheinander in derselben Datei erscheinen (eine Seite für eine Grafik).
Hier ist eine einfachere Version von Svens Lösung für R-Anfänger, die sonst die do.call- und verschachtelten Listen verwenden würden, die sie weder brauchen noch verstehen. Ich habe empirische Beweise. :)
library(ggplot2)
library(gridExtra)
pdf("plots.pdf", onefile = TRUE)
cuts <- unique(diamonds$cut)
for(i in 1:length(cuts)){
dat <- subset(diamonds, cut==cuts[i])
top.plot <- ggplot(dat, aes(price,table)) + geom_point() +
opts(title=cuts[i])
bottom.plot <- ggplot(dat, aes(price,depth)) + geom_point() +
opts(title=cuts[i])
grid.arrange(top.plot, bottom.plot)
}
dev.off()
Hier ist eine Lösung, die mir aber nicht besonders gefällt:
ggsave("test.pdf", do.call("marrangeGrob", c(unlist(p,recursive=FALSE),nrow=2,ncol=1)))
Das Problem besteht darin, dass in jeder Gruppe die gleiche Anzahl von Parzellen vorhanden ist. Wenn all(sapply(p, length) == 2)
falsch wäre, würde es brechen.
Hier ist eine Funktion, die auf Svens Ansatz basiert, einschließlich der roxygen2 -Dokumentation und eines Beispiels.
#' Save list of ggplot2 objects to single pdf
#'
#' @param list (list) List of ggplot2 objects.
#' @param filename (chr) What to call the pdf.
#'
#' @return Invisible NULL.
#' @export
#'
#' @examples
#' #plot histogram of each numeric variable in iris
#' list_iris = map(names(iris[-5]), ~ggplot(iris, aes_string(.)) + geom_histogram())
#' #save to a single pdf
#' GG_save_pdf(list_iris, "test.pdf")
GG_save_pdf = function(list, filename) {
#start pdf
pdf(filename)
#loop
for (p in list) {
print(p)
}
#end pdf
dev.off()
invisible(NULL)
}
Ich habe einige dieser Lösungen ausprobiert, jedoch ohne Erfolg. Ich recherchierte ein bisschen weiter und fand eine Lösung, die für mich perfekt funktionierte. Alle meine Grafiken werden in einer einzigen PDF-Datei gespeichert, jedes Diagramm auf einer Seite.
library(ggplot2)
pdf("allplots.pdf",onefile = TRUE)
for(i in glist){
tplot <- ggplot(df, aes(x = as.factor(class), y = value))
print(tplot)
}
dev.off()
Eine nette Lösung ohne das gridExtra
-Paket:
library(plyr)
library(ggplot2)
li = structure(p, class = c("gglist", "ggplot"))
print.gglist = function(x, ...) l_ply(x, print, ...)
ggsave(li, file = "test.pdf")