提问



R中赋值运算符=<-之间有什么区别?


我知道运营商略有不同,正如这个例子所示


x <- y <- 5
x = y = 5
x = y <- 5
x <- y = 5
# Error in (x <- y) = 5 : could not find function "<-<-"


但这是唯一的区别吗?

最佳参考


当您使用它们在函数调用中设置参数值时,赋值运算符的差异会更明显。例如:[58]


median(x = 1:10)
x   
## Error: object 'x' not found


在这种情况下,x在函数范围内声明,因此它不存在于用户工作区中。


median(x <- 1:10)
x    
## [1]  1  2  3  4  5  6  7  8  9 10


在这种情况下,x在用户工作区中声明,因此您可以在函数调用完成后使用它。





R社区普遍倾向于使用<-进行分配(功能签名除外)以兼容(非常)旧版本的S-Plus。请注意,空格有助于澄清类似的情况


x<-3
# Does this mean assignment?
x <- 3
# Or less than?
x < -3





大多数R IDE都有键盘快捷键,使<-更容易输入。建筑师中的 Ctrl + =,RStudio中的 Alt + - ( Option + <在emacs + ESS中,kbd> - 在macOS下), Shift + - (下划线)。





如果您更喜欢将=编写为<-,但希望对公开发布的代码使用更常见的赋值符号(例如,在CRAN上),那么您可以使用tidy_*函数之一formatR包用<-自动替换=[59]


library(formatR)
tidy_source(text = "x=1:5", arrow = TRUE)
## x <- 1:5





问题的答案为什么x <- y = 5会抛出错误而不是x <- y <- 5?是它归结为解析器中包含的魔力.R的语法包含许多模糊的情况,必须以某种方式解决。解析器选择以不同的顺序解析表达式的位,具体取决于是否使用=<-[60]


要了解发生的情况,您需要知道该任务以静默方式返回已分配的值。您可以通过明确打印更清楚地看到,例如print(x <- 2 + 3)


其次,如果我们使用前缀表示法进行分配,那就更清楚了


x <- 5
`<-`(x, 5)  #same thing

y = 5
`=`(y, 5)   #also the same thing


解析器将x <- y <- 5解释为


`<-`(x, `<-`(y, 5))


我们可能会期待x <- y = 5


`<-`(x, `=`(y, 5))


但实际上它被解释为


`=`(`<-`(x, y), 5)


这是因为=的优先级低于<-,如?Syntax帮助页面所示。​​[61]

其它参考1


Google的R风格指南通过禁止=来简化问题。这不是一个糟糕的选择。


https://google.github.io/styleguide/Rguide.xml[62]


R手册详细介绍了所有5个赋值运算符。


http://stat.ethz.ch/R-manual/R-patched/library/base/html/assignOps.html[63]

其它参考2


根据John Chambers的说法,运算符=仅允许在顶层,这意味着它不允许在if之类的控制结构中,使得以下编程错误成为非法。


> if(x = 0) 1 else x
Error: syntax error


正如他所写的那样,在控制表达式中不允许新的赋值形式[[=]]避免了编程错误(例如上面的例子),这些错误更可能与运算符相等而不是其他S赋值。


如果它与周围的逻辑结构,大括号或一对额外的括号隔离,你可以设法做到这一点,所以if ((x = 0)) 1 else x会起作用。


见http://developer.r-project.org/equalAssign.html [64]

其它参考3


x = y = 5相当于x = (y = 5),因为赋值运算符组从右到左,有效。含义:将5分配给y,保留数字5;然后将该5分配给x


这与(x = y) = 5不同,它不起作用!含义:将y的值赋给x,保留y的值;然后分配5对,嗯......到底是什么?


混合不同类型的赋值运算符时,<-=更紧密。所以x = y <- 5被解释为x = (y <- 5),这是有道理的。


不幸的是,x <- y = 5被解释为(x <- y) = 5,这是不起作用的情况!


有关优先级(绑定)和分组规则,请参见?Syntax?assignOps

其它参考4


运算符<-=分配到评估它们的环境中。运算符<-可以在任何地方使用, ,而运算符=只允许在顶层 (例如,在输入的完整表达式中)命令提示符)或作为支持的表达式列表中的子表达式之一。

其它参考5


这也可以增加对这两个运算符之间差异的理解:


df <- data.frame(
      a = rnorm(10),
      b <- rnorm(10)
)


对于第一个元素,R已经赋值和正确的名称,而第二个元素的名称看起来有点奇怪。


str(df)
# 'data.frame': 10 obs. of  2 variables:
#  $ a             : num  0.6393 1.125 -1.2514 0.0729 -1.3292 ...
#  $ b....rnorm.10.: num  0.2485 0.0391 -1.6532 -0.3366 1.1951 ...


R版本3.3.2(2016-10-31); macOS Sierra 10.12.1