在R中,为什么<-也是赋值,为什么rm(list <-ls())不起作用?

时间:2018-10-08 23:54:20

标签: r

根据R manual

  

运算符<-可以在任何地方使用,而运算符=仅在顶层使用(例如,在命令提示符下键入的完整表达式中)

所以我尝试了rm(list <-ls()),因为<-运算符可以如上所述在任何地方使用,但是R给我一个错误,说“ ...必须包含名称或字符串”。

rm(list = ls())可以正常工作。据我所知,<-是更通用的赋值,而=可以在更严格的情况下使用。但是为什么在函数中使用<-却会出错?

3 个答案:

答案 0 :(得分:6)

这是因为默认情况下rm()使用非标准评估。它会尝试删除您为非list=(或pos=env=inherits=)以外的参数输入的字面意思。

所以你可以做

a <- 10
rm(a)

请注意,a仅被解释为符号。不评估返回值。调用rm(list<-ls())时,您希望该表达式被求值,但事实并非如此。它正在尝试查找名为"list<-ls()"的变量,但是不存在这样的变量,因为没有变量应具有这样的名称。另外,它必须是一个“有效”变量名。从?make.names帮助页面

  

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

这意味着它将不会解析不寻常的变量名,就像您可以通过用反斜杠或单引号转义符号来创建的那样。从技术上讲,您也可以这样做

a <- 10
rm("a")

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

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

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

如果您要传递一个返回变量名称的函数(如ls()一样,则需要使用命名的list=参数)。 <-运算符不能代替=命名参数。

答案 1 :(得分:2)

您正在阅读赋值操作的条目,而对于rm(list = ls()=并不用作赋值运算符,而是在函数调用中设置参数值(请参见this Stack Overflow answer中的讨论。)

让我们以一个例子来说明:

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-08创建

更新

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

答案 2 :(得分:1)

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

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