0

I understand that resid() is a generic function in R, and which specific residual function is used depends on the object to which resid() is applied, just like print().

However, I noticed that, sometimes loading a package would change which specific residual function is used, yielding drastically different residual plots. Could anyone help me understand why that happens?

This is an example from my data:

> #### Showing packages loaded  after starting up R ####
> search()
 [1] ".GlobalEnv"        "tools:rstudio"     "package:stats"     "package:graphics"  "package:grDevices" "package:utils"    
 [7] "package:datasets"  "package:methods"   "Autoloads"         "package:base"     
> 
> #### Before loading nlme ####
> 
> ## s1 is a gls object, calculated using the nlme package
> s1 <- readRDS("../Data/my_gls.RDS")
> qqnorm(resid(s1, type = "pearson"), main = "before loading nlme")
> qqline(resid(s1, type = "pearson"))
> 
> methods(resid)
[1] residuals.default*       residuals.glm            residuals.HoltWinters*   residuals.isoreg*        residuals.lm            
[6] residuals.nls*           residuals.smooth.spline* residuals.tukeyline*    
see '?methods' for accessing help and source code
Warning message:
In .S3methods(generic.function, class, envir) :
  generic function 'resid' dispatches methods for generic 'residuals'
> sloop::s3_dispatch(resid(s1, type = "pearson"))
   resid.gls
=> resid.default
> ## the resid.default is used

And the resulting qqplot isenter image description here

Then, after loading the nlme package,

> #### After loading nlme ####
> 
> library(nlme)
Warning message:
package ‘nlme’ was built under R version 4.1.2 
> search()
 [1] ".GlobalEnv"        "package:nlme"      "tools:rstudio"     "package:stats"     "package:graphics"  "package:grDevices"
 [7] "package:utils"     "package:datasets"  "package:methods"   "Autoloads"         "package:base"     
> 
> # s2 is the same as s1
> s2 <- readRDS("../Data/my_gls.RDS")
> qqnorm(resid(s2, type = "pearson"), main = "after loading nlme")
> qqline(resid(s2, type = "pearson"))
> 
> methods(resid)
 [1] residuals.default*       residuals.glm            residuals.gls*           residuals.glsStruct*     residuals.gnls*         
 [6] residuals.gnlsStruct*    residuals.HoltWinters*   residuals.isoreg*        residuals.lm             residuals.lme*          
[11] residuals.lmeStruct*     residuals.lmList*        residuals.nlmeStruct*    residuals.nls*           residuals.smooth.spline*
[16] residuals.tukeyline*    
see '?methods' for accessing help and source code
Warning message:
In .S3methods(generic.function, class, envir) :
  generic function 'resid' dispatches methods for generic 'residuals'
> sloop::s3_dispatch(resid(s2, type = "pearson"))
=> resid.gls
 * resid.default
> # resid.gls is used

the qqplot looks like this enter image description here

As the command sloop::s3_dispatch(resid(s1, type = "pearson")) indicated, resid.default is the function being used before the nlme package is loaded, but resid.gls is the one being used after nlme is loaded. Why such a change---is it because resid.gls is not included in the default options of resid(), as the first methods(resid) suggested?

I am using R 4.1.0, and I would appreciate your feedback very much, if any. Thank you.

> version
               _                           
platform       x86_64-w64-mingw32          
arch           x86_64                      
os             mingw32                     
system         x86_64, mingw32             
status                                     
major          4                           
minor          1.0                         
year           2021                        
month          05                          
day            18                          
svn rev        80317                       
language       R                           
version.string R version 4.1.0 (2021-05-18)
nickname       Camp Pontaneze
Jwjw
  • 49
  • 2
  • 1
    Related: [How can a non-imported method in a not-attached package be found by calls to functions not having it in their namespace?](https://stackoverflow.com/questions/11004018/how-can-a-non-imported-method-in-a-not-attached-package-be-found-by-calls-to-fun) and [Namespaces and generic functions in R](https://stackoverflow.com/questions/55378596/namespaces-and-generic-functions-in-r) – markus Apr 20 '22 at 21:21
  • You've already said the answer. There is no function `resid.gls` in base R but your object has a class of "gls". So when you call resid, it looks for `resid.gls` because that's the class of your object first, doesn't find one, so runs `resid.default`. But `nlme` does define `resid.gls` so when you run `resid()` on your model after you load the package. it finds the more specific one and uses that. That's just how S3 dispatch works in R. If you want to learn more check out https://adv-r.hadley.nz/s3.html – MrFlick Apr 20 '22 at 23:17

0 Answers0