패키지란 무엇인가
패키지는 R을 확장하는 함수, 문서, 때로는 데이터의 묶음입니다. 기본 R은 벡터, 모델, 그래프를 주고 패키지는 그 밖의 모든 것을 주는데, 그 "그 밖의 모든 것"이 어마어마합니다. CRAN(Comprehensive R Archive Network)은 약 2만 개의 패키지를 호스팅하며, 모든 패키지가 공개 전에 CRAN의 제출 검사를 통과합니다. 그 저장소가 R이 데이터 작업에서 경쟁력을 유지하는 주된 이유입니다. 어떤 분석이든 누군가 이미 패키지로 만들어 두었을 가능성이 큽니다.
CRAN만이 유일한 출처는 아닙니다. Bioconductor는 생물정보학 생태계를 호스팅하고, 개발 중인 많은 패키지는 GitHub에 있습니다(remotes::install_github()로 설치할 수 있습니다). 다만 입문자라면 CRAN을 기본으로 삼고, 나머지는 README가 시키는 순간 만나게 될 것으로 두어도 됩니다.
몇몇 패키지는 R 자체와 함께 제공되어(stats, utils, graphics 등) 자동으로 로드됩니다. mean()과 plot()이 그냥 동작하는 이유죠. 그 외의 모든 것은 아래의 두 단계 의식을 따릅니다.
install.packages()는 한 번, library()는 세션마다
입문자가 가장 많이 헷갈리는 부분이니 최대한 또렷하게 말하겠습니다. 패키지를 동작하게 만드는 일은 수명이 다른 두 가지 행동입니다.
install.packages("dplyr") # ONCE per machine: downloads from CRAN and installs
library(dplyr) # EVERY session: loads it so your code can use it
install.packages("dplyr")은 책을 사는 것과 같습니다. 한 번 하면 그 뒤로는 여러분의 책장(디스크)에 놓여 있습니다. 따옴표에 주의하세요. 이름을 문자열로 전달하는 것입니다.library(dplyr)은 책장에서 책을 꺼내는 것과 같습니다. 모든 R 세션 시작에서(실무적으로는 모든 스크립트 맨 위에서) 합니다. 여기서는 따옴표가 필요 없습니다.library()는 특별해서 이름 자체를 받아들입니다(일관성을 원한다면library("dplyr")도 동작합니다).
두 가지 실패 형태가 어느 단계를 건너뛰었는지 알려 줍니다. library()에서 나오는 Error: there is no package called 'dplyr'는 설치된 적이 없다는 뜻입니다. 스크립트 중간에 나오는 Error: could not find function "filter"(또는 "%>%")는 패키지가 설치되어 있지만 이번 세션에서 불러오지 않았다는 뜻입니다. 모든 library() 호출을 여기저기 흩뿌리지 않고 스크립트 맨 위에 두면 두 번째 실패가 1초 안에 드러나고, 그 목록이 스크립트의 의존성 목록 역할도 합니다. tidyverse 설치도 같습니다. install.packages("tidyverse")를 한 번 하고 세션마다 library(tidyverse)를 하면 dplyr, ggplot2 등 핵심 세트가 한 줄로 불러와집니다.
하지 말아야 할 일은 반복 실행하거나 공유하는 스크립트 안에 install.packages()를 남겨 두는 것입니다. 실행할 때마다 다시 내려받고, 그것을 실행하는 사람을 놀라게 할 수 있습니다. 설치는 콘솔에서 하는 행위이고 로드는 스크립트에서 하는 행위입니다.
require()와 pkg::fun()
require()는 library()의 동의어처럼 보이고, 그렇게 잘못 쓰는 일이 흔합니다. 차이는 패키지가 없을 때 벌어지는 일입니다. library()는 오류로 멈추고, require()는 경고를 출력하고 FALSE를 돌려주며 스크립트를 계속 진행시킵니다. 그러다 대개 스무 줄 뒤에서 정직한 "no package called" 대신 헷갈리는 "could not find function"으로 죽습니다. 의존성을 불러올 때는 library()를 쓰세요. 맨 위에서 크게 실패하는 것이 기능입니다. require()는 반환값이 요점이 되는 조건 검사에서만 제 값을 합니다.
if (!require(praise)) {
install.packages("praise")
library(praise)
}
패키지를 아예 불러오지 않고 쓰는 방법도 있습니다. :: 연산자는 함수를 전체 주소 package::function()으로 호출합니다. 패키지가 설치되어 있어야 하지만 세션에 아무것도 붙지 않습니다.
(stats는 어차피 자동 로드되므로 그냥 sd()도 동작하지만, 문법은 설치된 어떤 패키지에도 동일합니다.) ::는 두 곳에서 빛납니다. library() 한 줄이 과한 일회성 호출, 그리고 로드된 두 패키지가 같은 이름을 내보낼 때의 구분입니다. dplyr::filter()와 stats::filter()가 고전적인 충돌입니다.
패키지 최신 상태 유지하기
패키지는 R과 독립적으로 발전하므로 업데이트는 여러분의 몫입니다.
update.packages() # offers to update everything outdated
update.packages(ask = FALSE) # same, without prompting per package
명백하지 않은 규칙이 하나 있습니다. 패키지는 특정 major.minor R 버전에 맞춰 빌드됩니다. R 자체를 업그레이드하면(예: 4.3에서 4.4로. R 설치 참고) 기존 패키지 라이브러리가 일반적으로 이어지지 않으며, 해결책은 그저 새 버전에서 쓰는 패키지를 다시 설치하는 것입니다. install.packages() 10분이면 되는 일이지 재앙은 아닙니다. 다만 새로 설치한 R이 스크립트를 "no package called" 오류의 벽으로 맞이할 때 처음에는 누구나 놀랍니다.
무엇을 가지고 있는지 확인하기
"무엇이 어디에 설치되어 있는가"에 답하는 함수 세 가지입니다.
installed.packages()[, "Version"] # every installed package with its version
sessionInfo() # R version + what THIS session has loaded
.libPaths() # the folders where packages are installed
installed.packages()는 패키지마다 한 행씩인 행렬을 돌려주며, 보통 필요한 것은 Version 열입니다. sessionInfo()는 재현성 도구입니다. 그 출력을 버그 리포트에 붙여 넣으면 읽는 사람이 여러분의 R 버전, 운영체제, 로드된 모든 패키지의 정확한 버전을 알 수 있습니다. .libPaths()는 R이 찾는 라이브러리 폴더를 보여 줍니다. 이것이 존재한다는 사실을 알면 "그 패키지는 실제로 어디로 갔지?"라는 의문과 공용 컴퓨터에서 왜 관리자 권한이 필요할 때가 있는지가 풀립니다.
알아 둘 만한 패키지들
오늘 당장 필요하지는 않지만 끊임없이 만나게 될 것들입니다. 각각이 무엇을 위한 것인지 알면 다른 사람의 코드를 읽는 데 도움이 됩니다.
- dplyr - 데이터 조작 동사들.
filter,mutate,group_by,summarize. - ggplot2 - 표준 시각화 패키지. 온라인에서 보는 R 그래픽 대부분이 ggplot2입니다.
- tidyr - 넓은 형태와 긴 형태 사이의 데이터 재구성(
pivot_longer,pivot_wider). - readr / readxl - 각각 빠른 CSV 읽기와 Excel 파일 읽기.
- lubridate - 기대한 대로 동작하는 날짜.
- stringr - 일관성 있는 문자열 조작.
- data.table - 고성능 데이터 프레임 생태계의 대안. tidyverse와는 다른 방언이며 대용량 데이터에서 사랑받습니다.
- shiny - 전부 R로 작성하는 대화형 웹 앱.
앞의 여섯 개는 tidyverse의 핵심이며 install.packages("tidyverse")로 함께 도착합니다. 이들을 반드시 써야 할 의무는 없습니다. 기본 R로도 전부 할 수 있습니다. 다만 현대 R 코드 대부분이 사는 곳이 이 생태계입니다.
핵심 정리
- CRAN은 검증된 약 2만 개의 패키지를 호스팅하고, 나머지는 Bioconductor와 GitHub가 담당합니다.
install.packages("name")은 컴퓨터당 한 번(따옴표 필수),library(name)은 세션마다 한 번씩 스크립트 맨 위에서 합니다.library()는 크게 실패합니다. 좋은 일이죠.require()는FALSE를 돌려주며 검사 안에서만 유용합니다.pkg::fun()은 패키지를 붙이지 않고 함수 하나를 쓰며, 이름 충돌을 해결해 줍니다.update.packages()로 최신 상태를 유지하고, R 주요 버전 업그레이드 후에는 패키지를 다시 설치해야 합니다.sessionInfo()는 여러분의 코드가 무엇 위에서 돌았는지 남에게(또는 미래의 자신에게) 알려 주는 방법입니다.
다음 순서는 작업 디렉터리입니다. R이 파일을 어디에서 찾는지, 그리고 데이터 읽기가 실패할 때 왜 가장 먼저 확인해야 하는지 다룹니다.
자주 묻는 질문
R에서 패키지는 어떻게 설치하나요?
패키지 이름을 따옴표로 감싸 install.packages("name")을 실행하세요. 예: install.packages("dplyr"). R이 CRAN에서 내려받아 컴퓨터에 설치합니다. 컴퓨터당 한 번만 하면 되고, 이후에는 각 세션에서 library(dplyr)로 불러옵니다.
install.packages()와 library()의 차이는 무엇인가요?
install.packages("dplyr")은 패키지를 컴퓨터로 내려받습니다. 컴퓨터당 한 번입니다. library(dplyr)은 이미 설치된 패키지를 현재 세션으로 불러옵니다. 세션마다 한 번이며 보통 모든 스크립트 맨 위에 둡니다. 설치만 하고 불러오지 않으면 쓸 수 있는 것이 없고, 설치 없이 불러오면 "there is no package called 'dplyr'" 오류가 납니다.
R에서 library()와 require()의 차이는 무엇인가요?
둘 다 패키지를 불러오지만 실패했을 때 library()는 오류로 멈추고 require()는 경고만 낸 뒤 FALSE를 돌려줍니다. 그래서 크고 빠르게 실패해야 하는 스크립트에는 library()가 알맞고, require()는 if (!require(pkg)) install.packages(pkg) 같은 조건 검사 안에서만 유용합니다.