R에서 변수 만들기
R에서 변수는 값에 붙인 이름입니다. 할당 화살표 <-로 만들며, 이름은 화살표 앞에, 값은 뒤에 옵니다.
변수 세 개, 서로 다른 종류의 값 세 개, 그리고 어디에도 타입 선언이 없습니다. R은 값 자체에서 타입을 추론합니다(자세한 내용은 데이터 타입에서 다룹니다). 변수가 만들어지면 값이 쓰일 수 있는 곳 어디에서나 사용할 수 있습니다.
재할당도 같은 방식으로 동작합니다. 변수는 다시 할당하는 순간 새로운 값으로, 심지어 새로운 타입으로도 아무 불평 없이 바뀝니다.
R은 문자열이 숫자가 되는 것에 대해 아무 말도 하지 않았습니다. 이 유연함은 편리하지만, 스크립트 중간에 변수의 의미가 바뀐다면 그건 대개 새 이름을 골라야 한다는 신호입니다.
R이 = 대신 <-를 쓰는 이유
모두가 묻는 질문이 있습니다. age = 30도 동작하는데, 왜 모든 R 책과 스타일 가이드와 패키지가 화살표를 쓸까요?
R에서 =는 나타나는 위치에 따라 서로 다른 두 가지이기 때문입니다. 최상위 수준에서는 할당을 합니다. 함수 호출 안에서는 이름으로 인자를 맞추며, 변수를 만들지 않습니다.
만약 mean(values, na.rm <- TRUE)처럼 썼다면 na.rm이라는 전역 변수를 실수로 만들고 TRUE를 위치 인자로 넘기게 됩니다. 문법상 허용되지만 잘못됐고, 발견하기도 어렵습니다. 이를 읽기 쉽게 유지하는 관례는 단순합니다.
<-는 언제나 할당을 의미합니다.=는 함수 호출 안에서 언제나 "이 인자가 이 값을 받는다"를 의미합니다.
이 구분을 따르면 여러분이 읽는 R 코드의 모든 줄이 무언가가 만들어지는 중인지 전달되는 중인지 한눈에 알려 줍니다. R 세계에서 가장 보편적인 스타일 규칙이며, RStudio는 <-에 전용 단축키(Alt+-)까지 제공합니다.
잘 쓰이지 않는 친척들: ->, =, assign()
R에는 할당 방법이 두 가지 더 있습니다. 직접 쓸 일은 드물어도 알아보는 것은 가치가 있습니다.
역방향 화살표 ->는 반대 방향으로 할당합니다. 값이 먼저, 이름이 나중입니다.
긴 파이프라인 끝에서("이걸 다 계산한 다음 저장") 가끔 보이지만, 대부분의 스타일 가이드는 피하라고 말합니다. 읽는 사람은 정의되는 이름을 찾으려고 줄의 시작을 훑기 때문입니다.
assign()은 문자열로부터 변수를 만듭니다. 즉, 이름을 실행 시점에 구성할 수 있다는 뜻입니다.
영리해 보이지만 거의 항상 잘못된 도구입니다. 번호가 붙은 변수 묶음은 사실 위장한 벡터나 리스트입니다. 이름을 정말로 계산해야만 하는 경우에만 assign()을 쓰세요. 짝이 되는 get("score")는 문자열 이름으로 변수를 읽습니다.
이름 규칙
R이 받아들이는 이름의 조건입니다.
- 문자, 숫자, 점(
.), 밑줄(_)을 포함합니다. - 문자로 시작하거나, 숫자가 뒤따르지 않는 점으로 시작합니다.
- 예약어(
if,for,TRUE,NULL,function등 몇 가지)가 아닙니다.
그래서 다음은 모두 유효합니다.
그리고 다음은 유효하지 않습니다.
2nd_user- 숫자로 시작할 수 없습니다._temp- (Python과 달리) 밑줄로 시작할 수도 없습니다.user-name- 하이픈은 뺄셈이지 이름에 쓰는 문자가 아닙니다.TRUE- 예약어입니다.
이름은 대소문자를 구분합니다. total, Total, TOTAL은 서로 무관한 세 변수이며, 오타로 새 변수를 만들어도 R은 경고하지 않습니다.
목록 보기와 제거하기: ls()와 rm()
여러분이 만든 모든 변수는 작업 공간(전역 환경)에 놓입니다. ls()는 거기 있는 것들을 나열하고 rm()은 제거합니다.
알아 둘 만한 두 가지가 있습니다. 첫째, rm(list = ls())는 작업 공간 전체를 비웁니다. 탐색적 세션의 맨 위에서는 편리하지만 그 밖의 곳에서는 파괴적입니다. 둘째, 점으로 시작하는 이름(.cache 같은)은 ls(all.names = TRUE)를 호출하지 않는 한 ls()에서 보이지 않습니다. 유닉스의 숨김 파일과 같은 관례입니다.
명명 관례: snake_case를 쓰세요
엄격한 규칙 너머로, 현대 R 커뮤니티(그리고 tidyverse 스타일 가이드)는 다음 관례에 정착했습니다.
- 변수와 함수에는
lower_snake_case:retry_count,fit_model. - 이름 속 점은 유효하지만 낡았습니다: 기본 R에는
my.data같은data.frame시대의 이름이 가득하지만, 점은 R의 S3 메서드 체계에서도 의미를 갖기 때문에(print.data.frame은 "데이터 프레임을 위한 print 메서드") 새 코드에서는 피합니다. - 헝가리안 접두사도, camelCase도 쓰지 않습니다. 오래된 패키지에서는
camelCase를 보게 되지만, 생태계가 정착한 곳은 snake_case입니다. - R에는 진짜 상수가 없습니다. 관례는 상수로 삼을 값의 이름을 대문자로 쓰고(
MAX_RETRIES <- 5) 그냥 재할당하지 않는 것입니다.
설명적인 이름을 고르고 일관되게 유지하세요. avg_score는 as보다 네 타를 더 치게 하지만, 앞으로의 모든 독자가 스크립트 위쪽으로 되돌아가는 수고를 덜어 줍니다.
핵심 정리
name <- value는 변수를 만듭니다. 커뮤니티는=를 함수 인자용으로 남겨 둡니다.->와assign()도 존재합니다. 직접 쓰는 것보다 읽게 되는 일이 더 많을 것입니다.- 이름에는 문자, 숫자, 점, 밑줄을 쓸 수 있고, 숫자나 밑줄로 시작할 수 없으며, 대소문자를 구분합니다.
ls()는 작업 공간을 보여 주고rm()은 정리합니다.snake_case로 쓰면 여러분의 코드가 오늘날 모두가 쓰는 R처럼 보일 것입니다.
다음 순서는 그 변수들이 실제로 담는 값의 종류입니다. numeric, integer, character, logical을 다룹니다.
자주 묻는 질문
R에서 변수는 어떻게 만드나요?
이름, 할당 화살표 <-, 값을 차례로 씁니다. 예: age <- 30. R은 값을 보고 타입을 알아내므로 선언 단계가 없습니다. 최상위 수준에서는 age = 30도 동작하지만, 커뮤니티 관례는 <-입니다.
R에서 <-와 =의 차이는 무엇인가요?
스크립트 최상위 수준에서는 같은 일을 합니다. 함수 호출 안에서는 다릅니다. mean(x, na.rm = TRUE)에서 =는 변수를 만드는 것이 아니라 이름으로 인자를 맞추는 역할입니다. =가 맥락에 따라 두 역할을 하기 때문에, R 스타일 가이드는 <-를 할당에, =를 인자에 배정합니다.
R에서 변수를 어떻게 삭제하나요?
rm(x)는 작업 공간에서 변수 x를 제거합니다. rm(list = ls())는 모든 것을 제거하는데, 깨끗하게 시작할 때 유용하지만 분석 도중에는 위험합니다. ls()는 현재 존재하는 것들을 나열합니다.
R 변수 이름에 점을 넣을 수 있나요?
네. my.data는 완전히 유효한 이름이며, 예전 R 코드는 점을 곳곳에 사용합니다. 다만 현대적인 스타일은 밑줄(my_data)을 선호합니다. 점은 R의 S3 메서드 체계에서도 의미를 갖기 때문에 점이 들어간 이름은 읽을 때 모호해지기 때문입니다.