这个问题是对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
包中的一个函数。我没有附加包装,只是使用::
表示法加载。
在下面的代码中,我将直接使用requireNamespace
加载它。
requireNamespace("forecast", quietly = TRUE)
length(stats::fitted(y))
[1] 10
突然之间,同一命令返回了不同的结果。
我了解为什么会发生这种情况(希望我说的没错):通过加载forecast
包,将通用函数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
。
答案 0 :(得分:6)
我从R devel找到了this thread。 R Core的Brian Ripley说:
卸载名称空间不会取消注册其方法(并且 注册没有堆栈,所以R不可能知道那里有什么 之前)。
然后线程注意到?unloadNamespace
将您指向?detach
:
请参阅帮助中的注释以分离有关以下方面的问题 卸载和重新加载名称空间。
最终会说出以下内容(强调我的意思)
如果程序包具有名称空间,则在默认情况下不会卸载它 命名空间(甚至可能没有使用unload = TRUE),并分离 通常不会卸载任何动态加载的已编译代码 (DLL)。此外,从名称空间注册的 S3方法将不会 已删除。
因此,我的理解是,在加载名称空间(例如,通过使用::
)时,会注册S3方法,这些方法从不链接到它们从其加载的名称空间,因此,卸载名称空间也无法取消注册方法。从methods()
清除它们的唯一方法是重新启动R。
与RolandASc noted一样,如果要避免调度到stats:::fitted.default
,则可以选择使用fitted.Arima
来调用默认方法。
答案 1 :(得分:5)
@Calum您完全正确地指出,卸载名称空间不会删除为另一个包中定义的S3泛型注册的S3方法。如果您有兴趣,这里更详细地介绍了这种情况以及原因。
加载预测程序包时,它定义的所有方法都“注册”在各种不同名称空间的数据库中。遵循的规则R是方法在定义其S3泛型的包的名称空间中注册。由于fitted()
泛型是在 stats 中定义的,因此在称为.__S3MethodsTable__.
的环境中,这就是 forecast 定义的新方法的注册地。卸下或卸载预测会使 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"
(有关问题和解答,see here。)