gpt4 book ai didi

r - 检查父函数中是否缺少参数

转载 作者:行者123 更新时间:2023-12-04 15:21:51 28 4
gpt4 key购买 nike



我有一个功能 f计算调用它的环境的摘要。在这个简单的例子中,它只是对找到的所有对象求和。

f <- function(){
x <- ls(parent.frame())
sum(sapply(x, get, envir=parent.frame()))
}
g <- function(x = 7, y){
z <- 3
f()
}

但是,如果从缺少参数的函数中调用,它将引发错误。
R> g(y = 34)
[1] 44

R> g()
Error in FUN(c("x", "y", "z")[[2L]], ...) :
argument "y" is missing, with no default

为了适本地处理它,我需要一种方法来告诉,从 f内部, 如果 yg 环境中的其他任意对象是 g 的参数在这种情况下,如果它丢失了。

我到目前为止的尝试

我尝试不同的解决方案
debug(f)
g()

当然 missing(y)不工作,因为 y不是 f 的参数.改变所处的环境 missing被评估也不起作用,因为我们仍然处于调用堆栈的同一级别:
Browse[2]> eval(missing(y), parent.frame())
Error in missing(y) : 'missing' can only be used for arguments

Browse[2]> identical(sys.frames(), eval(sys.frames(), parent.frame()))
[1] TRUE

我能做的是确定是否 yg 的参数使用肮脏的黑客功能
Browse[2]> eval(substitute(missing(a), list(a="x")), parent.frame())
[1] TRUE

Browse[2]> eval(substitute(missing(a), list(a="y")), parent.frame())
[1] TRUE

Browse[2]> eval(substitute(missing(a), list(a="z")), parent.frame())
[1] FALSE

产生 TRUE对于两个参数 xy但不是普通变量 z .与 tryCatch 结合使用检查是否可以检索参数可以解决问题,但它非常脏:
is.argument <- eval(substitute(missing(a), list(a="y")), parent.frame())
if(is.argument){
tryCatch({
get("y", parent.frame())
FALSE
}, error = function(e) TRUE)
} else {
NA
}

此外,我不知道如何定义 is.argument对于任意参数,与明确声明的 "y" 相反在上面的例子中。

更新:目的

在现实中, f的目的正在调试 g在运行时。我可能会打电话
R> debug(g)
R> g()

单步执行并使用 f 检查对象的状态,或者我可能会设置 options(error=recover)然后发现自己在调试 g如果它产生了错误。在这两种情况下都应该有一个明确定义的调用堆栈,所以我想我的基本问题是是否可以在不同级别上以类似于帧堆栈的方式查询它(使用 sys.frames() 访问)。我必须承认,这对我来说是深水。

想想 f作为我自己的调整版本 ls.str ,可以这样使用:
Browse[2]> ls.str()   # Inside g()
x : num 7
y : <missing>

经过一番挖掘 ls.strutils:::print.ls_str我发现它完成了同样的任务
for (nam in x) {
cat(nam, ": ")
o <- tryCatch(get(nam, envir = E, mode = M), error = function(e) e)
if (inherits(o, "error")) {
cat(if (length(grep("missing|not found", o$message)))
"<missing>"
else o$message, "\n", sep = "")
} else {
strO <- function(...) str(o, ...)
do.call(strO, strargs, quote = is.call(o) || is.symbol(o))
}
}

除非有适当的方法来做到这一点,否则我只会进行类似的黑客攻击。

最佳答案

缺失参数的值在与环境关联的配对列表中由称为“空符号”的奇数对象表示。事实证明,至少目前,“空符号”也是通过调用 quote(expr=) 返回的。 . ( See here 用于讨论空符号。)

函数ls_safe()使用这两个事实来实现缺失的替代测试。它返回由其 pos 指定的环境中存在的非缺失变量的字符向量。争论。

ls_safe <- function(pos=1) {
## Capture the parent environment's frame as a list
ll <- as.list(parent.frame(pos))
## Check for "missing" variables
ii <- sapply(ll, function(X) identical(X, quote(expr=)))
names(ll)[!ii]
}

## Then just use ls_safe() in place of ls()
f <- function(){
x <- ls_safe(pos=2)
sum(sapply(x, get, envir=parent.frame()))
}

g <- function(x = 7, y){
z <- 3
f()
}

g(99)
## [1] 102
g(99, 1000)
## [1] 1102

关于r - 检查父函数中是否缺少参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27822745/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com