R: сохранение графиков ggplot2 в списке
Я пишу R-код, который позволяет пользователям выбирать столбцы из данных и отображать гистограммы для каждого из них. Следовательно, я использую цикл 'for' для генерации необходимого количества графиков с использованием библиотеки ggplot2 и сохранения их в одном списке. Но проблема, с которой я сталкиваюсь, заключается в том, что на каждой итерации цикла "for" все объекты в списке сохраняют один и тот же сюжет. Таким образом, конечный результат состоит из сетки гистограмм, помеченных по-разному, но изображающих один и тот же (последний) столбец.
Я понимаю, что этот вопрос довольно старый, и я нашел ответы на переименование графов ggplot2 в цикле for и https://stat.ethz.ch/pipermail/r-help/2008-February/154438.html будет полезной отправной точкой.
Я использовал стандартный набор данных швейцарской фертильности, доступный в R, для генерации графиков. Вот код: -
data_ <- swiss
data_ <- na.omit(data_)
u <- c(2, 3, 4, 5, 6)
plotData <- data_[,u]
bw <- 5
plotType <- 'probability'
library(ggplot2)
library(gridExtra)
histogramList <- vector('list', length(u))
if(plotType=='probability')
{
for(i in 1:length(u))
{
indexDataFrame <- data.frame(plotData[,i])
probabilityHistogram <- ggplot(indexDataFrame, aes(x=indexDataFrame[,1]))
histogramList[[i]] <- probabilityHistogram + geom_histogram(aes(y=..density..), binwidth=bw, colour='black', fill='skyblue') + geom_density() + scale_x_continuous(names(plotData)[i]) + opts(legend.position='none')
}
} else
if(plotType=='frequency')
{
for(i in 1:length(u))
{
indexDataFrame <- data.frame(plotData[,i])
probabilityHistogram <- ggplot(indexDataFrame, aes(x=indexDataFrame[,1]))
histogramList[[i]] <- probabilityHistogram + geom_histogram(aes(y=..count..), binwidth=bw, colour='black', fill='skyblue') + geom_density() + scale_x_continuous(names(plotData)[i]) + opts(legend.position='none')
}
}
arg_list <- c(histogramList, list(nrow=3, ncol=2))
#jpeg('histogram', width=1024, height=968)
do.call(grid.arrange, arg_list)
#graphics.off()
Прошу прощения, если я пропустил очевидный ответ на вопрос на этом форуме и буду благодарен, если вы можете направить меня к нему. Надеюсь, мои разъяснения ясны, а если нет, сообщите мне о необходимых разъяснениях.
Спасибо!
Ответы
Ответ 1
Вы можете значительно упростить свой код:
- Использование граней вместо ручной компоновки нескольких графиков
- Плавление ваших данных с помощью функции
melt
в пакете reshape2
- Это означает, что вы можете удалить цикл
Вот полный код вашего кода, без петли в поле зрения.
data_ <- swiss
data_ <- na.omit(data_)
u <- c(2, 3, 4, 5, 6)
plotData <- data_[,u]
bw <- 5
plotType <- 'frequency'
library(ggplot2)
library(reshape2)
mdat <- melt(plotData)
if(plotType=='probability'){
ph <- ggplot(mdat, aes(value)) +
geom_histogram(aes(y=..density..), binwidth=bw, colour='black', fill='skyblue') +
geom_density() +
facet_wrap(~variable, scales="free")
}
if(plotType=='frequency'){
ph <- ggplot(mdat, aes(value)) +
geom_histogram(aes(y=..count..), binwidth=bw, colour='black', fill='skyblue') +
geom_density() +
facet_wrap(~variable, scales="free")
}
print(ph)
Полученная графика:
Вероятность:
![enter image description here]()
Частота
![enter image description here]()
Ответ 2
Вместо отображения эстетики с помощью aes
вам может быть полезно использовать aes_string
:
for(i in 1:length(u))
{
probabilityHistogram <- ggplot(plotData, aes_string(x=names(plotData)[i]))
histogramList[[i]] <- probabilityHistogram + geom_histogram(aes(y=..density..), binwidth=bw, colour='black', fill='skyblue') + geom_density() + scale_x_continuous(names(plotData)[i]) + opts(legend.position='none')
}
Это работало для меня, по крайней мере. Это позволяет избежать подмножества ваших данных и позволяет ссылаться на столбец, который вы хотите построить, по указанному имени.