더북(TheBook)

이를 좀 더 직접적으로 알아보기 위해 리스트를 데이터 프레임으로 변환하는 다음 예를 살펴보자.

> x <- lapply(1:10000, function(x) {
+   data.frame(val = x,
+               val2 = 2 * x,
+               val3 = 2 / x,
+               val4 = 4 * x,
+               val5 = 4 / x)
+ })

> system.time(y <- do.call(rbind, x))
  user system elapsed
  2.59   0.00    2.60

위 결과에서 보다시피 do.call(rbind, 데이터 프레임)9 을 사용해 리스트 안에 저장된 데이터 프레임을 하나로 합치는 데 2.60초가 소요되었다. 2초 정도는 긴 시간이 아니지만 컬럼 수가 많아지거나 데이터가 많아지면 이 시간은 급격히 증가하며 심지어 데이터 처리의 대부분의 시간이 여기에만 소요되기도 한다.

이러한 문제를 해결해주는 data.table 패키지의 함수가 rbindlist( )다. 다음 표에 rbindlist( )에 대해 정리했다.

표 5-14 리스트를 데이터 테이블로 변환

data.table::rbindlist : 리스트를 데이터 테이블로 빠르게 변환한다.

data.table::rbindlist(
  l  # 데이터 테이블 또는 데이터 프레임의 리스트
)

반환 값은 데이터 테이블이다.

rbindlist는 인자로 데이터 테이블 또는 데이터 프레임의 리스트를 받아 하나의 데이터 테이블로 합쳐준다. 따라서 llply( )를 사용해 일단 데이터 테이블의 리스트로 결과를 만든 다음 이를 다시 하나의 데이터 테이블로 병합한다면 ldply( )를 사용하는 것보다 속도가 매우 빠를 것이다. 이를 다음 예에서 살펴본다.

> system.time(x <- ldply(1:10000, function(x) {
+   data.frame(val = x,
+               val2 = 2 * x,
+               val3 = 2 / x,
+               val4 = 4 * x,
+               val5 = 4 / x)
+ }))
  user system elapsed
  6.85   0.00    7.05

> system.time(x <- llply(1:10000, function(x) {
+   data.frame(val = x,
+               val2 = 2 * x,
+               val3 = 2 / x,
+               val4 = 4 * x,
+               val5 = 4 / x)
+ }))
  user system elapsed
  4.95   0.00    4.96

> system.time(x <- rbindlist(x))
  user system elapsed
     0      0       0

보다시피 데이터 프레임을 대신 만들어주는 ldply( )는 7.05초가 소요된 반면, llply( )를 사용해 데이터 테이블의 리스트를 먼저 만든 다음 이를 다시 rbindlist( )로 합쳐 최종 데이터 테이블을 만드는 코드는 총 4.96초(= 4.96 + 0)가 소요되었다.


9 do.call(rbind, 데이터 프레임)을 사용한 변환에 대해서는 ‘4.4.2 lapply( )’ 절에서 설명한 바 있다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.