=
赋值运算符和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 "<-<-"
但这是唯一的区别吗?
当您使用它们在函数调用中设置参数值时,赋值运算符的区别会更加明显。例如:
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
帮助页面所示。
Google 的 R 风格指南通过禁止“=”进行赋值来简化问题。不错的选择。
https://google.github.io/styleguide/Rguide.xml
R 手册详细介绍了所有 5 个赋值运算符。
http://stat.ethz.ch/R-manual/R-patched/library/base/html/assignOps.html
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
。
根据 John Chambers 的说法,运算符=
只允许在“顶层”使用,这意味着它不允许出现在控制结构中,例如if
,使得以下编程错误是非法的。
> if(x = 0) 1 else x
Error: syntax error
正如他所写,“在控制表达式中禁止使用新的赋值形式 [=] 可以避免编程错误(例如上面的示例),使用等号运算符比使用其他 S 赋值更有可能出现这种错误。”
如果它“通过大括号或一对额外的括号与周围的逻辑结构隔离”,那么您可以设法做到这一点if ((x = 0)) 1 else x
。
运算符<-
并将=
其分配到评估它们的环境中。运算符<-
可以在任何地方使用,而运算符=
只允许在顶层(例如,在命令提示符下键入的完整表达式中)或作为表达式括号列表中的子表达式之一。
这也可能增加对这两个运算符之间差异的理解:
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
我不确定是否在这里引用了 Patrick Burns 的书 R inferno,其中8.2.26 = 不是 <- Patrick 声明的同义词“当您想设置 a 的参数时,您显然不想使用 '<-'功能。”。这本书可在https://www.burns-stat.com/documents/books/the-r-inferno/