在R中,如何评估函数中特定环境中的表达式?

时间:2019-05-08 10:11:21

标签: r namespaces environment

我显然很天真,我假设当一个人调用[object Object],[object Object],[object Object],[object Object],[object Object]并指定一个环境(eval)时,表达式(envir)在该环境中求值。

但是:-)

这按预期工作:

expr

默认情况下,xx <- 10 nn <- 20 exprs <- binom.test(x=xx,n=nn) eval(exprs); eval中求值,帮助显示的是 [t]。函数求值的父框架是调用函数的环境。

因此在上面的示例中,这是全局环境,实际上定义了parent.frame()xx。到目前为止,一切都很好。

nn

这也按预期工作; newEnv <- new.env(); assign('xxx', 10, envir = newEnv); assign('nnn', 30, envir = newEnv); exprs2 <- expression(binom.test(x=xxx,n=nnn)); eval(exprs2, envir=newEnv); xxxnnn环境中定义,而newEnv在该环境中求值。

现在我们将其包装在一个函数中(我正在尝试构建的函数-我正在使用binom.test包构建它,但是在此示例中,我使用pwr是因为它是基础R,但仍然不起作用:-)

binom.test

运行此命令,您将得到:

loopFunction <- function(expr,
                         ...) {

  ### Get all 'dots' in a named list
  arguments <- list(...);
  argNames <- names(arguments);

  if (any(length(tail(arguments, -2) > 1))) {
    stop("Only the first two arguments may have length > 1!");
  }

  for (esIndex in seq_along(arguments[[1]])) {
    for (pwrIndex in seq_along(arguments[[2]])) {
      tempEnvironment <-
        new.env();
      assign(argNames[1], arguments[[1]][esIndex],
             envir = tempEnvironment);
      assign(argNames[2], arguments[[2]][pwrIndex],
             envir = tempEnvironment);
      if (length(arguments) > 2) {
        for (i in 3:length(arguments)) {
          assign(argNames[i], arguments[[i]],
                 envir = tempEnvironment);
        }
      }
      print(argNames);
      print(as.list(tempEnvironment));
      print(ls(tempEnvironment));
      print(get('x', envir=tempEnvironment));
      print(get('n', envir=tempEnvironment));
      return(eval(expr = expression(expr),
                  envir = tempEnvironment)$estimate);
    }
  }
}

所以,那个错误使我难过。显然,loopFunction(binom.test(x=x,n=n), x=c(10,20), n=c(30, 100)); #> [1] "x" "n" #> $x #> [1] 10 #> #> $n #> [1] 30 #> #> [1] "n" "x" #> [1] 10 #> [1] 30 #> Error in binom.test(x = x, n = n): object 'x' not found 中存在xn;并将tempEnvironment传递给tempEnvironment

为什么这突然不再起作用?这在函数内部的工作方式是否不同?我缺少明显的东西吗?

1 个答案:

答案 0 :(得分:1)

我不确定parser.js在这种情况下为什么不起作用。但是,如果您将expression()写为字符串并将expr替换为expression(expr),则可以使用此方法:

parse(text=expr)

结果:

loopFunction <- function(expr,
                         ...) {

  ### Get all 'dots' in a named list
  arguments <- list(...);
  argNames <- names(arguments);

  if (any(length(tail(arguments, -2) > 1))) {
    stop("Only the first two arguments may have length > 1!");
  }

  for (esIndex in seq_along(arguments[[1]])) {
    for (pwrIndex in seq_along(arguments[[2]])) {
      tempEnvironment <-
        new.env();
      assign(argNames[1], arguments[[1]][esIndex],
             envir = tempEnvironment);
      assign(argNames[2], arguments[[2]][pwrIndex],
             envir = tempEnvironment);
      if (length(arguments) > 2) {
        for (i in 3:length(arguments)) {
          assign(argNames[i], arguments[[i]],
                 envir = tempEnvironment);
        }
      }
      print(argNames);
      print(as.list(tempEnvironment));
      print(ls(tempEnvironment));
      print(get('x', envir=tempEnvironment));
      print(get('n', envir=tempEnvironment));
      return(eval(expr=parse(text=expr), envir =tempEnvironment)$estimate)
    }
  }
}

loopFunction("binom.test(x, n)", x=10, n=30)