Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
此R习惯用法的用途(match.call后跟eval(parent.frame())_R - Fatal编程技术网

此R习惯用法的用途(match.call后跟eval(parent.frame())

此R习惯用法的用途(match.call后跟eval(parent.frame()),r,R,我继承了一些代码,这些代码使用了我认为是库中常见的R习惯用法,但我不确定以这种冗长的方式编写会实现什么。最终我打算重新编写,但在我做一些愚蠢的事情之前,我首先想知道为什么 ecd <- function(formula, data, subset, weights, offset, ...) { cl = match.call() mf = match.call(expand.dots = FALSE) m = match(c("formula",

我继承了一些代码,这些代码使用了我认为是库中常见的R习惯用法,但我不确定以这种冗长的方式编写会实现什么。最终我打算重新编写,但在我做一些愚蠢的事情之前,我首先想知道为什么

ecd <-
function(formula, data, subset, weights, offset, ...) {
    cl = match.call()
    mf = match.call(expand.dots = FALSE)
    m =
        match(c("formula", "data", "subset", "weights", "offset"),
              names(mf),
              0L)
    mf = mf[c(1L, m)]
    mf$drop.unused.levels = TRUE
    mf[[1L]] = quote(stats::model.frame)
    mf = eval(mf, parent.frame())
    mt = attr(mf, "terms")
    y = stats::model.response(mf, "numeric")
    w = as.vector(stats::model.weights(mf))

    offset = as.vector(stats::model.offset(mf))

    x = stats::model.matrix(mt, mf, contrasts)
    z = ecd.fit(x, y, w, offset, ...)

ecd我认为这应该回答所有问题,代码中有解释:

# for later
FOO <- function(x) 1000 * x
y <- 1

foo <- function(...) {
  cl = match.call()
  message("cl")
  print(cl)
  message("as.list(cl)")
  print(as.list(cl))
  message("class(cl)")
  print(class(cl))
  # we can modify the call is if it were a list
  cl[[1]] <- quote(FOO)
  message("modified call")
  print(cl)
  y <- 2
  # now I want to call it,  if I call it here or in the parent.frame might
  # give a different output
  message("evaluate it locally")
  print(eval(cl))
  message("evaluate it in the parent environment")
  print(eval(cl, parent.frame()))
  message("eval.parent is equivalent and more idiomatic")
  print(eval.parent(cl))
  invisible(NULL)
}
foo(y)

# cl
# foo(y)
# as.list(cl)
# [[1]]
# foo
# 
# [[2]]
# y
# 
# class(cl)
# [1] "call"
# modified call
# FOO(y)
# evaluate it locally
# [1] 2000
# evaluate it in the parent environment
# [1] 1000
# eval.parent is equivalent and more idiomatic
# [1] 1000
#供以后使用

FOO
eval(mf,parent.frame())
正在从合适的环境中获取
mf
。我以为它正在父环境中调用
mf
,no?
eval在envir指定的环境中计算expr参数并返回计算值。如果未指定envir,则默认值为parent.frame()(调用eval的环境)。
来自文档(
help(“eval”)
)。是的,因此它在父环境中计算
mf
,它以通常的方式获得
mf
(作为封闭框架中的函数参数),然后返回父框架中计算
mf
的值(然后将其分配给一个名为
mf
…的变量。好吧,我没有写这个)。当然,除非“get
mf
”是指分配变量(“new”
mf
),在这种情况下,我认为我们是一致的。感谢对代码的解释,我也很想理解你为什么会这样做?据我所知,这使代码更难阅读和理解,并可能使你暴露在函数之外的奇怪效果下?我听到的关于这种NSE的解释只是为了抓住variab打印标签的le名称。我认为代码不是很干净,它没有注释,
mf
不是同一类型的对象,这取决于您查看的位置,并且有一个神秘的名称。如果直接在函数中调用
stats::model.frame
,而不进行替换,
的第一个元素上的替换,可能会更清晰>match.call()
有这样一个优点,即显式使用与原始调用完全相同的参数。使用
stats::model.frame(公式、数据、子集、权重、偏移量等)
您要输入两次这些变量,因此如果某些内容发生更改,您必须在两个位置进行更新,下一位读者必须进行可视化比较,以注意您传递的参数与原始调用中的参数相同。此外,如果函数支持缺少参数,您将遇到问题(例如,如果缺少
subset
,上述调用将失败),这可以通过适当的
if(missing(subset)){…}
等进行处理,但更详细。谢谢,我认为这回答了所有问题。