R 中未计算的参数

Unevaluated argument in R

我还是R的新手,对惰性求值还很了解。我在 SO (R functions that pass on unevaluated arguments to other functions) 上阅读了很多线程,但我仍然不确定。

问题一:

这是我的代码:

f <- function(x = ls()) {
  a<-1
  #x ##without x
  }
f(x=ls())

当我执行此代码时,即 f(),什么也没有 returns。具体来说,我没有看到 a 的值。为什么会这样?

问题二:

此外,我确实在这段代码中看到了 a 的值:

f <- function(x = ls()) {
  a<-1
  x ##with x
  }
f(x=ls())

当我通过 f() 执行函数时,我得到:

[1] "a" "x"

为什么会这样?有人可以帮我吗?

问题一

这与惰性求值无关。

一个函数return是它执行的最后一条语句的结果。在这种情况下,最后一条语句是 a <- 1a <- 1 的结果是 1。例如,您可以执行 b <- a <- 1,这将导致 b 等于 1。因此,在这种情况下,您的函数是 returns 1。

> f <- function(x = ls()) {
+   a<-1
+   }
> b <- f(x=ls())
> print(b)
[1] 1

参数x没有被使用,所以没有任何作用。

函数可以 return 可见(默认)或不可见的值。为了 return 不可见,可以使用函数 invisible。一个例子:

> f1 <- function() {
+   1
+ }
> f1()
[1] 1
> 
> f2 <- function() {
+   invisible(1)
+ }
> f2()
> 

在这种情况下 f2 似乎 return 什么都没有。但是,它仍然是 return 的值 1。invisible 所做的是在调用函数时不打印任何内容,并且结果未分配给任何内容。与您的示例相关的是 a <- 1 也 return 是无形的。这就是您的函数似乎没有 return 任何内容的原因。但是当赋值给上面的b时,b仍然得到值1。

问题二

首先,我将解释为什么您会看到您看到的结果。您在结果中看到的 a 是由之前的一些代码引起的。如果我们先清理工作区,我们只会看到 f。这是有道理的,因为我们创建了一个变量 f(函数在 R 中也是一个变量),然后执行 ls()

> rm(list = ls())
> 
> f <- function(x = ls()) {
+   a<-1
+   x 
+ }
> f(x=ls())
[1] "f"

函数的作用(至少是您所期望的),如果首先列出所有变量 ls() 然后将结果作为 x 传递给函数。这个函数然后 returns x,这是所有变量的列表,然后被打印出来。

如何修改它以显示工作中的懒惰评估

> rm(list = ls())
> 
> f <- function(x) {
+   a <<- 1
+   x
+ }
> 
> f(x = ls())
[1] "a" "f"
> 

在这种情况下,使用了全局赋值 (a <<- 1),它在全局工作区中创建了一个新变量 a(这不是您通常想要做的事情)。

在这种情况下,人们仍然希望函数调用的结果只是 f。它也显示 a 的事实是由惰性评估引起的。

如果没有惰性求值,它将首先求值 ls()(当时工作区中只有 f),然后将其复制到名称为 x 的函数中。然后函数returns x。在这种情况下, ls() 在创建 a 之前被评估。

但是,使用惰性求值,表达式 ls() 仅在需要表达式的结果时才求值。在这种情况下,即打印函数 returns 和结果时。那时全局环境发生了变化(创建了a),也就是说ls()也显示了a

(这也是您不希望函数使用 <<- 更改全局工作区的原因之一。)