R 의 가장 대표적인 데이터 자료 구조 중의 하나를 꼽으라고 하면 행(row)과 열(column)로 구성된 2차원 배열 형태의 테이블인 Data Frame 일 것입니다.
그리고 Data Frame 자료 구조를 조작, 관리, 전처리 할 수 있는 패키지로는 Base R과 dplyr 패키지가 많이 사용이 되는데요, 이번 포스팅에서는 Data Frame의 확장 데이터 구조인 data.table 데이터 구조와 이를 조작, 관리, 처리하는데 사용하는 data.table 패키지에 대해서 소개하려고 합니다.
(1) R data.table은 무엇인가? (What is R data.table?)
(2) 왜 R data.table 인가? (Why R data.table?)
(3) R data.table 설치하기 (How to install R data.table)
(4) R data.table 참고할 수 있는 사이트 (Reference sites of R data.table)
(5) R data.table 구문 소개 포스팅 링크
(1) R data.table 은 무엇인가? (What is R data.table?) |
R data.table 은 (a) 행과 열로 구성된 2차원의 테이블 형태를 가지는 'data.frame'의 확장 데이터 구조(data.table: Extension of 'data.frame')이면서, (b) data.table을 생성, 조작, 처리, 집계할 수 있는 패키지(package) 입니다.
아래에 data.table 패키지를 사용하여 문자열을 가진 'g' 변수와 숫자형 데이터를 가진 'x' 변수에 대해 10개의 관측치를 가지고 있는 간단한 data.table 자료구조를 하나 만들어 봤는데요, str() 로 자료 구조에 대해 확인해보면 'Classes 'data.table' and 'data.frame': 10 obs. of 2 variables:' 라는 설명이 나옵니다. 'data.table'이면서 'data.frame'이라고 나옵니다.
View(data_dt) 로 자료를 확인해봐도 기존에 우리가 알고 있던 data.frame 과 data.table 이 구조가 같다는 것을 눈으로 확인할 수 있습니다.
library(data.table)
> data <- data.table(g = c(rep('a', 5), rep('b', 5)), x = 1:10) > str(data) Classes 'data.table' and 'data.frame': 10 obs. of 2 variables: $ g: Factor w/ 2 levels "a","b": 1 1 1 1 1 2 2 2 2 2 $ x: int 1 2 3 4 5 6 7 8 9 10 - attr(*, ".internal.selfref")=<externalptr>
> View(data)
|
R CRAN에는 data.table 패키지에 대해서,
- 대용량 데이터(예: 100GB)에 대한 빠른 집계
(Fast aggregation of large data (e.g. 100GB in RAM)) - 빠른 정렬된 조인
(Fast ordered joins) - 복사를 사용하지 않고 그룹별로 칼럼에 대한 빠른 합치기/수정/삭제
(Fast add/modify/delete of columns by group using no copies at all) - 사용자 친화적이고 빠른 문자 구분 값의 읽기와 쓰기
(Friendly and fast character-separated-value read/write) - 빠른 개발을 위한 자연스럽고 유연한 구문을 제공
(Offers a natural and flexible syntax, for faster development.)
한다고 소개하고 있습니다.
(2) 왜 R data.table 인가? (Why R data.table?) |
data.table 의 GitHub 페이지에서 '왜 data.table 인가 (Why data.table?)' 에 대해서 6가지 이유를 말하고 있습니다. (위의 data.table 소개 내용과 유사합니다만, 이유 항목별로 순서가 조금 다르고, 항목도 조금 다르긴 합니다.)
- 빠르게 쓰고 읽을 수 있는 간결한 구문 (concise syntax: fast to type, fast to read)
- 빠른 속도 (fast speed)
- 효율적인 메모리 사용 (memory efficient)
- 세심한 API 라이프사이클 관리 (careful API lifecycle management)
- 커뮤니티 (community)
- 풍부한 기능 (feature rich)
첫번째 data.frame 이 좋은 이유로 "빠르게 쓰고 읽을 수 있는 간결한 구문 (concise systax: fast to type, fast to read)"을 들었는데요, 이에 대해서는 Base R, dplyr, data.table 의 세 개 패키지별로 위의 data 에 대해서 그룹 'g' 별로 변수 'x'의 평균(mean) 을 구해보는 구문을 비교해보면 이해하기 쉬울 것 같습니다.
자, 아래 구문을 보면 어떠신가요? 제 눈에는 data.table 이 제일 간결해보이네요!
Base R |
dplyr |
data.table |
tapply( data$x, data$y, mean) |
data %>% group_by(g) %>% summarise(mean(x)) |
data[, mean(x), by = 'g'] |
두번째 data.frame 의 장점으로 "빠른 속도 (fast speed)" 를 들었는데요, H2Oai 에서 R data.table과 R dplyr 뿐만 아니라 Python pandas, Spark, Julia 등 다른 Database-like 언어의 패키지까지 벤치마킹 테스트를 해놓은 자료가 있어서 아래에 소개합니다.
질문은 5GB 데이터셋에 대해 'id1' 그룹별로 'v1' 칼럼에 대해 합(sum)을 구하라는 집계를 수행하는 것인데요, R data.table 이 12초, R dplyr은 156초, Python pandas는 100초가 걸렸네요. data.table이 겁나게 빠른 것을 알 수 있습니다.
* 출처: https://h2oai.github.io/db-benchmark/
data.table이 이처럼 빠른데는 여러가지 이유가 있는데요, 그중에서도 핵심은 data.table은 테이블을 수정할 때 레퍼런스(Reference)를 이용할 수 있으므로, 새로운 객체를 다시 만들 필요없이, 원래의 객체를 바로 수정할 수 있다는 점입니다.
세번째 data.table의 장점으로 "효율적인 메모리 사용 (memory efficient)"을 꼽았는데요, 역시 H2O ai 에서 위와 동일 질문에 대해 이번에는 '50GB' 의 대용량 데이터에 대해서 수행해보았습니다.
특기할 점은 R data.table은 122초, Spark은 374초가 걸려서 에러없이 수행이 된 반면, R dplyr, Python pandas는 "Out of Memory"가 났다는 점입니다.
* 출처: https://h2oai.github.io/db-benchmark/
네번째로 data.table의 장점으로 "세심한 API 라이프사이클 관리(careful API lifecycle management)"를 들고 있습니다.
data.table 패키지는 Base R에만 의존성(dependency)을 가지고 있습니다. 폐쇄망 환경에서 R 패키지 설치하거나 버전 업그레이드 할 때 의존성 확인하면서 하나 하나 설치하려면 보통 일이 아닌데요, data.table 패키지는 Base R에만 의존성이 있으므로 패키지 설치 및 관리가 무척 수월하겠네요.
다섯째 data.table의 장점으로 "커뮤니티 (Community)"를 들고 있습니다. data.table 패키지는 Matt Dowle 외 100여명의 contributor 가 제작 및 관리하고 있는 패키지로서, 소스코드는 https://github.com/Rdatatable/data.table 에서 확인하거나 소스 코드에 기여할 수 있습니다.
여섯째 data.table의 장점으로 "풍부한 기능 (feature rich)"을 들고 있는데요, 앞으로 하나씩 같이 알아가보시지요.
이렇게 data.table 은 굉장히 매력적인 장점을 가지고 있는데요, 한가지 단점이 있다면 기존에 익숙한 Base R, dplyr 을 놔두고 새로 data.table 패키지의 구문을 배워야 한다는 점입니다.
Base R 쓰다가 dplyr 을 처음 봤을 때의 당혹스러움만큼이나 data.table 구문을 처음 보면 아마도 당황스러울 것입니다. '어, 이게 R 맞나? 내가 지금 무슨 프로그래밍 언어를 보고 있는 거지?' 하고 말이지요.
그래도 다행이라면 구문이 간결해서 배우기 (상대적으로) 쉽다는 점이겠습니다. R data.table은 충분히 시간과 노력을 투자해서 배워볼 만한 값어치가 있다고 생각합니다.
(3) R data.table 설치하기 (How to install R data.table) |
패키지 설치 및 로딩은 다른 패키지와 동일합니다.
# install data.table package install.packages("data.table")
# latest development version: data.table::update.dev.pkg()
# loading data.table package library(data.table)
|
(4) R data.table 참고할 수 있는 사이트 (Reference sites of R data.table) |
- data.table 패키지 소소코드: https://github.com/Rdatatable/data.table
- R package 다운로드, 매뉴얼, 튜토리얼: https://cran.r-project.org/web/packages/data.table/
많은 도움이 되었기를 바랍니다.
다음번 포스팅에서는 R data.table 의 데이터셋을 만드는 3가지 방법을 소개하겠습니다.
(5) R data.table 구문 소개 포스팅 링크 |
-
데이터를 읽어와서 data.table 만들기, data.frame을 data.table로 변환하기
: https://rfriend.tistory.com/563 -
data.table의 기본 구문 DT[i, j, by][order] 과 Base R, dplyr, SQL 구문 비교
-
data.table의 구문 DT[i, j, by]에서 행 subset과 열 select하고 계산하기
-
data.table의 by 구문으로 그룹별 집계하기 (Aggregation by Group)
-
여러개의 변수를 처리하는 data.table의 특수 부호 .SD, .SDcols
-
data.table의 키와 빠른 이진 탐색 기반의 부분집합 선택
-
data.table에서 Key를 칼럼 j와 그룹 by와 함께 사용하기
-
data.table에서 Key 값의 매칭되는 모든 행(mult="all"), 첫번째 행(mult="first"), 마지막 행(mult="last"), 값이 존재하는 행만(nomatch=NULL) 가져오기
: https://rfriend.tistory.com/571 -
data.table을 참조하여 := 연산자로 data.table의 칼럼 추가, 갱신, 삭제하기
(add/updata/delete column in R data.table)
: https://rfriend.tistory.com/573 -
data.table을 참조하여 := 연산자로 얕은 복사 시의 부작용, copy() 함수로 깊은 복사하는 방법
: https://rfriend.tistory.com/574 -
data.table의 효율적인 데이터 재구조화 : melt(), dcast()
: https://rfriend.tistory.com/575
-
패턴이 있는 여러개의 칼럼을 동시에 길게 녹이고(melt), 옆으로 넓게 주조(cast) 하기
: rfriend.tistory.com/576 -
그룹별 관측치 개수 별로 Data.Table을 구분해서 생성하기
: rfriend.tistory.com/607
-
.SDcols 로 일부 칼럼 가져오기 (Column subsetting using .SDcols)
: rfriend.tistory.com/608
-
회귀 모델의 오른쪽 부분(model's right-hand side)의 변수 조합을 일괄 다루기
: rfriend.tistory.com/609
-
R data.table의 조건이 있는 상태에서 Key를 기준으로 데이터셋 합치기(Conditional Joins)
: rfriend.tistory.com/610
-
R data.table의 .SD[], by 를 사용해서 그룹별로 부분집합 가져오기 (Group Subsetting)
-
R data.table 그룹별 선형회귀모형 적합하고 회귀계수 구하기 (Grouped Regression)
: rfriend.tistory.com/614
-
R data.table 이차 인덱스(Secondary indices)를 활용한 빠른 탐색 기반 subsetting
: rfriend.tistory.com/615
-
R data.table의 자동 인덱싱 (Auto indexing)
: rfriend.tistory.com/616
이번 포스팅이 도움이 되었다면 아래의 '공감~
'를 꾹 눌러주세요.
행복한 데이터 과학자 되세요. :-)