표현식과 자동 출력
R은 표현식 언어입니다. 여러분이 쓰는 거의 모든 줄이 값을 만들어 냅니다. 콘솔에서는 표현식만 단독으로 입력해도 평가되어 값이 자동으로 출력됩니다. print()가 필요 없습니다.
각 결과 앞에는 [1]이 붙습니다. 이것은 표시된 첫 값의 위치를 R이 알려 주는 것으로, R이 벡터 단위로 생각한다는 첫 힌트입니다(자세한 내용은 아래에서 다룹니다). 자동 출력에는 첫날부터 알아 둘 만한 함정이 있습니다. 최상위 수준의 단독 표현식에만 적용된다는 점입니다. 같은 표현식이라도 함수 본문이나 for 반복문 안에서는 아무것도 출력하지 않습니다. 그래서 스크립트에서는 반드시 보여야 할 출력에 cat()이나 print()를 명시적으로 씁니다.
할당: 화살표
R의 할당 연산자는 <-로, 값을 받는 이름 쪽을 가리키는 화살표입니다.
radius <- 5는 "radius가 5를 받는다"로 읽습니다. 물론 =도 최상위 할당에서 동작하고, 입문자들은 왜 한 글자면 될 것을 두 글자로 쓰냐고 묻습니다. 답은 힘이 실린 관례입니다. 모든 주요 스타일 가이드, 기본 R 문서, 그리고 여러분이 앞으로 읽게 될 사실상 모든 R 코드가 할당에 <-를 쓰고 =는 딱 한 가지 용도, 즉 함수 호출 안에서 인자 이름을 지정하는 데(다음 절) 남겨 둡니다. 이 관례를 따르면 두 작업이 시각적으로 구분됩니다. RStudio에서는 Alt+-(macOS에서는 Option+-)를 누르면 화살표가 입력됩니다.
할당은 자동 출력되지 않는다는 점에 주의하세요. area <- 78.5는 값을 조용히 저장합니다. 그래서 위 코드에는 print()가 필요했습니다.
대소문자 구분
R은 여러분이 만든 이름과 언어가 제공하는 이름 모두에서 대소문자를 엄격하게 구분합니다.
서로 다른 두 변수입니다. 마찬가지로 mean()은 함수이지만 Mean()은 존재하지 않습니다. R이 object 'x' not found나 could not find function으로 인사한다면 무엇보다 먼저 대소문자를 확인하세요. 입문자에게 가장 흔한 오류입니다.
함수 호출과 이름 있는 인자
함수는 괄호로 호출하고 인자는 쉼표로 구분합니다. 인자는 위치로, 이름으로, 또는 둘을 섞어서 전달할 수 있습니다.
seq() 호출은 R의 이름 있는 인자 문법을 보여 줍니다. 그리고 여기서 =가 제 몫을 합니다. 호출 안에서 name = value는 인자에 이름표를 붙입니다. 이름 있는 인자를 쓰면 매개변수 순서를 외울 필요가 없고, 호출 자체가 설명이 됩니다. seq(0, 100, 25)도 똑같이 동작하지만 읽는 사람에게 알려 주는 정보는 적습니다. 실무 관례는 이렇습니다. 첫 인자(보통 데이터)는 위치로 전달하고 나머지는 이름을 붙이세요.
어떤 함수든 도움말은 키 하나면 됩니다. 콘솔에서 ?seq를 입력하면 문서가 열립니다.
모든 것은 벡터입니다
R이 다른 언어와 다르게 느껴지게 만드는 개념입니다. R에는 홀로 존재하는 단일 숫자가 없습니다. 5조차 길이 1의 벡터이며, 연산은 벡터 전체에 원소 단위로 적용됩니다.
어디에도 반복문이 없지만 모든 원소가 변환되었습니다. 대부분의 언어에서는 for 반복문 세 번이지만, R에서는 그냥 산술입니다. 이것이 벡터화이며 모든 것을 규정합니다. 비교 연산자, 문자열 함수, 수학 함수 모두 이런 식으로 동작합니다. 관용적인 R 코드에 예상보다 반복문이 훨씬 적은 이유이기도 합니다. 전체 이야기는 벡터에서 다룹니다.
중괄호와 블록
if, 반복문, 함수의 여러 줄짜리 본문은 중괄호 {}로 묶습니다.
두 가지를 눈여겨보세요. 조건은 괄호 안에 들어가고, 표기는 if:나 if ... then이 아니라 그냥 if입니다. 또한 Python과 달리 R에서는 들여쓰기에 아무 의미가 없습니다. 블록을 정의하는 것은 중괄호이고, 들여쓰기는 사람을 위한 것입니다. 한 줄짜리에서 중괄호를 생략하는 것은 문법상 허용되지만 편집 중 버그를 낳는 고전적 원인입니다. 그냥 항상 쓰세요.
공백과 세미콜론
R은 여분의 공백을 무시하고, 줄바꿈이 문장을 끝냅니다. 세미콜론은 필요 없습니다.
세 번째 줄이 +로 끝나기 때문에 R은 표현식이 아직 끝나지 않았음을 알고, 줄을 나눠 써도 동작합니다. 긴 줄을 나눌 때 기억할 규칙은 하나입니다. 연산자나 쉼표 뒤에서 끊으세요. 앞에서 끊으면 R이 첫 줄을 완성된 문장으로 취급합니다. 세미콜론은 두 문장을 한 줄에 욱여넣을 때만 존재합니다(a <- 1; b <- 2). 허용되지만 권장되지 않고, 쉽게 피할 수 있습니다.
스타일: R 코드를 쓰는 방식
문법을 넘어서, R에는 강한 커뮤니티 관례가 있습니다(생태계 대부분이 따르는 tidyverse 스타일 가이드로 성문화되어 있습니다).
- 할당에는
<-,=는 호출 안의 인자에만 사용합니다. snake_case이름:monthlyRevenue나monthly.revenue가 아니라monthly_revenue. 점은 R 이름에서 문법상 허용되지만 피하는 편이 좋습니다. R 내부가 쓰는 명명 패턴과 충돌하기 때문입니다.- 연산자 주위와 쉼표 뒤에 공백을 둡니다(
x<-a*2가 아니라x <- a * 2). - 중괄호 안은 공백 네 칸으로 들여쓰기 합니다(두 칸을 쓰는 팀도 있습니다. 하나를 골라 일관되게 쓰세요).
- 한 줄에 한 문장.
이 중 어느 것도 인터프리터가 강제하지 않습니다. 그러나 여러분의 코드를 읽는 모든 사람이 강제합니다. 이름 짓기에 대한 이야기는 변수에서 이어집니다.
핵심 정리
- R은 표현식을 평가하고 콘솔에서 단독 표현식을 자동 출력하지만, 함수나 반복문 안에서는 그렇지 않습니다.
- 할당은
<-("받는다")로 하고,=는 함수 호출에서 인자 이름을 붙일 때만 씁니다. - R은 대소문자를 완전히 구분합니다. 초반의 "not found" 오류 대부분은 대소문자 오타 때문입니다.
- 모든 것이 벡터이며 연산은 원소 단위로 적용됩니다.
c(1, 2, 3) * 2는 반복문 없이2 4 6입니다. - 중괄호가 블록을 정의하고 줄바꿈이 문장을 끝내며,
snake_case와 띄어쓰기 관례를 지키면 코드가 다른 사람들의 코드처럼 읽힙니다.
다음 순서는 주석입니다. R 코드에 설명을 다는 방법과, R에 블록 주석 문법이 없다는 점에 어떻게 대응할지 다룹니다.
자주 묻는 질문
R에서 <-는 무슨 뜻인가요?
<-는 R의 할당 연산자입니다. x <- 5는 값 5를 x라는 이름에 저장합니다. "받는다"로 읽으면 됩니다. =도 최상위 수준에서는 할당을 하지만, 모든 주요 스타일 가이드가 강제하는 커뮤니티 관례는 할당에는 <-를 쓰고 =는 함수 호출 안에서 인자 이름을 지정할 때만 쓰는 것입니다.
R은 대소문자를 구분하나요?
네, 완전히 구분합니다. total, Total, TOTAL은 서로 다른 세 개의 이름이며, mean(x) 대신 Mean(x)을 호출하면 경고가 아니라 오류가 납니다. 'could not find function'이나 'object not found' 오류는 대개 대소문자 오타 때문입니다.
R에서 세미콜론이 필요한가요?
아니요. 줄바꿈이 문장을 끝냅니다. 세미콜론은 두 문장을 한 줄에 밀어 넣을 때만 필요한데(a <- 1; b <- 2), 스타일 가이드는 어차피 권장하지 않습니다. 한 줄에 한 문장씩 쓰면 세미콜론은 다시 생각할 필요가 없습니다.
R이 벡터화되어 있다는 것은 무슨 뜻인가요?
R의 기본 연산은 벡터 전체에 한 번에 적용됩니다. c(1, 2, 3) * 2는 2 4 6을 돌려주는데, 곱셈이 반복문 없이 모든 원소에 적용된 것입니다. 다른 언어라면 for 반복문이 되었을 코드 대부분이 R에서는 표현식 하나입니다.