这个问题上有所跟进这个问题。考虑下面的例子
set.seed(1)
x <- cumsum(rnorm(10))
y <- stats::arima(x, order = c(1, 0, 0))
length(stats::fitted(y))
[1] 0
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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 on 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
Run Code Online (Sandbox Code Playgroud)
It seems that once I load the package I cannot use the old method of fitted.
I am wondering how to handle these situations.
As pointed out in the comments after unloadNamespace("forecast") I get that
isNamespaceLoaded("forecast")
[1] FALSE
Run Code Online (Sandbox Code Playgroud)
But methods fitted still includes fitted.Arima.
我从R devel 找到了这个线程。R Core的Brian Ripley说:
卸载名称空间不会取消注册其方法(并且注册没有堆栈,因此R不可能知道之前的内容)。
然后,该线程注意到将?unloadNamespace您指向?detach:
有关卸载和重新加载名称空间的一些问题,请参见帮助中的注释以进行分离。
最终会说出以下内容(强调我的意思)
如果程序包具有名称空间,则在默认情况下,将其分离不会卸载该名称空间(甚至可能不会使用unload = TRUE),并且分离通常不会卸载任何动态加载的已编译代码(DLL)。此外,不会删除名称空间中注册的S3方法。
因此,我的理解是,在加载名称空间(例如使用::)时,会注册S3方法,这些方法从不链接到它们从其加载的名称空间,因此,卸载名称空间也无法取消注册这些方法。清除它们的唯一方法methods()是重新启动R。
正如RolandASc指出的,stats:::fitted.default如果您要避免调度到,可以选择使用调用默认方法fitted.Arima。
@CalumYou完全正确地指出,卸载名称空间不会删除为另一个包中定义的S3泛型注册的S3方法。如果您有兴趣,这里更详细地介绍了这种情况以及原因。
当预测包被加载,所有的它定义在各种不同的命名空间的“已登记”在数据库中的方法。遵循的规则R是方法在定义其S3泛型的包的名称空间中注册。由于fitted()泛型是在stats中定义的,因此这是在称为的环境中注册由Forecast定义的新方法的地方.__S3MethodsTable__.。分离或卸载预测会使stats程序包保持不变(如果考虑的话,可能是一个整体明智的设计决策),不幸的结果是该fitted.Arima方法(以及许多其他方法)仍在其中注册.__S3MethodsTable__。
要查看是否是如此,请看以下内容:
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"
Run Code Online (Sandbox Code Playgroud)
(有关相关问题和解答,请参见此处。)