Combine multiple plots, generated using the “by” R function, in one figure

∥☆過路亽.° 提交于 2021-02-02 09:40:32

问题


I have a data frame containing multiple numeric columns and one column with different factors. I'd like to produce a unique image containing the plots of the numeric columns, by factor. I tried the following:

varA    <- runif(40)
varB    <- runif(40)
varB    <- runif(40)
varC    <- runif(40)

mainVar <- c(rep('cat', 10), rep('dof', 10), rep('mouse', 10), rep('frog', 10))

plotData <- data.frame(varA, varB, varC, mainVar)

pdf('asd.pdf')
par(mfrow=c(2,2))

by(plotData, plotData$mainVar, function(x){

  par(mfrow=c(1,3))
  boxplot(x$varA)
  boxplot(x$varB)
  boxplot(x$varC)

})

dev.off()

It produces a unique pdf, but with a page for every factor.

Instead, I'd like to get something like that (without the red lines):

figure


回答1:


First, both techniques shown here prefer data in a "tall" format. There are several tools that will reshape it for you, I'll use

# library(tidyr)
plotDataTall <- tidyr::gather(plotData, k, v, -mainVar)
head(plotDataTall)
#   mainVar    k         v
# 1     cat varA 0.4023846
# 2     cat varA 0.3406813
# 3     cat varA 0.7990530
# 4     cat varA 0.3706167
# 5     cat varA 0.5986029
# 6     cat varA 0.1626782

Other tools include the reshape2 package or the stats function reshape, both of which are increasingly less-intuitive to use for first time users.

ggplot2

library(ggplot2)

ggplot(plotDataTall, aes(x = k, y = v)) +
  geom_boxplot() +
  facet_wrap(~ mainVar, nrow=2) +
  theme(axis.title.x = element_blank(),
        axis.title.y = element_blank())

Base R

Because you cannot nest uses of par(mfrow=...) (they replace, not nest), you can stick with the over-arching 2x2 and handling the per-variable boxplots within boxplot. This can be with the wide data:

par(mfrow=c(2,2), mar=c(4,3,3,0.1))
ign <- by(plotData, plotData$mainVar, function(x) {
  boxplot(x$varA, x$varB, x$varC, main=x$mainVar[1])
})

or the tall format:

par(mfrow=c(2,2), mar=c(4,3,3,0.1))
ign <- by(plotDataTall, plotDataTall$mainVar, function(x) {
  boxplot(v~k, data=x, main=x$mainVar[1])
})

(I took the liberty of adjusting the margins, primarily for a shrunken combined plot here. Not required for production.)




回答2:


As r2evans already points out, I doubt this is possible with the base plot function. Using ggplot2 (part of the tidyverse) you can get a one-page plot using:

library(tidyverse)
plotData %>% 
gather(var, y, -mainVar) %>% 
ggplot(aes(x = var, y = y)) + geom_boxplot() + facet_wrap(~mainVar)

note that this also uses the pipe operator (dplyr), and gather (tidyr) both part of tidyverse



来源:https://stackoverflow.com/questions/49635233/combine-multiple-plots-generated-using-the-by-r-function-in-one-figure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!