如何在R包中使用get0仅在包名称空间内搜索?

如何在R包中使用get0仅在包名称空间内搜索?,r,namespaces,package,arguments,R,Namespaces,Package,Arguments,假设我的包中有一个内部函数,称之为is(),如果is(),则可以认为它是一个更通用的版本。特别是,它搜索专门的函数,这些函数用于判断提供的对象是否是给定的类。例如,is u()可以编程为: is_ <- function(obj, class) { if (exists(paste0("is.", class))) { get0(paste0("is.", class))(obj) } else inherits(obj, cl

假设我的包中有一个内部函数,称之为
is()
,如果
is()
,则可以认为它是一个更通用的版本。特别是,它搜索专门的函数,这些函数用于判断提供的对象是否是给定的类。例如,
is u()可以编程为:

is_ <- function(obj, class) {
  if (exists(paste0("is.", class))) {
     get0(paste0("is.", class))(obj)
  }
  else inherits(obj, class)
}
在我定义的地方

is.numeric_vector <- function(x) is.numeric(x) && is.null(dim(x))

is.numeric\u vector问题在于包名称空间将从从全局环境继承的基本名称空间继承。有关更详细的说明,请参见此处:。如果您想对符号查找进行更多控制,则需要自己完成这项工作。您可以在包中包含自己的
get
函数

# These are private helpers that do not need to be exported from your package.
.pkgenv <- environment()
get1 <- function(name, env = .pkgenv) {
  if (identical(env, emptyenv())) {
    NULL
  } else if (identical(env, globalenv())) {
    # stop at global env
    NULL
  } else if (exists(name, envir=env, inherits = FALSE)) {
    env[[name]]
  } else {
    # try parent
    get1(name, parent.env(env))
  }
}

这里我们只检查null,而不是单独验证名称,然后检索值。如果<代码> GET1是一个被称为一堆的东西,你可能想考虑缓存结果,这样你就不必总是要继承继承树。< /P>你有一个你正在研究的函数冲突的实际例子吗?我们可以用来测试这个问题。
在包内定义,而不是在包外定义(即在全局环境中)<代码>是(1,“数字向量”)
将返回
TRUE
但我希望它返回
FALSE
,因为
继承(1,“数字向量”)
FALSE
。这很有帮助,谢谢。是否有办法限制环境
get0()
使用其
envir
继承的
参数进行搜索?如果用户附加了一个包含
is\u numeric\u vector()
的包,那么
is\u()
不会仍然拾取它,因为它的环境是它来自的包,而不是全局环境?用户附加的包不应该在继承链中。如果你发现一个反例,请分享。没有办法改变get0的工作方式,因为这就是BaseR的工作方式。如果您喜欢手动迭代专利环境,您可以编写自己的。这发生在我自己的R包中,
WeightIt
。我使用的
is_u1;()
函数与我在这里发布的函数类似,但将
paste0(“is.”,class)
替换为
paste0(“is_1;,class)
purrr
包有一个函数,
是\u numeric()
,它会产生一个“弃用”警告。当用户附加
purr
并且运行
is_x(numeric”)
时,
purr:is_numeric()
get0()检索。您的解决方案不会阻止这种情况,因为
purrr:is\u numeric()
不在全局环境中。确定。我的父订单搞错了,所以是的,附加的包成为了全球环境的父项。因此,在全球环境中没有停止搜索的通用方法。我更新了我的答案,使用了一个替代
get0
的选项,该选项将在全局环境中停止。
# These are private helpers that do not need to be exported from your package.
.pkgenv <- environment()
get1 <- function(name, env = .pkgenv) {
  if (identical(env, emptyenv())) {
    NULL
  } else if (identical(env, globalenv())) {
    # stop at global env
    NULL
  } else if (exists(name, envir=env, inherits = FALSE)) {
    env[[name]]
  } else {
    # try parent
    get1(name, parent.env(env))
  }
}
is_ <- function(obj, class) {
  if (!is.null(fn <- get1(paste0("is.", class)))) {
    fn(obj)
  } else {
    inherits(obj, class)
  }
}