Home > Mobile >  ACF plot in ggplot2 from a mixed effects model
ACF plot in ggplot2 from a mixed effects model

Time:06-02

I'm trying to perform an autocorrelation plot in ggplot2.

library(nlme)

fm2 <- lme(distance ~ age   Sex, data = Orthodont, random = ~ 1)
plot(ACF(fm2,resType="normalized"),alpha=0.05)

Result through the above function: enter image description here

########################## IC ###########################

ic_alpha= function(alpha, acf_res){
  return(qnorm((1   (1 - alpha))/2)/sqrt(acf_res$n.used))
}

#################### graphics ###########################
library(ggplot2)

ggplot_acf_pacf= function(res_, lag, label, alpha= 0.05){
  df_= with(res_, data.frame(lag, ACF))
  
  lim1= ic_alpha(alpha, res_)
  lim0= -lim1
  
  
  ggplot(data = df_, mapping = aes(x = lag, y = ACF))  
    geom_hline(aes(yintercept = 0))  
    geom_segment(mapping = aes(xend = lag, yend = 0))  
    labs(y= label)  
    geom_hline(aes(yintercept = lim1), linetype = 2, color = 'blue')  
    geom_hline(aes(yintercept = lim0), linetype = 2, color = 'blue')
}
######################## result ########################
acf_ts = ggplot_acf_pacf(res_= ACF(fm2,resType="normalized"),
                         20,
                         label= "ACF")

However, I am encountering the following error:

Error in sqrt(acf_res$n.used) : 
  non-numeric argument to mathematical function

What I intend to get is something like: enter image description here

CodePudding user response:

The object produced by ACF does not have a member called n.used. It has an attribute called n.used. So your ic_alpha function should be:

ic_alpha <- function(alpha, acf_res) {
  return(qnorm((1   (1 - alpha)) / 2) / sqrt(attr(acf_res, "n.used")))
}

Another problem is that, since ic_alpha returns a vector, you will not have a single pair of significance lines, but rather one pair for each lag, which looks messy. Instead, emulating the base R plotting method, we can use geom_line to get a single curving pair.

ggplot_acf_pacf <- function(res_, lag, label, alpha = 0.05) {
  
  df_ <- with(res_, data.frame(lag, ACF))
  
  lim1 <- ic_alpha(alpha, res_)
  lim0 <- -lim1
  
  ggplot(data = df_, mapping = aes(x = lag, y = ACF))  
    geom_hline(aes(yintercept = 0))  
    geom_segment(mapping = aes(xend = lag, yend = 0))  
    labs(y= label)  
    geom_line(aes(y = lim1), linetype = 2, color = 'blue')  
    geom_line(aes(y = lim0), linetype = 2, color = 'blue')  
    theme_gray(base_size = 16)
}

Which results in:

ggplot_acf_pacf(res_ = ACF(fm2, resType = "normalized"), 20, label = "ACF")

enter image description here

  • Related