这个问题在某种程度上是对this question的跟进。请考虑以下示例
set.seed(1)
x <- cumsum(rnorm(10))
y <- stats::arima(x, order = c(1, 0, 0))
length(stats::fitted(y))
[1] 0
到目前为止很好:返回零因为R现在没有如何在类stats::fitted
的对象上使用Arima
。
接下来在我的代码中,我需要forecast
包中的一个函数。我没有附上包,我只是使用::
notation加载它。在我下面的代码中,我将使用requireNamespace
直接加载它。
requireNamespace("forecast", quietly = TRUE)
length(stats::fitted(y))
[1] 10
然后突然相同的命令返回不同的结果。我理解为什么会发生这种情况(我希望我说的正确):通过加载forecast
package,将通用函数fitted
(即fitted.Arima
)的新方法加载到命名空间中,从而产生不同的结果。
对我来说这种行为非常烦人:有没有办法选择fitted
的具体方法?我读了this chapter,但没有弄清楚如何规避这个问题。
我还尝试从命名空间卸载forecast
包,但没有成功:
unloadNamespace("forecast")
length(stats::fitted(y))
[1] 10
似乎一旦我加载包我不能使用fitted
的旧方法。我想知道如何处理这些情况。
正如unloadNamespace("forecast")
之后的评论中指出的那样,我明白了
isNamespaceLoaded("forecast")
[1] FALSE
但methods
适合仍然包括fitted.Arima
。
@CalumYou完全正确地指出卸载命名空间不会删除为另一个包中定义的S3泛型注册的S3方法。在这里,如果您感兴趣,可以更详细地了解这种情况的原因和原因。
加载预测包时,它定义的所有方法都在各种不同命名空间的数据库中“注册”。遵循的规则R是方法在定义其S3泛型的包的命名空间中注册。由于fitted()
泛型是在统计数据中定义的,因此预测定义的新方法在.__S3MethodsTable__.
环境中被注册。分离或卸载预测会使统计数据包保持不变(如果你考虑的话,可能是一个整体明智的设计决策),不幸的结果是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"
(有关问题和答案,see here。)
我从R devel找到了this thread。 Brian Ripley(R Core)说:
卸载命名空间不会取消注册其方法(并且注册没有堆栈,因此R无法知道之前的内容)。
该线程然后注意到?unloadNamespace
指向你在?detach
:
有关卸载和重新加载名称空间的一些问题,请参阅帮助中的注释以分离。
最终会说以下(强调我的)
如果一个包有一个命名空间,那么在默认情况下卸载它不会卸载命名空间(甚至可能没有unload = TRUE),并且分离通常不会卸载任何动态加载的编译代码(DLL)。此外,不会删除命名空间中注册的S3方法。
因此,我的理解是,在加载命名空间(例如使用::
)注册S3方法时,这些方法永远不会链接到它们从中加载的命名空间,因此卸载名称空间也不能取消注册方法。从methods()
清除它们的唯一方法是重启R.
作为RolandASc noted,如果你想避免派遣到stats:::fitted.default
,你可以选择使用fitted.Arima
调用默认方法。