Search code examples
rlatticer-mosaic

Error while adding panel.lmbands to lattice plot in R


I want to add panel.lmbands from mosaic package. I am using the following code

library(lattice)
library(tidyverse)
library(hydroGOF)
library(mosaic)
library(latticeExtra)

summ <- iris %>% 
  group_by(Species) %>% 
  summarise(Rsq = cor(Sepal.Length, Petal.Length)^2,
            RMSE = rmse(Sepal.Length, Petal.Length),
            NSE = NSE(Sepal.Length, Petal.Length)) %>% 
  mutate_if(is.numeric, round, digits=2)

summ$ann <- lapply(1:nrow(summ), function(i) with(summ[i, ], 
            c(bquote(R^2 == .(Rsq)), bquote(RMSE == .(RMSE)), bquote(NSE == .(NSE))))
)

xyplot(Petal.Length ~ Sepal.Length | Species, data = iris, pch = 23, 
             layout=c(3,1), 
             band.lty = c(conf =2, pred = 1), 
             band.lwd =c(conf =1, pred = 1),
             npts = 500,
             panel = panel.lmbands,
             scales=list(cex=c(1.4,1.4), alternating=1, relation = "free"),
             xlab = list(label="Sepal Length", fontsize=20),
             ylab = list(label="Petal Length", fontsize=20),
             panel = function(x, ...) {
               i <- panel.number()
               panel.xyplot(x, ...)
               panel.key(as.expression(summ$ann[[i]]), points = FALSE)
             })

It returns me following error

Error in xyplot.formula(Petal.Length ~ Sepal.Length | Species, data = iris, : formal argument "panel" matched by multiple actual arguments

The expected output will look like the following enter image description here

How can I correct the error?


Solution

  • In this case, your error message is very helpful -- you have defined the panel argument twice, which is not allowed. You can fix the problem by modifying your custom panel function:

    panel = function(x, ...) {
                   i <- panel.number()
                   panel.xyplot(x, ...)
                   panel.lmbands(x, ...)
                   panel.key(as.expression(summ$ann[[i]]), points = FALSE)
                 }
    

    You might also consider using ggformula rather than lattice for plotting, since that makes stacking layers much easier.

    Here is the core of your plot using ggformula (without custom labels, annotation, etc, which you could add):

    suppressPackageStartupMessages(library(ggformula))
    gf_point(Petal.Length ~ Sepal.Length |  ~ Species, data = iris, shape = 23) %>%
      gf_lm(interval = "prediction", fill = "blue") %>%
      gf_lm(interval = "confidence", fill = "red")
    

    Created on 2021-08-26 by the reprex package (v2.0.0)

    For more information on ggformula, see http://www.mosaic-web.org/ggformula/