You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pryr包where函数调用to_env未找到却能运行的原因探究

关于pryr包where函数中to_env的疑问解答

核心原因是to_env是pryr包的内部非导出函数:

  • 这类函数仅对包内部的代码可见,不会对外暴露——你通过library(pryr)加载包后,在全局环境里直接调用to_env是找不到它的。
  • 原生的pryr::where()运行在pryr包的专属环境中,这个环境能直接访问包内所有内部函数,所以to_env可以正常调用。

当你把where函数的代码复制到全局环境并重命名后,新函数的执行环境变成了全局环境,而全局环境中不存在to_env,因此会触发"找不到函数"的错误。

让复制后的函数正常运行的两种方法

  1. 直接调用pryr内部的to_env
    修改代码中的to_env为pryr:::to_env(三个冒号用于访问包的非导出函数),修改后的函数如下:

    my_where <- function (name, env = parent.frame()) 
    {
      stopifnot(is.character(name), length(name) == 1)
      env <- pryr:::to_env(env)
      if (identical(env, emptyenv())) {
        stop("Can't find ", name, call. = FALSE)
      }
      if (exists(name, env, inherits = FALSE)) {
        env
      }
      else {
        my_where(name, parent.env(env))
      }
    }
    
  2. 自行实现to_env的功能
    to_env的核心作用是将不同类型的输入(环境对象、字符串、数字)转换为对应的环境对象,你可以把它的逻辑内嵌到函数里,或者单独实现:

    # 先实现to_env的简化版本
    to_env <- function(x) {
      if (is.environment(x)) return(x)
      if (is.character(x)) return(as.environment(x))
      if (is.numeric(x)) return(sys.frame(x))
      stop("Invalid environment specification", call. = FALSE)
    }
    
    # 再定义你的where函数
    my_where <- function (name, env = parent.frame()) 
    {
      stopifnot(is.character(name), length(name) == 1)
      env <- to_env(env)
      if (identical(env, emptyenv())) {
        stop("Can't find ", name, call. = FALSE)
      }
      if (exists(name, env, inherits = FALSE)) {
        env
      }
      else {
        my_where(name, parent.env(env))
      }
    }
    

内容的提问来源于stack exchange,提问作者Allrounder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 09:47:11