답변:
rbindlist의 최적화 된 버전으로 do.call(rbind, list(...)), 사용시 속도가 느린 것으로 알려져 있습니다.rbind.data.frame
rbindlist빛나는 곳을 보여주는 몇 가지 질문
do.call 및 ldply를 사용하여 긴 데이터 프레임 목록 (~ 1 백만)을 단일 데이터 프레임으로 변환하는 데 문제가 있습니다.
여기에는 얼마나 빠른지 보여주는 벤치 마크가 있습니다.
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
그것은 하는 데 사용 처리하는 투쟁 factors으로 인해 수정 된 이후이 버그로 :
rbindlist 두 개의 data.tables 중 하나에는 요인이 있고 다른 하나에는 열에 대한 문자 유형이 있습니다 ( 버그 # 2650 )
중복 된 열 이름에 문제가 있습니다
참조 경고 메시지 : rbindlist에 (allargs) : data.table 가능한 버그 : 강압에 의해 도입의 NA? ( 버그 # 2384 )
rbindlistlists 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의 복사본을 만들 것이다 모두를.
DF = data.frame(a=1:3); .Internal(inspect(DF)); tracemem(DF); attr(DF,"test") <- "hello"; .Internal(inspect(DF)).
rbind.data.frame특별한 "hijacking"로직을 가지고 있습니다-첫 번째 인자가 a data.table일 때 .rbind.data.table, 대신 약간 호출하고 rbindlist내부적으로 호출합니다 . 당신이 이미 가지고있는 경우에 따라서 data.table바인드에 물체를 사이에 아마 약간의 성능 차이있다 rbind및 rbindlist.
dplyr::rbind_list또한 매우 유사하다
함으로써 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또한 얻은 fillR. 구현 누락 된 열을 작성하여 바인드 할 수 있습니다 인수를,
지금에 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.framedata.frame 당 많은 열이 있고 바인딩 할 많은 data.frame이있는 경우 도 느려질 수 있습니다 (아래 벤치 마크 참조).
그러나 rbindlist요소 수준 확인 또는 이름 일치와 같은 특정 기능 이 부족하면 (보다) 빠를수록 가중치가 매우 작거나 없습니다 rbind.data.frame. 속도와 메모리에 최적화 된 C로 신중하게 구현 되었기 때문입니다.
다음은 rbindlist의 use.names기능을 사용하여 열 이름으로 일치하는 동안 효율적인 바인딩을 강조하는 벤치 마크입니다 v1.9.3. 데이터 세트는 크기가 10 * 500 인 10000 개의 데이터 프레임으로 구성됩니다.
NB :이 벤치 마크에 대한 비교를 포함하도록 업데이트되었습니다 dplyrs '을 (를)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 배 빠릅니다 .
attr<-로class<-(제 생각에는)rownames<-모두 수정되었습니다.