此习语的目的(match.call后跟eval(parent.frame())

时间:2019-04-05 12:11:12

标签: r

我已经继承了一些代码,这些代码使用了我认为是库的常见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, ...)

我目前的理解是,它从原始参数到函数构造一个函数调用对象(类型?),然后手动调用它,而不仅仅是直接调用stats::model.frame。任何见解将不胜感激。

1 个答案:

答案 0 :(得分:1)

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

# 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