Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Namespaces and generic functions in R

Tags:

namespaces

r

this question is somewhat a follow up on this question. Consider the following example

set.seed(1)
x <- cumsum(rnorm(10))
y <- stats::arima(x, order = c(1, 0, 0))
length(stats::fitted(y))
[1] 0

So far so good: zero is returned because R does not now how to use stats::fitted on an object of class Arima.

Next in my code, I need one function from the forecast package. I do not attach the package, I just load it using the ::notation. In my code below I will load it directly using requireNamespace.

requireNamespace("forecast", quietly = TRUE)
length(stats::fitted(y))
[1] 10

And suddenly the same command returns a different result. I understand why this happens (and I hope I am saying it correctly): by loading the forecastpackage a new method for the generic function fitted (namely fitted.Arima) is loaded into the namespace which results in a different outcome.

For me this behavior is quite annoying: is there any way to choose one specific method for fitted? I read this chapter but did not figure out how to circumvent this problem.

I also tried to unload the forecast package from namespace, but no success:

unloadNamespace("forecast")
length(stats::fitted(y))
[1] 10

It seems that once I load the package I cannot use the old method of fitted. I am wondering how to handle these situations.

EDIT

As pointed out in the comments after unloadNamespace("forecast") I get that

isNamespaceLoaded("forecast")
[1] FALSE

But methods fitted still includes fitted.Arima.

like image 923
Cettt Avatar asked Mar 27 '19 13:03

Cettt


Video Answer


1 Answers

@CalumYou is exactly right in pointing out that unloading a namespace will not remove S3 methods registered for an S3 generic defined in another package. Here, in case you are interested, is a more detailed look at how and why that is the case.

When the forecast package is loaded, all of the methods that it defines are "registered" in data bases in a variety of different namespaces. The rule R follows is that a method gets registered in the namespace of the package that defines its S3 generic. Since the fitted() generic is defined in stats, that's where the new methods defined by forecast get registered, in an environment called .__S3MethodsTable__.. Detaching or unloading forecast leaves the stats package untouched (probably an overall wise design decision, if you think about it), with the unfortunate consequence that the fitted.Arima method (along with many others) remain registered in its .__S3MethodsTable__.

To see that this is so, have a look at the following:

isNamespaceLoaded("forecast")
## [1] FALSE
ls(stats:::.__S3MethodsTable__., pattern = "fitted")
## [1] "fitted.default"       "fitted.isoreg"        "fitted.kmeans"       
## [4] "fitted.nls"           "fitted.smooth.spline"

## Loading the forecast namespace registers new 'fitted' methods ...
requireNamespace("forecast", quietly = TRUE)
isNamespaceLoaded("forecast")
## [1] TRUE
ls(stats:::.__S3MethodsTable__., pattern = "fitted")
##  [1] "fitted.ar"              "fitted.Arima"           "fitted.arma"           
##  [4] "fitted.bats"            "fitted.default"         "fitted.ets"            
##  [7] "fitted.fracdiff"        "fitted.garch"           "fitted.gls"            
## [10] "fitted.glsStruct"       "fitted.gnls"            "fitted.gnlsStruct"     
## [13] "fitted.isoreg"          "fitted.kmeans"          "fitted.lagwalk"        
## [16] "fitted.lme"             "fitted.lmeStruct"       "fitted.lmList"         
## [19] "fitted.modelAR"         "fitted.nlmeStruct"      "fitted.nls"            
## [22] "fitted.nnetar"          "fitted.quantmod"        "fitted.smooth.spline"  
## [25] "fitted.tbats"           "fitted.tslm"            "fitted.values.quantmod"

## ... which are left behind even when the forecast namespace is unloaded
unloadNamespace("forecast")
isNamespaceLoaded("forecast")
## [1] FALSE
ls(stats:::.__S3MethodsTable__., pattern = "fitted")
##  [1] "fitted.ar"              "fitted.Arima"           "fitted.arma"           
##  [4] "fitted.bats"            "fitted.default"         "fitted.ets"            
##  [7] "fitted.fracdiff"        "fitted.garch"           "fitted.gls"            
## [10] "fitted.glsStruct"       "fitted.gnls"            "fitted.gnlsStruct"     
## [13] "fitted.isoreg"          "fitted.kmeans"          "fitted.lagwalk"        
## [16] "fitted.lme"             "fitted.lmeStruct"       "fitted.lmList"         
## [19] "fitted.modelAR"         "fitted.nlmeStruct"      "fitted.nls"            
## [22] "fitted.nnetar"          "fitted.quantmod"        "fitted.smooth.spline"  
## [25] "fitted.tbats"           "fitted.tslm"            "fitted.values.quantmod"

(For a related question and answer, see here.)

like image 184
Josh O'Brien Avatar answered Oct 04 '22 07:10

Josh O'Brien