Menu

R 연산자: 산술, 비교, 논리, %in%과 %%

R에서 필요한 모든 연산자입니다. %%와 %/%를 포함한 산술 연산, 벡터화된 비교, &와 &&의 차이, 그리고 포함 여부를 검사하는 %in%을 다룹니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

R이 제공하는 연산자들

R의 연산자는 네 가지 작업 그룹으로 나뉩니다. 산술(+ - * / ^ %% %/%), 비교(== != < <= > >=), 논리(& | && || ! xor), 그리고 포함 검사 %in%입니다. 대부분의 언어와 다른 점이 두 가지 있습니다. 거의 모든 연산자가 벡터화되어 있어 벡터 전체에 원소 단위로 한 번에 동작한다는 점, 그리고 서로 바꿔 쓸 수 없는 AND 연산자 두 개와 OR 연산자 두 개가 있다는 점입니다. 이 페이지에서는 이들 전부와, 조용히 잘못된 답을 만들어 내는 우선순위 함정을 다룹니다.

산술: +, -, *, /, ^, %%, %/%

처음 다섯 개는 예상대로 동작합니다. 퍼센트로 감싼 두 개, 즉 %%(나머지)와 %/%(정수 나눗셈의 몫)가 사람들이 검색하는 것들입니다.

/는 언제나 부동소수점 나눗셈을 한다는 점에 주의하세요. 17 / 53이 아니라 3.4입니다. 정수 부분을 원한다면 그것이 바로 %/%의 용도입니다.

%%의 일상적인 역할은 나누어떨어짐 판정입니다. 2로 나눈 나머지가 없으면 짝수입니다.

두 번째 줄은 잠시 멈춰 볼 만합니다. 피연산자가 음수일 때 R의 %%제수의 부호를 가진 결과를 돌려줍니다(-7 = -3 * 3 + 2이므로 -7 %% 32입니다). 어떤 언어는 반대로 동작하니, 코드를 이식하는 중이라면 확인하세요.

비교 연산자는 벡터화되어 있습니다

==, !=, <, <=, >, >=는 원소 단위로 비교해 단일 답이 아니라 논리 벡터를 돌려줍니다.

이것이 R에서 이루어지는 거의 모든 필터링의 엔진입니다. 벡터 전체를 어떤 값과 비교해 논리 마스크를 얻고, 그 마스크로 부분 집합을 뽑습니다. 소수에 ==를 쓸 때 한 가지 주의가 필요합니다. 부동소수점 수는 근사적으로 저장되므로 0.1 + 0.2 == 0.3FALSE입니다. 소수 비교에는 all.equal()을 쓰거나 abs(x - y) < 1e-9을 확인하세요.

논리 연산자: &와 && (고전적인 혼란)

R에는 AND 연산자 두 개와 OR 연산자 두 개가 있고, 잘못 고르는 것은 일종의 통과 의례입니다.

&|는 벡터화되어 있습니다. 두 논리 벡터를 원소 단위로 결합합니다.

데이터에 필터를 만들 때는 언제나 이쪽을 쓰세요. 예: df[df$age > 30 & df$city == "Lisbon", ].

&&||는 스칼라이고 단축 평가를 합니다. 단일 값을 받아 하나의 TRUE/FALSE를 돌려주며, 첫 피연산자가 이미 답을 정하면 두 번째는 아예 건너뜁니다.

두 번째 줄이 단축 평가를 보여 줍니다. x < 0FALSE이므로 R은 stop() 호출을 결코 평가하지 않습니다. &&if() 조건에 어울리는 이유가 바로 이것입니다. if (!is.na(x) && x > 10)처럼 쓰면 xNA일 때 x > 10 부분이 안전하게 건너뛰어집니다.

경험 법칙은 이렇습니다. **벡터와 데이터 필터링에는 &/|, if() 조건에는 &&/||**입니다. 그리고 R 4.3부터는 이것이 강하게 강제됩니다. &&||에 길이가 1보다 긴 벡터를 넘기면 오류입니다(예전 R 버전은 조용히 첫 원소만 사용했고, 그 때문에 진짜 버그가 수년간 숨어 있었습니다).

xor(a, b)가 이 묶음을 마무리합니다. 둘 중 정확히 하나만 TRUE일 때 TRUE입니다.

%in%: 포함 여부 검사

x %in% tablex의 각 원소에 대해 "이것이 table 어딘가에 나타나는가?"를 묻습니다. 실제 R 코드에서 가장 많이 쓰이는 연산자 중 하나입니다.

검사되는 쪽이 벡터 전체일 수 있기 때문에, %in%은 허용된 값 집합으로 행을 필터링하는 데 자연스러운 도구입니다.

또한 그 대안, 즉 |로 이어 붙인 ==의 연쇄보다 낫습니다.

허용 값이 다섯 개가 되면 == 연쇄는 반복의 벽이 되지만, %in% 버전은 벡터만 길어질 뿐입니다. 더 미묘한 두 번째 장점도 있습니다. %in%결코 NA를 돌려주지 않습니다.

NA == 1NA인 이유는 알 수 없는 값이 1과 같은지 R이 알 수 없기 때문입니다. 결측값에서 깊이 다루는 동작입니다. 그 NA는 도달하는 모든 if()를 오염시킵니다. %in%은 항상 TRUEFALSE로 답해 이 문제를 통째로 비켜 가며, 그래서 결측이 있을 수 있는 데이터의 조건에는 더 안전한 선택입니다.

우선순위 함정

두 가지 연산자 우선순위 함정이 "R이 고장 났다" 싶은 순간의 상당 부분을 차지합니다. 첫째, ^가 단항 마이너스보다 강하게 결합합니다.

둘째, 콜론이 이항 산술보다 강하게 결합합니다.

헷갈리면 괄호를 넣으세요. 비용이 들지 않고, 모든 독자(미래의 자신 포함)가 인터프리터와 같은 방식으로 읽게 됩니다.

$와 [ ]: 접근 연산자

$, [ ], [[ ]]도 끊임없이 보게 됩니다. 엄밀히 말해 이것들도 연산자이며, 계산이 아니라 구조체에서 값을 꺼내는 데 쓰입니다.

벡터, 리스트, 데이터 프레임 페이지에서 자세히 다룹니다. 여기서는 같은 연산자 가족의 일원임을 알아보는 것으로 충분합니다.

핵심 정리

  • %%는 나머지를, %/%는 정수 몫을 줍니다. x %% 2 == 0은 짝수인지 검사합니다.
  • 비교는 벡터화되어 있어 필터링에 쓸 수 있는 논리 벡터를 돌려줍니다.
  • &/|는 벡터를 원소 단위로 결합하고, &&/||if() 안의 단일 값을 위한 것이며 단축 평가를 합니다. R 4.3부터 긴 벡터에 &&를 쓰면 오류입니다.
  • x %in% table==의 연쇄를 대체하며 결코 NA를 돌려주지 않습니다.
  • -2^2-4이고 1:n - 1은 0에서 시작합니다. 헷갈리면 괄호를 치세요.

다음 순서는 이 연산자들을 if, else, ifelse() 안에서 활용하는 것, 즉 R의 조건문입니다.

자주 묻는 질문

R에서 %%는 무슨 일을 하나요?

%%는 나머지 연산자로, 나눗셈의 나머지를 돌려줍니다. 17 %% 52입니다. 짝이 되는 %/%는 정수 나눗셈으로 나머지 없는 몫을 돌려줍니다. 17 %/% 53입니다. %%의 고전적인 용도는 짝수 판별입니다. x %% 2 == 0처럼 씁니다.

R에서 &와 &&의 차이는 무엇인가요?

&는 벡터화되어 있습니다. 두 벡터를 원소 단위로 비교해 같은 길이의 벡터를 돌려줍니다. &&는 단일 값에만 동작하고, 단축 평가를 하며(첫 피연산자가 이미 결과를 결정하면 두 번째를 건너뜁니다), 정확히 하나의 TRUE 또는 FALSE를 돌려줍니다. 벡터를 필터링할 때는 &를, if() 조건 안에서는 &&를 쓰세요. R 4.3부터는 &&||에 길이가 1보다 긴 벡터를 넘기면 경고가 아니라 오류입니다.

R에서 %in%은 무슨 일을 하나요?

x %in% tablex의 각 원소가 table 어딘가에 나타나는지 검사해 원소마다 TRUE 또는 FALSE를 돌려줍니다. "mango" %in% basket|로 이어 붙인 == 비교의 연쇄를 대체하며, ==와 달리 결코 NA를 돌려주지 않습니다. 검사 대상 쪽에 결측값이 있어도 그냥 FALSE가 됩니다.

R에서 -2^2는 왜 -4를 돌려주나요?

^가 단항 마이너스보다 강하게 결합하기 때문에 R은 -2^2-(2^2)로 읽고, 그 결과는 -4입니다. 음수 2의 제곱을 의도했다면 (-2)^2라고 쓰세요. 결과는 4입니다. 콜론에도 비슷한 함정이 있습니다. 1:n - 11:(n - 1)이 아니라 (1:n) - 1을 뜻합니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기