【问题标题】:In R, why rm(list<-ls()) does not work when <- is also assignment?在 R 中,当 <- 也是赋值时,为什么 rm(list<-ls()) 不起作用?
【发布时间】:2019-03-13 16:06:36
【问题描述】:

根据R manual

运算符

所以我尝试了 rm(list

rm(list=ls()) 没有任何问题。据我所知,

【问题讨论】:

  • 它们在设置函数参数时不会做同样的事情。在调用中使用时,&lt;- 在调用环境中分配一个变量,但不设置参数名称,而= 则相反。这里发生的事情就像alist(x &lt;- 1) 如何返回一个未命名的表达式列表,而alist(x = 1) 返回一个数字的命名列表。这很重要,因为所有关键字参数(... 之后的参数)都需要名称。
  • @alistaire 感谢您的有用评论。但是表达式列表和数字列表之间有什么区别?由于我无法为函数中的参数 x 执行“typeof”(即 alist(x=1) 和 alist(x
  • 如果你在它或子集上调用str,你可以看到。表达式是未计算的语言对象。假设你打算传递给参数的参数是一个数字,它会导致问题。

标签: r


【解决方案1】:

这是因为rm() 默认使用非标准评估。它会尝试删除您为不是list=(或pos=env=inherits=)的参数输入的内容。

所以你可以这样做

a <- 10
rm(a)

请注意,a 仅被解释为一个符号。它不会被评估以返回值。当您调用 rm(list&lt;-ls()) 时,您期望该表达式被评估,但事实并非如此。它试图找到一个名为"list&lt;-ls()" 的变量,但不存在这样的变量,因为任何变量都不应该有这样的名称。此外,它必须是一个“有效”的变量名。来自?make.names 帮助页面

语法上有效的名称由字母、数字和点或下划线字符组成,并以字母或点开头,后面不跟数字

这意味着它不会解析不寻常的变量名称,例如您可以通过转义带有反引号或单引号的符号来生成的变量名称。从技术上讲,您也可以这样做

a <- 10
rm("a")

因为非标准评估检查参数是否为文字字符值。但即使它们最终会返回一个字符值,它仍然不会评估任何表达式。例如

a <- 10
b <- "a"
rm(b)

上面发生的情况是 b 被删除,而不是 a

如果你想传入一个返回变量名的函数(就像ls() 所做的那样),你需要使用命名的list= 参数。 &lt;- 运算符不能替代 = 的命名参数。

【讨论】:

  • 当您在 Rstudio 上键入 ?rm 时,您可以看到 rm 接受的参数包括 ...(ellipsis)list=chracter()。这是否意味着除非明确指定为 list=ls(),否则 rm() 仅采用符号,例如您的变量 'a',其值为 10?
  • 另一个问题!我创建了两个这样的变量:'list
  • @Jinoo 我试图在答案中添加更多细节。需要注意的是typeof 不使用非标准评估,因此它评估您传递给它的参数。更恰当的比较是 typeof(quote(list&lt;-ls))typeof(quote(y)) 前者是“语言”(不能是变量名),后者是“符号”,即变量名。
【解决方案2】:

您正在阅读赋值操作的条目,而在 rm(list = ls() 的情况下,= 不用作赋值运算符,而是在函数调用中设置参数值(参见 @ 中的讨论987654321@).

我们举个例子来说明:

formals(print)
#> $x
#> 
#> 
#> $...
# The first argument to print() is named x
print(x = "a")
#> [1] "a"
# We've only set the value of argument x, not assigned to x
x
#> Error in eval(expr, envir, enclos): object 'x' not found
print(x <- "a")
#> [1] "a"
# Now we've assigned to x, and passed x as the first argument to print
x
#> [1] "a"
print(y <- "b")
#> [1] "b"
# It works with any variable name, since R can take variables by name or order
y
#> [1] "b"

reprex package (v0.2.1) 于 2018 年 10 月 8 日创建

更新

alistaire 对此问题发表了出色的评论,大约在我回答您也应该阅读的同时。

【讨论】:

    【解决方案3】:

    &lt;- 不是更通用。它仅适用于分配。 = 有两个用途:赋值和参数传递。在函数内部,= 执行参数分配,这就是您要在此处执行的操作。使用=,您不会创建具有值ls() 的变量list;您正在为函数rm() 的参数list 分配参数ls()

    rm() 的第一个参数是...,它必须是字符串或要删除的变量的名称。您传递了list &lt;- ls(),它既不是字符串也不是名称,这就是您收到错误的原因。如果要将ls()传递给rm()中的list参数,则需要使用=,而不是&lt;-

    【讨论】:

      猜你喜欢
      • 2018-04-08
      • 1970-01-01
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      • 2011-04-01
      • 2015-10-12
      • 2018-12-13
      • 1970-01-01
      相关资源
      最近更新 更多