在R中赋值运算符=和<-之间有什么区别?
我知道操作符略有不同,如本例所示
x <- y <- 5
x = y = 5
x = y <- 5
x <- y = 5
# Error in (x <- y) = 5 : could not find function "<-<-"
但这是唯一的不同吗?
在R中赋值运算符=和<-之间有什么区别?
我知道操作符略有不同,如本例所示
x <- y <- 5
x = y = 5
x = y <- 5
x <- y = 5
# Error in (x <- y) = 5 : could not find function "<-<-"
但这是唯一的不同吗?
当前回答
根据John Chambers的说法,操作符=只允许在“顶层”,这意味着它不允许在像if这样的控制结构中,这使得下面的编程错误是非法的。
> if(x = 0) 1 else x
Error: syntax error
正如他所写的,“在控制表达式中禁止新的赋值形式[=]可以避免编程错误(如上面的例子),与其他S赋值相比,相等操作符更有可能出现这种错误。”
如果它“通过大括号或一对额外的圆括号与周围的逻辑结构隔离”,则可以做到这一点,因此if ((x = 0)) 1否则x就可以工作。
参见http://developer.r-project.org/equalAssign.html
其他回答
在函数调用中使用赋值操作符来设置实参值时,赋值操作符之间的区别更加明显。例如:
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是在用户工作区中声明的,因此可以在函数调用完成后使用它。
为了兼容(非常)老版本的S-Plus, R社区普遍倾向于使用<-进行赋值(函数签名除外)。注意,空格有助于阐明情况,如
x<-3
# Does this mean assignment?
x <- 3
# Or less than?
x < -3
大多数R ide都有快捷键,使<-更容易输入。Architect中的Ctrl + =, RStudio中的Alt + - (macOS下的Option + -), emacs+ESS中的Shift + -(下划线)。
如果你更喜欢写=而不是<-,但想要为公开发布的代码(例如在CRAN上)使用更常见的赋值符号,那么你可以使用formatR包中的tidy_*函数之一自动将=替换为<-。
library(formatR)
tidy_source(text = "x=1:5", arrow = TRUE)
## x <- 1:5
对于“为什么x <- y = 5抛出错误而x <- y <- 5没有抛出错误?”这个问题的答案是“这取决于解析器中包含的魔法”。R的语法包含许多必须以某种方式解决的模糊情况。解析器根据是否使用=或<-来选择以不同的顺序解析表达式的位。
为了理解发生了什么,您需要知道赋值函数会默默地返回被赋值的值。通过显式打印可以更清楚地看到这一点,例如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)
这是因为=的优先级低于<-,请参见?语法帮助页面。
根据John Chambers的说法,操作符=只允许在“顶层”,这意味着它不允许在像if这样的控制结构中,这使得下面的编程错误是非法的。
> if(x = 0) 1 else x
Error: syntax error
正如他所写的,“在控制表达式中禁止新的赋值形式[=]可以避免编程错误(如上面的例子),与其他S赋值相比,相等操作符更有可能出现这种错误。”
如果它“通过大括号或一对额外的圆括号与周围的逻辑结构隔离”,则可以做到这一点,因此if ((x = 0)) 1否则x就可以工作。
参见http://developer.r-project.org/equalAssign.html
这也有助于理解这两个操作符之间的区别:
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
在R的过去版本甚至R的前身语言(S语言)中,<-和=之间存在一些差异。但目前,像使用其他现代语言(python, java)一样使用=似乎不会引起任何问题。你可以通过使用<-来实现更多的功能,当传递一个值给一些增强,同时也创建一个全局变量,但它可能会有奇怪的/不想要的行为,如in
df <- data.frame(
a = rnorm(10),
b <- rnorm(10)
)
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 ...
强烈推荐!试着阅读这篇文章,这是试图解释这两者区别的最好的文章: 检查https://colinfay.me/r-assignment/
此外,可以将<-看作一个无形地返回一个值的函数。
a <- 2
(a <- 2)
#> [1] 2
参见:https://adv-r.hadley.nz/functions.html
谷歌的R样式指南通过禁止赋值使用“=”简化了这个问题。不错的选择。
https://google.github.io/styleguide/Rguide.xml
R手册详细介绍了所有5个赋值操作符。
http://stat.ethz.ch/R-manual/R-patched/library/base/html/assignOps.html