为啥不能在函数中使用“=” R 运算符?

Posted

技术标签:

【中文标题】为啥不能在函数中使用“=” R 运算符?【英文标题】:Why the "=" R operator should not be used in functions?为什么不能在函数中使用“=” R 运算符? 【发布时间】:2012-06-12 13:12:51 【问题描述】:

The manual 状态:

操作符‘

The question here 提到在函数调用中使用时的区别。但在函数定义中,似乎可以正常工作:

a = function () 

    b = 2
    x <- 3
    y <<- 4


a()
# (b and x are undefined here)

那么为什么手册会提到the operator ‘=’ is only allowed at the top level??

language definition 中没有任何内容(没有列出 = 运算符,真可惜!)

【问题讨论】:

您引用的文本说“在子表达式的括号列表中的*** OR”。您在子表达式的花括号列表中使用它。这是允许的。 你必须不遗余力地找到一个既不是顶层也不是大括号内的表达式。这是一个。有时您希望将赋值封装在 try 块中:try( x &lt;- f() ) 可以,但 try( x = f(x) ) 不行——您需要更改赋值运算符或添加大括号。 另一个例子是当您将表达式包装在 system.time 调用中时:system.time(a &lt;- runif(10000))。我几乎只使用 = 赋值,也没有遇到很多问题。 system.time(notanargumentofsystem.time = 1) 哦,混蛋 @GavinSimpson 我相信fun(a &lt;- 1) 的混乱程度大于a &lt;- 1; fun(a) 的好处。在其他语言中很少看到赋值代替函数参数。 R 是一种奇怪但无论如何都很棒的语言。 &lt;- 在任何地方工作都是危险的,而我过去看到的另一个危险是当人们的意思是 x smaller than negative 1 时,他们忘记了空格并以 x&lt;-1 结束(你可能会笑,但它确实发生了) 【参考方案1】:

你引用的文字是at the top level OR in a braced list of subexpressions。您在子表达式的花括号列表中使用它。哪个是允许的。

你必须不遗余力地找到一个既不是顶层也不是大括号内的表达式。这是一个。有时您想在 try 块中包装赋值:try( x &lt;- f() ) 可以,但 try( x = f(x) ) 不行——您需要更改赋值运算符或添加大括号。

【讨论】:

文森特,谢谢,但这如何回答我关于b = 2 在我的示例中出错的问题?也许我错过了一些东西,所以请用更明显的方式解释:) @Tomas 我添加了您认为有帮助的评论。我认为这回答了这个问题。 但是,try((x = f())) 工作正常。 R 文档在声明其他方面是完全错误的。【参考方案2】:

不在顶层的表达式包括在if 等控制结构中的使用。例如下面的编程错误是非法的。

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

这里提到:https://***.com/a/4831793/210673

另见http://developer.r-project.org/equalAssign.html

【讨论】:

感谢second link!最重要的信息是:“在允许的情况下,= 运算符在语义上等同于所有早期分配(即&lt;- 和其他)。”【参考方案3】:

除了一些例子,如system.time,正如其他人所展示的那样,&lt;-= 有不同的结果,主要区别是更哲学的。 Perl 的创建者 Larry Wall 说过“相似的东西应该看起来相似,不同的东西应该看起来不同”这样的话,我发现在不同的语言中看看哪些东西被认为是“相似的”以及哪些被认为是很有趣的不同的”。现在对于 R 分配,让我们比较 2 个命令:

myfun( a <- 1:10 )

myfun( a = 1:10 )

有些人会争辩说,在这两种情况下,我们都将1:10 分配给a,所以我们所做的事情是相似的。

另一个论点是,在第一次调用中,我们分配给变量a,该变量与调用myfun的环境相同,而在第二次调用中,我们分配给变量a在调用函数时创建的环境中,并且是函数的本地变量,这两个a 变量是不同的。

因此,使用哪个取决于您认为分配是“相似”还是“不同”。

就我个人而言,我更喜欢&lt;-,但我认为不值得为此打一场圣战。

【讨论】:

以上是关于为啥不能在函数中使用“=” R 运算符?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能将接口与显式运算符一起使用? [复制]

为啥 `R` 管道运算符 `|>` 在使用 Shiny 的反应式编程中不起作用?

为啥我不能在没有括号的插值字符串中使用条件运算符? [复制]

C# - 为啥我不能在字符串中使用三元运算符? [复制]

为啥我们不能在 Array.map() 中使用扩展运算符,还有啥可以替代展平数组? [复制]

为啥 R 使用部分匹配?