如何防止库屏蔽功能

时间:2016-10-15 21:18:39

标签: r

典型情况如下:

library(dplyr)
library(xgboost)

当我导入库xgboost时,slice的{​​{1}}函数被屏蔽了,即使我从不使用dplyr,我也必须写dplyr::slice明确。

问题的明显解决方案是在xgboost::slice之前导入xgboost。但是导入所有可能提前影响dplyr功能的库是很疯狂的。此外,当我使用dplyr库时,通常会发生此问题。即caret函数自动导入所需的库,并且当时屏蔽了一些函数。

  1. 可以防止某些功能被屏蔽吗?
  2. 是否可以使用早期导入的函数(例如train)屏蔽“屏蔽功能”(例如xgboost::slice)?
  3. 注释

    • 不询问如何禁用警告信息。
    • 没有询问如何使用蒙面函数。

5 个答案:

答案 0 :(得分:18)

R的下一个版本有this in the NEWS{.Rd} file(引自构建后的NEWS文件):

• The import() namespace directive now accepts an argument except
  which names symbols to exclude from the imports. The except
  expression should evaluate to a character vector (after
  substituting symbols for strings). See Writing R Extensions.

手册中引用的文字为here (in raw texi format)

我们很快就可以。现在有人不能,特别是当Base R包中的函数被掩盖时,这是一个巨大的痛苦:lag()filter(),......

我们过去曾使用“em> anti-social 这个词来表达这种行为。我认为它不太强大。

为了说明这个问题,这里是我十年前写的代码片段(并将其发布在现已消失的R Graph Gallery上),该代码使用一种聪明而快速的方法来计算移动平均线:

  ## create a (normalised, but that's just candy) weight vector
  weights <- rep(1/ndays, ndays)
  ## and apply it as a one-sided moving average calculations, see help(filter)
  bbmiddle <- as.vector(filter(dat$Close, weights,
                               method="convolution", side=1))

如果你在交互式会话中做library(dplyr),那么你已经死了,因为filter()现在已经完全不同了。不太好。

答案 1 :(得分:11)

  
      
  1. 可以防止某些功能被屏蔽吗?
  2.   

我不相信,但我可能是错的。我不确定这会是什么样的

  
      
  1. 是否可以使用早期导入的函数(例如dplyr :: slice)屏蔽“屏蔽功能”(例如xgboost :: slice)?
  2.   

如果您只是询问或在交互式会话中使用,您可以随时将slice定义为您实际想要使用的功能

slice <- dplyr::slice

然后您可以使用slice,就像它是dplyr版本一样(因为现在它是。)

答案 2 :(得分:6)

解决方案是管理您的命名空间,就像在其他语言中一样。您可以有选择地导入dplyr函数:

import {SharedModule} from './shared/shared.module';

import {ComponentsModule} from './components/components.module';
....
@NgModule({
declarations: [
    AppComponent,
],
imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    SharedModule,
    ComponentsModule,
    BsDropdownModule.forRoot(),
    RouterModule.forRoot(
        APP_ROUTES,
        {enableTracing: true})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}

为方便起见,您还可以导入整个包并从以前连接的包中选择性地重新导入函数:

select <- dplyr::select

R有一个很棒的模块系统,附加整个命名空间对于交互式使用尤其方便。如果包装作者的偏好与您的偏好不匹配,则需要进行一些手动调整。

请注意,在包和长期维护脚本中,您应该为选择性导入授予特权,部分原因是在将来的版本中很难预测新的导出函数。批量导入多个软件包可能会导致意外屏蔽。

更一般地说,一个好的规则是依靠单个附加包并选择性地导入其余包。为此,library("dplyr") filter <- stats::filter 包可能很方便,如果你是一个沉重的tidyverse用户,因为它为几个包提供了一个导入点。

最后,从您的问题看来,您认为附加包的顺序可能会在其他包中产生副作用。这没什么好担心的,因为所有包都有自己的上下文。导入方案只会影响您的脚本。

答案 3 :(得分:3)

您现在还可以使用conflict_prefer()软件包中的conflicted函数来指定哪个软件包的函数应“获胜”,以及哪些函数名称存在冲突时应将其屏蔽(详细信息here )。在您的示例中,您将运行

conflict_prefer("slice", "dplyr", "xgboost") 

在加载库之后。然后,当您运行slice时,它将默认使用dplyr::slice而不是xgboost::slice。或者,您可以简单地运行

conflict_prefer("slice", "dplyr")

如果要使dplyr::slice的优先级高于所有其他软件包的slice函数。

答案 4 :(得分:0)

我知道这是一个愚蠢的回答,并且这个线程很旧(但是今天我只有同样的问题):我更改了加载程序包的顺序。我个人对MASS和Dplyr的“选择”功能有疑问。我想一直使用Dplyr版本。所以我先加载了MASS!