Programing

R에서 "="와 "<-"할당 연산자의 차이점은 무엇입니까?

lottogame 2020. 10. 2. 21:22
반응형

R에서 "="와 "<-"할당 연산자의 차이점은 무엇입니까?


할당 연산자 =<-R 의 차이점은 무엇입니까 ?

이 예에서 볼 수 있듯이 연산자는 약간 다릅니다.

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

그러나 이것이 유일한 차이점입니까?


할당 연산자 =<-R 의 차이점은 무엇입니까 ?

하여 예에서 보듯이, =그리고 <-(그들은 같은 식으로 혼합되는 경우 계산 순서를 결정하는) 약간 다른 연산자 우선 순위를 갖는다. 실제로 ?SyntaxR 에서는 가장 높은 것부터 가장 낮은 것까지 다음과 같은 연산자 우선 순위 테이블을 제공합니다.


‘-> ->>’           rightwards assignment
‘<- <<-’           assignment (right to left)
‘=’                assignment (right to left)

그러나 이것이 유일한 차이점입니까?

할당 연산자 에 대해 질문했기 때문에 예, 그게 유일한 차이점입니다. 그러나 당신은 그렇지 않다고 믿으면 용서받을 것입니다. ?assignOps더 많은 차이점이 있다는 주장 의 R 문서조차 :

연산자 <-는 어디에서나 사용할 수 있지만 연산자 =는 최상위 수준 (예 : 명령 프롬프트에 입력 된 전체 식) 또는 중괄호 식 목록의 하위 식 중 하나로 만 허용됩니다.

그것에 대해 너무 세밀하게 언급하지 말자 : R 문서는 (미묘하게) 틀렸다 [ 1 ] . 이것은 쉽게 보여줄 수 있습니다. 우리 =는 (a) 최상위 수준이 아니고 (b) 중괄호로 묶인 표현식 목록 (예 :)에서 하위 표현식이 아닌 연산자 의 반대 예제를 찾아야합니다 {…; …}. — 더 이상 고민하지 않고 :

x
# Error: object 'x' not found
sum((x = 1), 2)
# [1] 3
x
# [1] 1

분명히 우리는 =컨텍스트 (a) 및 (b) 외부 에서를 사용하여 할당을 수행했습니다 . 그렇다면 핵심 R 언어 기능에 대한 문서가 수십 년 동안 잘못된 이유는 무엇입니까?

R의 구문에서 기호 =는 일상적으로 합쳐지는 두 가지 다른 의미를 갖기 때문입니다.

  1. 첫 번째 의미는 할당 연산자 입니다. 이것이 우리가 지금까지 이야기 한 전부입니다.
  2. 두 번째 의미는 연산자가 아니라 함수 호출에서 전달 되는 명명 된 인수 를 신호 하는 구문 토큰 입니다 . 연산자 와 달리 런타임에 아무 작업도 수행하지 않고식이 구문 분석되는 방식 만 변경합니다.=

보자.

일반적인 형식의 모든 코드에서…

‹function_name›(‹argname› = ‹value›, …)
‹function_name›(‹args›, ‹argname› = ‹value›, …)

=명명 된 인수 전달을 정의하는 토큰입니다 . 할당 연산자 아닙니다 . 또한 일부 구문 컨텍스트에서는 =완전히 금지 됩니다.

if (‹var› = ‹value›) …
while (‹var› = ‹value›) …
for (‹var› = ‹value› in ‹value2›) …
for (‹var1› in ‹var2› = ‹value›) …

이 중 하나라도 "bla›에 예기치 않은 '='오류가 발생합니다.

In any other context, = refers to the assignment operator call. In particular, merely putting parentheses around the subexpression makes any of the above (a) valid, and (b) an assignment. For instance, the following performs assignment:

median((x = 1 : 10))

But also:

if (! (nf = length(from))) return()

Now you might object that such code is atrocious (and you may be right). But I took this code from the base::file.copy function (replacing <- with =) — it’s a pervasive pattern in much of the core R codebase.

The original explanation by John Chambers, which the the R documentation is probably based on, actually explains this correctly:

[= assignment is] allowed in only two places in the grammar: at the top level (as a complete program or user-typed expression); and when isolated from surrounding logical structure, by braces or an extra pair of parentheses.


A confession: I lied earlier. There is one additional difference between the = and <- operators: they call distinct functions. By default these functions do the same thing but you can override either of them separately to change the behaviour. By contrast, <- and -> (left-to-right assignment), though syntactically distinct, always call the same function. Overriding one also overrides the other. Knowing this is rarely practical but it can be used for some fun shenanigans.


The difference in assignment operators is clearer when you use them to set an argument value in a function call. For example:

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

In this case, x is declared within the scope of the function, so it does not exist in the user workspace.

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

In this case, x is declared in the user workspace, so you can use it after the function call has been completed.


There is a general preference among the R community for using <- for assignment (other than in function signatures) for compatibility with (very) old versions of S-Plus. Note that the spaces help to clarify situations like

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

Most R IDEs have keyboard shortcuts to make <- easier to type. Ctrl + = in Architect, Alt + - in RStudio (Option + - under macOS), Shift + - (underscore) in emacs+ESS.


If you prefer writing = to <- but want to use the more common assignment symbol for publicly released code (on CRAN, for example), then you can use one of the tidy_* functions in the formatR package to automatically replace = with <-.

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

The answer to the question "Why does x <- y = 5 throw an error but not x <- y <- 5?" is "It's down to the magic contained in the parser". R's syntax contains many ambiguous cases that have to be resolved one way or another. The parser chooses to resolve the bits of the expression in different orders depending on whether = or <- was used.

To understand what is happening, you need to know that assignment silently returns the value that was assigned. You can see that more clearly by explicitly printing, for example print(x <- 2 + 3).

Secondly, it's clearer if we use prefix notation for assignment. So

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

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

The parser interprets x <- y <- 5 as

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

We might expect that x <- y = 5 would then be

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

but actually it gets interpreted as

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

This is because = is lower precedence than <-, as shown on the ?Syntax help page.


Google's R style guide simplifies the issue by prohibiting the "=" for assignment. Not a bad choice.

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

The R manual goes into nice detail on all 5 assignment operators.

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


x = y = 5 is equivalent to x = (y = 5), because the assignment operators "group" right to left, which works. Meaning: assign 5 to y, leaving the number 5; and then assign that 5 to x.

This is not the same as (x = y) = 5, which doesn't work! Meaning: assign the value of y to x, leaving the value of y; and then assign 5 to, umm..., what exactly?

When you mix the different kinds of assignment operators, <- binds tighter than =. So x = y <- 5 is interpreted as x = (y <- 5), which is the case that makes sense.

Unfortunately, x <- y = 5 is interpreted as (x <- y) = 5, which is the case that doesn't work!

See ?Syntax and ?assignOps for the precedence (binding) and grouping rules.


According to John Chambers, the operator = is only allowed at "the top level," which means it is not allowed in control structures like if, making the following programming error illegal.

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

As he writes, "Disallowing the new assignment form [=] in control expressions avoids programming errors (such as the example above) that are more likely with the equal operator than with other S assignments."

You can manage to do this if it's "isolated from surrounding logical structure, by braces or an extra pair of parentheses," so if ((x = 0)) 1 else x would work.

See http://developer.r-project.org/equalAssign.html


The operators <- and = assign into the environment in which they are evaluated. The operator <- can be used anywhere, whereas the operator = is only allowed at the top level (e.g., in the complete expression typed at the command prompt) or as one of the subexpressions in a braced list of expressions.


This may also add to understanding of the difference between those two operators:

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

For the first element R has assigned values and proper name, while the name of the second element looks a bit strange.

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 version 3.3.2 (2016-10-31); macOS Sierra 10.12.1

참고URL : https://stackoverflow.com/questions/1741820/what-are-the-differences-between-and-assignment-operators-in-r

반응형