Search code examples
rggplot2autocorrelation

Error: Aesthetics must be either length 1 or the same as the data (121): yintercept


I have the following data (from 1 to 1032) and I am trying to plot correlogram for autocorrelation and partial autocorrelation:

prp: data frame

prp$Log.prp.Standardized: the column that I am trying to plot

Data:

prp$Log.prp.Standardized (Name of the column - I have 1 column with 1032 values)

1       1.7923928339
2       0.7792383013
3      -0.2033400303
4      -1.7016479357
5       0.8002357419
6       0.3575677621
7       1.0209246410
8       0.7188631605
9      -0.5320108464
10     -0.2190886401
.
.
.
.
(till 1032)

The function that I am using:

correlogram <- function(x, type = "correlation"){
  gacf = acf(x, plot=FALSE, lag.max=120, type = type)
  gacf.df = with(gacf, data.frame(lag, acf))
  gacf.df$sig = qnorm((1 + 0.95)/2)/sqrt(length(x))
  q <- ggplot(data = gacf.df, mapping = aes(x = lag, y = acf))
  q <- q + xlim(c(0,120)) + theme_bw()
  q <- q + geom_hline(aes(yintercept = 0))
  q <- q + geom_segment(mapping = aes(xend = lag), yend = 0, lwd = 1)
  q <- q + geom_hline(aes(yintercept = c(sig, -1*sig)), linetype = 2, colour = "#e51843")
  if(type == "partial"){
    q <- q + ylab(expression(alpha[k]))
  } else {
    q <- q + ylab(expression(rho[k]))
  }
  q <- q + xlab("lag k")
}

Then the code I am running:

require(gridExtra)
library(gridExtra)
library(ggplot2)
library(grid)
q1 <- correlogram(prp$Log.prp.Standardized) + xlab(" ") + ggtitle("Total and Partial Correlograms")
q2 <- correlogram(prp$Log.prp.Standardized, type = "partial") 
grid.arrange (q1, q2, nrow = 2)
grid

But I am getting the following error:

Error: Aesthetics must be either length 1 or the same as the data (121): yintercept

Any help will be appreciated!


Solution

  • The issue is that you map c(sig, -1*sig) on yintercept which will not work as the length of c(sig, -1*sig) is two times the length of your df gacf.df. That's what the error message is telling you. There are two options to achieve your desired result:

    1. If you add sig as a variable you have to add the horizontal lines via two calls of geom_hline.

    2. The approach below instead makes sig a scalar. In that case you don't have to wrap yintercept = c(sig, -1*sig) inside aes() :

    correlogram <- function(x, type = "correlation"){
      gacf = acf(x, plot=FALSE, lag.max=120, type = type)
      gacf.df = with(gacf, data.frame(lag, acf))
      #gacf.df$sig = qnorm((1 + 0.95)/2)/sqrt(length(x))
      
      sig = qnorm((1 + 0.95)/2)/sqrt(length(x))
      q <- ggplot(data = gacf.df, mapping = aes(x = lag, y = acf))
      q <- q + xlim(c(0,120)) + theme_bw()
      q <- q + geom_hline(aes(yintercept = 0))
      q <- q + geom_segment(mapping = aes(xend = lag), yend = 0, lwd = 1)
      # q <- q + geom_hline(aes(yintercept = sig), linetype = 2, colour = "#e51843")
      # q <- q + geom_hline(aes(yintercept = -1*sig), linetype = 2, colour = "#e51843")
      q <- q + geom_hline(yintercept = c(sig, -1*sig), linetype = 2, colour = "#e51843")
      if(type == "partial"){
        q <- q + ylab(expression(alpha[k]))
      } else {
        q <- q + ylab(expression(rho[k]))
      }
      q <- q + xlab("lag k")
    }
    
    library(gridExtra)
    library(ggplot2)
    library(grid)
    
    set.seed(42)
    
    prp <- data.frame(Log.prp.Standardized = rnorm(100))
    
    q1 <- correlogram(prp$Log.prp.Standardized) + xlab(" ") + ggtitle("Total and Partial Correlograms")
    q2 <- correlogram(prp$Log.prp.Standardized, type = "partial") 
    grid.arrange (q1, q2, nrow = 2)
    

    Created on 2021-02-18 by the reprex package (v1.0.0)