我试图创建一个引用从它被调用来创建一个唯一的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必须是多个呼叫,取决于环境之间的重现性。
我知道我可以通过环境,但我开始怀疑是否做主叫的环境中捕捉实际上是可能的。
TL,DR: parent.frame()
不parent.frame(environment())
; evalq
不eval
。
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"
你的问题是, 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?