867

=赋值运算符和R中有什么区别<-

我知道运营商略有不同,如本例所示

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

但这是唯一的区别吗?

4

8 回答 8

734

当您使用它们在函数调用中设置参数值时,赋值运算符的区别会更加明显。例如:

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+=在 Architect 中,Alt+-在 RStudio 中(Option+-在 macOS 下),Shift+ -(下划线)在 emacs+ESS 中。


如果您更喜欢写入=<-希望对公开发布的代码(例如在 CRAN 上)使用更常见的赋值符号,那么您可以使用包中的tidy_*功能之一formatR自动替换=<-.

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)

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

于 2009-11-16T14:36:35.430 回答
210
于 2018-07-27T19:17:14.773 回答
107

Google 的 R 风格指南通过禁止“=”进行赋值来简化问题。不错的选择。

https://google.github.io/styleguide/Rguide.xml

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

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

于 2009-11-16T14:44:30.187 回答
45

x = y = 5等价于x = (y = 5),因为赋值运算符从右到左“分组”,这是有效的。含义:将 5 分配给y,留下数字 5;然后将 5 分配给x.

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

当您混合使用不同类型的赋值运算符时,<-绑定比=. 所以x = y <- 5被解释为x = (y <- 5),这是有道理的。

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

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

于 2014-09-09T21:21:01.917 回答
35

根据 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

于 2011-01-28T18:34:34.610 回答
24

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

于 2009-11-16T12:21:15.760 回答
8

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

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

于 2016-12-10T21:32:04.733 回答
0

我不确定是否在这里引用了 Patrick Burns 的书 R i​​nferno,其中8.2.26 = 不是 <- Patrick 声明的同义词“当您想设置 a 的参数时,您显然不想使用 '<-'功能。”。这本书可在https://www.burns-stat.com/documents/books/the-r-inferno/

于 2021-09-06T16:57:42.717 回答