나는 문서화를 진행 data.table
중이며 여기 SO에 대한 일부 대화에서 rbindlist
보다 나은 것으로 나타났습니다 rbind
.
나는 왜 왜 어떤 시나리오 가 rbindlist
더 뛰어나고 rbind
어떤 시나리오가 rbindlist
실제로 뛰어 rbind
납니까?
메모리 활용 측면에서 이점이 있습니까?
답변
rbindlist
의 최적화 된 버전으로 do.call(rbind, list(...))
, 사용시 속도가 느린 것으로 알려져 있습니다.rbind.data.frame
실제로 어디에서 뛰어 납니까
rbindlist
빛나는 곳을 보여주는 몇 가지 질문
do.call 및 ldply를 사용하여 긴 데이터 프레임 목록 (~ 1 백만)을 단일 데이터 프레임으로 변환하는 데 문제가 있습니다.
여기에는 얼마나 빠른지 보여주는 벤치 마크가 있습니다.
rbind.data.frame이 느린 이유
rbind.data.frame
많은 검사를 수행하며 이름으로 일치합니다. (즉, rbind.data.frame은 열의 순서가 다르고 이름별로 일치한다는 사실을 설명하고) rbindlist
이러한 종류의 검사를 수행하지 않으며 위치별로 조인합니다.
예 :
do.call(rbind, list(data.frame(a = 1:2, b = 2:3), data.frame(b = 1:2, a = 2:3)))
## a b
## 1 1 2
## 2 2 3
## 3 2 1
## 4 3 2
rbindlist(list(data.frame(a = 1:5, b = 2:6), data.frame(b = 1:5, a = 2:6)))
## a b
## 1: 1 2
## 2: 2 3
## 3: 1 2
## 4: 2 3
rbindlist의 다른 제한 사항
그것은 하는 데 사용 처리하는 투쟁 factors
으로 인해 수정 된 이후이 버그로 :
rbindlist 두 개의 data.tables 중 하나에는 요인이 있고 다른 하나에는 열에 대한 문자 유형이 있습니다 ( 버그 # 2650 )
중복 된 열 이름에 문제가 있습니다
참조
경고 메시지 : rbindlist에 (allargs) : data.table 가능한 버그 : 강압에 의해 도입의 NA? ( 버그 # 2384 )
rbind.data.frame 행 이름이 실망 스러울 수 있습니다
rbindlist
lists
data.frames
및 을 처리 할 수 data.tables
있으며 행 이름없이 data.table을 반환합니다.
당신은 do.call(rbind, list(...))
참조를 사용하여 행 이름의 뭉치에 들어갈 수 있습니다
do.call 내부에서 rbind를 사용할 때 행 이름을 바꾸는 것을 피하는 방법은 무엇입니까?
메모리 효율
메모리 측면에서 rbindlist
구현 C
되므로 메모리 효율적이므로 setattr
참조로 속성을 설정 하는 데 사용 됩니다.
rbind.data.frame
의 구현 R
, 그것은 할당을 많이하고, 사용하지 않습니다 attr<-
(그리고 class<-
및 rownames<-
(내부적으로) 생성 data.frame의 복사본을 만들 것이다 모두를.
답변
함으로써 v1.9.2
,rbindlist
같은 많은 기능을 구현하면서 상당히 발전했습니다.
SEXPTYPE
바인딩하는 동안 가장 높은 열 선택 -FR # 2456v1.9.2
닫기 에서 구현 및 버그 # 4981을 .- 취급
factor
먼저 구현 – 제대로 열v1.8.10
닫는 버그 # 2650 바인딩과 확장 주문 신중에 요소를v1.9.2
폐쇄 아니라를 FR # 4856 및 버그 # 5019을 .
또한 v1.9.2
, rbind.data.table
또한 얻은 fill
R. 구현 누락 된 열을 작성하여 바인드 할 수 있습니다 인수를,
지금에 v1.9.3
기존 기능에 대해 더 많은 개선 사항이 있습니다.
rbindlist
논증을 얻다use.names
기본적으로FALSE
이전 버전과의 호환성을위한 .rbindlist
또한 논쟁을 얻는다fill
기본적으로FALSE
이전 버전과의 호환성도 있습니다.- 이러한 기능은 모두 C로 구현되며 기능을 추가하는 동안 속도가 저하되지 않도록주의해서 작성되었습니다.
- 때문에
rbindlist
지금은 이름과 채우기없는 열을 기준으로 일치시킬 수 있습니다,rbind.data.table
단지 호출rbindlist
지금. 유일한 차이점은use.names=TRUE
기본적으로rbind.data.table
이전 버전과의 호환성을 위해입니다.
rbind.data.frame
(C로 이동하여) 피할 수있는 사본 (@mnel도 지적 함)으로 인해 상당히 느려집니다. 그게 유일한 이유는 아니라고 생각합니다. 열 이름 확인 / 일치에 대한 구현rbind.data.frame
data.frame 당 많은 열이 있고 바인딩 할 많은 data.frame이있는 경우 도 느려질 수 있습니다 (아래 벤치 마크 참조).
그러나 rbindlist
요소 수준 확인 또는 이름 일치와 같은 특정 기능 이 부족하면 (보다) 빠를수록 가중치가 매우 작거나 없습니다 rbind.data.frame
. 속도와 메모리에 최적화 된 C로 신중하게 구현 되었기 때문입니다.
다음은 rbindlist
의 use.names
기능을 사용하여 열 이름으로 일치하는 동안 효율적인 바인딩을 강조하는 벤치 마크입니다 v1.9.3
. 데이터 세트는 크기가 10 * 500 인 10000 개의 데이터 프레임으로 구성됩니다.
NB :이 벤치 마크에 대한 비교를 포함하도록 업데이트되었습니다 dplyr
s ‘을 (를)bind_rows
library(data.table) # 1.11.5, 2018-06-02 00:09:06 UTC
library(dplyr) # 0.7.5.9000, 2018-06-12 01:41:40 UTC
set.seed(1L)
names = paste0("V", 1:500)
cols = 500L
foo <- function() {
data = as.data.frame(setDT(lapply(1:cols, function(x) sample(10))))
setnames(data, sample(names))
}
n = 10e3L
ll = vector("list", n)
for (i in 1:n) {
.Call("Csetlistelt", ll, i, foo())
}
system.time(ans1 <- rbindlist(ll))
# user system elapsed
# 1.226 0.070 1.296
system.time(ans2 <- rbindlist(ll, use.names=TRUE))
# user system elapsed
# 2.635 0.129 2.772
system.time(ans3 <- do.call("rbind", ll))
# user system elapsed
# 36.932 1.628 38.594
system.time(ans4 <- bind_rows(ll))
# user system elapsed
# 48.754 0.384 49.224
identical(ans2, setDT(ans3))
# [1] TRUE
identical(ans2, setDT(ans4))
# [1] TRUE
이름을 확인하지 않고 열을 바인딩하는 데는 1.3이 걸리고 열 이름을 확인하고 바인딩하는 데 1.5 초가 더 걸렸습니다. 기본 솔루션에 비해 14 배 빠르며 dplyr
버전 보다 18 배 빠릅니다 .