rr-packager-s4r-s3

R: plot: Error in as.double(x): cannot coerce type 'S4' to vector of type 'double'


Apologies that this is 6 days after a similar post, however I suspect the root cause may be different. Another similar post says to ensure the plotting package is library'd but it should be (discussed below) and worked fine until this afternoon.

I have a package whose main function automates the process of boosted regression tree modelling. It's a massive sprawling function that does tons of stuff. Today I made a few small changes, adding a feature to include a random variable. Despite this not appearing to impact a later section about model evaluation in any way, when I run the function now I get the titular error. This comes from the following section:

evalmetrics <- c("ROC", "kappa", "prevalence", "TPR", "TNR", "FPR", "FNR", "CCR", "PPP", "NPP", "MCR", "OR")
for (s in evalmetrics) {
 png(filename = paste0("./",names(samples[i]),"/Bin_Eval_", s, ".png"))
 plot(e, s)
 dev.off()}

e is created by dismo::evaluate: e <- evaluate(p = pres,a = abs)

And when saved as an rds file it's an S4 object of class ModelEvaluation, which it should be. dismo::plot wants:

x   Object of class ModelEvaluation
y   Character. Either 'ROC' or a threshold dependent measure such as 'kappa', 'TPR'

So everything is 'in order' when it reaches the plot line. When I step into the gbm.auto function and run it line by line, everything works fine. When I run just that section using the exported e file, it works fine. But if I run gbm.auto as a function, I get the error. Seemingly plot is behaving like base::plot not dismo::plot. But I don't know why this would suddenly start happening. Nor what I can do about it: I @import the whole of the dismo package, and plot isn't exported by dismo so I can't force it with dismo::plot.

My limited understanding of plotting in R is that packages can overrule base/graphics as the sole plotting engine if the object class is something specific, and then they put their own spin on things. But my object class IS that specific thing, it worked for years, and all of a sudden it doesn't... but I can't for the life of me figure out how to debug it further, or fix it.

Any ideas welcome. Pseudo reproducible example: (drumline)

remotes::install_github("SimonDedman/gbm.auto")
library(gbm.auto)
drumline <- readRDS("2023-03-07_drumline_reefs_DtDropOff.rds")
gbm.auto(samples = as.data.frame(drumline),
         expvar = c("Habitat", "Tide", "Season", "LunarPhase", "Latitude", "Longitude", "Depth_m", "Temperature_C", "Hour", "Yearday", "Month", "DtDropOff"),
         resvar = "CaribbeanReef_CPUE",
         tc = 13,
         lr = list(0.001, 0.0000001),
         bf = 0.9,
         fam1 = "bernoulli",
         smooth = TRUE,
         simp = FALSE,
         savegbm = FALSE,
         BnW = FALSE)

Solution

  • I am able to get things working by adding these lines to dismo's NAMESPACE file and re-installing dismo from sources:

    exportMethods(plot)
    exportClasses(ModelEvaluation)
    

    And then deleting this line from gbm.auto's NAMESPACE file and re-installing gbm.auto from sources:

    importFrom(graphics, plot)
    

    The second step ensures that plot resolves to the S4 generic function dismo::plot rather than the S3 generic function graphics::plot.

    In any case, you should not be relying on unexported classes or methods from other packages. You might want to contact maintainer("dismo").