Search code examples
rgraphicspar

R | combine plots that use par(mfrow = ...) internally


Take plot.acf as an example. Both acf and pacf call this function internally. How can i plot them side by side?

Example:

TS <- ts.union(mdeaths, fdeaths)
acf(TS)
pacf(TS)

I tried to use par(mfrow = c(2,4)) and layout to combine them, but stats:::plot.acf overwrites this. The expected output would be:

enter image description here


Solution

  • A different approach than my other answer: Plot the ACF using ggplot2.

    ggacf <- function(x, ci=0.95, type="correlation", xlab="Lag", ylab=NULL,
                      ylim=NULL, main=NULL, ci.col="blue", lag.max=NULL) {
    
        x <- as.data.frame(x)
    
        x.acf <- acf(x, plot=F, lag.max=lag.max, type=type)
    
        ci.line <- qnorm((1 - ci) / 2) / sqrt(x.acf$n.used)
    
        d.acf <- data.frame(lag=x.acf$lag, acf=x.acf$acf)
    
        g <- ggplot(d.acf, aes(x=lag, y=acf)) +
            geom_hline(yintercept=0) +
            geom_segment(aes(xend=lag, yend=0)) +
            geom_hline(yintercept=ci.line, color=ci.col, linetype="dashed") +
            geom_hline(yintercept=-ci.line, color=ci.col, linetype="dashed") +
            theme_bw() +
            xlab("Lag") +
            ggtitle(ifelse(is.null(main), "", main)) +
            if (is.null(ylab))
                ylab(ifelse(type=="partial", "PACF", "ACF"))
            else
                ylab(ylab)
    
        g
    }
    

    This seeks to create a similar interface to plot.acf(). Then you can use all of the great features available to ggplot2 plots from the gridExtra package.

    library(ggplot2)
    library(gridExtra)
    
    grid.arrange(ggacf(lh), ggacf(lh, type="partial"), ncol=2)
    

    Then you get this:

    enter image description here

    Unfortunately grid.arrange() doesn't work with base graphics, hence the ggplot2 suggestion.