我可以在后续的函数调用中评估参数吗?

时间:2019-08-22 08:48:19

标签: r lazy-evaluation

当我尝试捕获的值可能在母函数内部更改时,是否可以在后续函数调用中多次评估函数参数?

我遇到的问题与以下示例类似。 我在f1()循环中有一个母函数rnorm()和一个子函数for。 子函数在循环的每次迭代中都应接收不同的自变量(即rnorm(n = ii),但我想在母函数的级别上对此进行控制。

f1 <- function(I, n = 1) {

    res <- vector("list", length = I)

    for (ii in seq_len(I)) {
        res[[ii]] <- rnorm(n = n)
    }
    return(res)
}

f1(I = 2, n = 1)
f1(I = 2, n = ii) # desired, but obviously doesn't work

我尝试和eval()quote()get()等玩耍,但无济于事。

1 个答案:

答案 0 :(得分:4)

您要进行非标准评估,这意味着在评估表达式之前,您需要基于函数参数(通常使用substitute)来修改表达式。

f1 <- function(I, n = 1) {

  nval <- substitute(n)


  res <- vector("list", length = I)

  if (is.numeric(nval)) {
    for (ii in seq_len(I)) {
      res[[ii]] <- rnorm(n = n)
    }
  } 

  if (is.name(nval)) {
    for (ii in seq_len(I)) {
      res[[ii]] <- eval(substitute(rnorm(n = nval), list(nval = nval)))
    }
  }

  return(res)
}

f1(I = 2, n = 1)
#[[1]]
#[1] 0.4600974
#
#[[2]]
#[1] -0.6399949

f1(I = 2, n = ii)
#[[1]]
#[1] 0.4554501
#
#[[2]]
#[1] 0.7048373 1.0351035

我认为您的例子仅仅是糟糕的软件设计。我强烈建议您不要这样做。

更好的方法是:

f1 <- function(I, n) {

  res <- vector("list", length = I)

  if (missing(n)) {
    for (ii in seq_len(I)) {
      res[[ii]] <- rnorm(n = ii)
    }
  } else {
    for (ii in seq_len(I)) {
      res[[ii]] <- rnorm(n = n)
    }
  }

  return(res)
}

f1(I = 2, n = 1)
f1(I = 2)