的R - 如何找到其中一个功能是从被调用函数中调用环境?(R - How to find the

2019-10-24 00:59发布

我试图创建一个引用从它被调用来创建一个唯一的ID范围的函数:

uniqueid <- function(name, envir = NULL) {

  if(identical(envir, globalenv())) {
    e = envir
  } else if (is.null(envir)) {
    e = parent.frame()
  } else if (is.environment(envir)) {
    e = envir
  } else {
    stop("given non-default argument \'envir\' is not an environment")
  }

  return(paste(sep = "",
    sub('<environment: (.*)>', '\\1', capture.output(e)),
    ".",
    name
    )
  )
}

我能做些什么,使这项工作,我认为它应该工作的方式吗? 者继续返回在其中所定义的功能的范围内,而不是在那里它被评估:

hello <- new.env()
hello$env <- new.env()

eval(envir=hello$env, {
  print(environment())
  print(hello$env) #hello$env is an environment
  print(hello) #hello is an environment
  uniqueid('hi')
})

我试图让这些投其所好至少一个,但它似乎并不像它想工作。 ř或者返回全球环境,或用于向所述函数的调用的一个实例创建的临时帧/环境的不断变化的范围。 该ID必须是多个呼叫,取决于环境之间的重现性。

我知道我可以通过环境,但我开始怀疑是否做主叫的环境中捕捉实际上是可能的。

Answer 1:

TL,DR: parent.frame()parent.frame(environment()) ; evalqeval

parent.frame需要论证n是世代数的回去,一个没有结果environment()调用(这是一个环境)。 如果你把它出的parent.frame()调用你的罚款。

此外,像您期望的,因为你的夜示例代码不工作environment()命令正在调用评估eval ,被评价为部分之前eval 。 即必须注明您的参数eval 。 另外,使用evalq而不是eval

uniqueid <- function(name) {
  print(parent.frame())
}
hello <- new.env()
hello$env <- new.env()
evalq(envir=hello$env, {
  print(environment()) # prints hello$env
  print(hello$env)     # prints hello$env
  print(hello)         # prints hello
  uniqueid('hi')       # prints hello$env
})

例如,这将让环境ID,并把它添加到name

uniqueid <- function(name) {
    # GlobalEnv etc have names; hello doesn't
    envName <- environmentName(parent.frame())
    # get the environment ID from the parent.frame() output if no name
    if (envName == "") {
        p <- parent.frame()
        envName <- sub('<environment: (.*)>', '\\1', capture.output(p))
    }
    return(paste(envName, name, sep=':'))
}
uniqueid('x') # R_GlobalEnv:x
print(hello) # <environment: 0x4641fa0>
evalq(envir=hello, uniqueid('x')) # "0x4641fa0:x"
print(hello$env) # <environment: 0x4640e60>
evalq(envir=hello$env, uniqueid('x')) # "0x4640e60:x"


Answer 2:

你的问题是, eval()期待的东西是不计算。 通过传递一个代码块{}你不会阻止评价。 例如,考虑简单的情况下,

a<-10
ee<-new.env()
ee$a<-5

eval(envir=ee, a)
# [1] 10
eval(envir=ee, {a})
# [1] 10
eval(envir=ee, quote(a))
# [1] 5
evalq(envir=ee, a)
# [1] 5

请注意,最后两个是如何明确地引用表达式,或者使用evalq()做表达的报价。 这些允许推迟评估,直到请求的环境内执行。

所以,如果你只需要改变你eval()evalq()你应该罚款。



文章来源: R - How to find the environment where a function is called from inside the called function?
标签: r scope