할당 연산자 =
와 <-
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 "<-<-"
그러나 이것이 유일한 차이점입니까?
답변:
할당 연산자
=
와<-
R 의 차이점은 무엇입니까 ?
하여 예에서 보듯이, =
그리고 <-
(그들은 같은 식으로 혼합되는 경우 계산 순서를 결정하는) 약간 다른 연산자 우선 순위를 갖는다. 실제로 ?Syntax
R에서 다음과 같은 연산자 우선 순위 테이블을 제공합니다.
… ‘-> ->>’ 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의 구문에서 기호 =
는 일상적으로 접히는 두 가지 고유 한 의미를 갖기 때문입니다.
=
보자
일반적인 형태의 모든 코드에서…
‹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›에서 예기치 않은 '='"오류가 발생합니다.
다른 상황에서는 =
할당 연산자 호출을 나타냅니다. 특히, 서브 표현식 주위에 괄호를 두는 것만으로 위의 (a)가 유효하고 (b) 대입이 됩니다. 예를 들어 다음은 할당을 수행합니다.
median((x = 1 : 10))
또한 :
if (! (nf = length(from))) return()
이제 그러한 코드가 끔찍하다고 반대 할 수도 있습니다 (그리고 여러분이 옳을 수도 있습니다). 하지만 난에서이 코드를했다 base::file.copy
(대체 기능 <-
으로 =
는 핵심 R 코드베이스의 대부분의 보급 패턴의 -).
R 문서에 기반한 John Chambers 의 원래 설명 은 실제로 이것을 올바르게 설명합니다.
[
=
할당]은 문법의 두 곳에서만 가능합니다 : 최상위 레벨 (완전한 프로그램 또는 사용자 유형 표현); 주변의 논리적 구조와 격리 할 때 중괄호 또는 추가 괄호로 묶습니다.
고백 : 나는 일찍 거짓말을했다. 이 입니다 사이 하나 개의 추가 차이 =
및 <-
사업자 : 그들은 서로 다른 함수를 호출. 기본적으로 이러한 기능은 동일하지만 동작을 변경하기 위해 이들 중 하나를 개별적으로 재정의 할 수 있습니다. 반면,으로 <-
하고 ->
있지만 구문 별개의 (왼쪽에서 오른쪽으로 할당), 항상 전화 같은 기능을. 하나를 재정의하면 다른 것도 재정의됩니다. 이것을 아는 것은 거의 실용적이 아니지만 재미있는 재미를 위해 사용될 수 있습니다 .
?
가 실제로와 사이에 =
있으며 <-
재정의 할 때 중요한 결과를 낳습니다 ?
.
=
구문 분석 트리가 작성되기 전에 특별한 치료 를 받는 다고 생각합니다 . 함수 인수와 관련하여 어쩌면 나머지 표현식을 구문 분석하기 전에 foo(x = a ? b)
살펴 보는 것이 좋습니다 =
.
할당 연산자 의 차이점은 함수 호출에서 인수 값을 설정하기 위해 사용할 때 더 명확합니다. 예를 들면 다음과 같습니다.
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+ =건축가에, Alt+ -RStudio에서 ( Option+ -맥 OS 미만) Shift+ -이맥스 +의 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
median((x = 1:10))
와 동일한 효과가 median(x <- 1:10)
있습니다.
x <- x = 5
해석 방법에 대한 당신의 설명 이 약간 잘못되었다는 것을 깨달았습니다 . 실제로 R은 그것을 `<-<-`(x, y = 5, value = 5)
(그 자체가 다소 비슷합니다)로 해석합니다 tmp <- x; x <- `<-<-`(tmp, y = 5, value = 5)
. 이케!
=
함수 호출에 할당을 수행하지 않습니다 및 할당 연산자가 아닙니다. 완전히 구별 된 구문 분석 된 R 표현식이며 동일한 문자를 사용합니다. 또한 표시하는 코드 x
는 함수 범위에서 "선언"하지 않습니다 . 함수 선언 행한다는 선언했다. 함수 호출은 그렇지 않습니다 (이름이 지정된 ...
인수 로 조금 더 복잡해집니다 ).
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
때 의 우연한 할당의 단점은 x < -y
내가 개인적으로 선호하는 것을 너무나 싫어합니다 =
. 공백에 의존하여 코드를 작성하는 것은 좋지 않습니다. 스타일 조언으로 간격을 제안하는 것이 좋지만 공간이 있는지 여부에 관계없이 코드가 다르게 실행됩니까? 코드를 다시 포맷하거나 검색 및 바꾸기를 사용하면 공백이 사라지고 코드가 잘못 될 수 있습니다. 그것은 문제가되지 않습니다 =
. IIUC, =
" <-
"; 즉, " <-
" 뿐만 아니라 공백을 포함하여 3 자 입니다.
TRUE
경우 테스트하려는 경우 R. 그래서 의해 x
보다 작은 -y
, 당신이 쓸 수있는 if (x<-y)
경고 또는 오류 및 작업 벌금 나타나지 않을 것이다. 그것은 단지 수 있습니다 FALSE
때 y=0
, 그래도.
=
하고 사용 <-
하면 추가 단계 grep "[^<]<-[^ ]" *.R
가 필요하지 않다고 주장하기가 어렵습니다 . =
그런 필요하지 않습니다 grep
.
<-
사용할 수 있다면 왜 눈과 손가락을 다치게 =
합니까? 시간의 99.99 %에서 =
좋습니다. 때로는 당신이 필요 <<-
하지만 다른 역사입니다.
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
우선 순위에 대한 (바인딩)과 규칙을 그룹화.
<- <<-
가 위에 나와 있습니다. =
즉, <-
먼저 실행됩니다. 따라서 x <- y = 5
로 실행해야합니다 (x <- y) = 5
.
John Chambers에 따르면, 작업자 =
는 "최상위 수준"에서만 허용됩니다. 즉 if
, 다음과 같은 제어 구조에서는 허용되지 않으므로 다음 프로그래밍 오류가 불법이됩니다.
> if(x = 0) 1 else x
Error: syntax error
그는 "제어식에서 새로운 할당 형식 [=]을 허용하지 않으면 다른 S 할당보다 동일한 연산자에서 발생하는 프로그래밍 오류 (예 : 위의 예)를 피할 수 있습니다."라고 말합니다.
"중괄호 나 여분의 괄호로 둘러싼 논리적 구조와 분리 된"경우이 작업을 수행 할 수 있습니다 if ((x = 0)) 1 else x
.
x==0
이며 거의 항상 의미가 있습니다.
x=0
할당보다 선호하는 좋은 이유 x<-0
!
=
있기 때문에 가능한 한 적게 =
하고 ==
모양과 유사하므로.
if(x = 0) 1 else x
오류를 찾아서 버그를 찾아서 수정하는 데 도움이됩니다. if(x <- 1) 1 else x
오류가 발생하지 않으며 매우 혼란 스럽습니다.
else
... 파이프 꿈 수,?, 값을 당신이 그런 식으로 작성하는 것을 의미했다"하지만
운영자 <-
와 =
그들이 평가되는 환경에 할당합니다. 연산자 <-
는 어디에서나 사용할 수 있지만 연산자 =
는 최상위 수준 (예 : 명령 프롬프트에 입력 된 전체 식) 또는 괄호 식 목록의 하위 식 중 하나 에서만 허용됩니다 .
x <- 42
그 자체로 진술이 있습니다. 에 if (x <- 42) {}
그것을 표현, 그리고 유효하지 않은 것입니다. 분명히, 이것은 당신이 지구 환경에 있는지 여부와 관계가 없습니다.
1 + (x = 2)
function() x = 1
, repeat x = 1
, if (TRUE) x = 1
...
또한이 두 연산자의 차이점을 이해하는 데 도움이 될 수 있습니다.
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
data.frame
제공된 변수의 이름을 데이터 프레임의 요소 이름으로 사용하려고합니다 . )
make.names("b <- rnorm(10)")
합니다.
<-
심볼 의 기원은 실제로 단일<-
키 가있는 오래된 APL 키보드에서 나옵니다 .