Przez v1.9.2
, rbindlist
ewoluował dość mocno, wdrażając wiele funkcji, w tym:
- Wybieranie najwyższej
SEXPTYPE
z kolumn podczas wiązania - zaimplementowane w v1.9.2
zamykaniu FR # 2456 i Bug # 4981 .
factor
Prawidłowa obsługa kolumn - najpierw zaimplementowana w v1.8.10
zamykaniu Bug # 2650 i rozszerzona o dokładne wiązanie uporządkowanych czynników v1.9.2
, zamykając FR # 4856 i Bug # 5019 .
Ponadto, w v1.9.2
, rbind.data.table
również zyskał fill
argument, który pozwala do wiązania poprzez wypełnienie brakujących kolumn, realizowany w R.
Teraz w v1.9.3
tych istniejących funkcjach wprowadzono jeszcze więcej ulepszeń:
rbindlist
otrzymuje argument use.names
, który domyślnie służy FALSE
do wstecznej kompatybilności.
rbindlist
również zyskuje argument fill
, który domyślnie służy również FALSE
kompatybilności wstecznej.
- Wszystkie te funkcje są zaimplementowane w C i starannie napisane, aby nie zmniejszać szybkości podczas dodawania funkcjonalności.
- Ponieważ
rbindlist
można teraz dopasowywać według nazw i wypełniać brakujące kolumny, rbind.data.table
po prostu wywołuje rbindlist
teraz. Jedyną różnicą jest to, że use.names=TRUE
domyślnie for rbind.data.table
, w celu zapewnienia zgodności wstecznej.
rbind.data.frame
spowalnia całkiem sporo, głównie z powodu kopii (na co wskazuje @mnel), których można by uniknąć (przechodząc do C). Myślę, że to nie jedyny powód. Implementacja sprawdzania / dopasowywania nazw kolumn w programie rbind.data.frame
może również działać wolniej, gdy jest wiele kolumn na ramkę data.frame i jest wiele takich ramek danych do powiązania (jak pokazano w poniższym benchmarku).
Jednak rbindlist
brak niektórych funkcji (takich jak sprawdzanie poziomów czynników lub pasujących nazw) ma bardzo małą (lub żadną) wagę, ponieważ jest szybszy niż rbind.data.frame
. To dlatego, że zostały starannie zaimplementowane w C, zoptymalizowane pod kątem szybkości i pamięci.
Oto punkt odniesienia, który podkreśla, że skuteczne wiązanie, dopasowując przez nazwy kolumn, jak również przy użyciu rbindlist
„s use.names
funkcję od v1.9.3
. Zestaw danych składa się z 10000 ramek danych, każda o rozmiarze 10 * 500.
Uwaga: ten wzorzec został zaktualizowany do obejmować porównanie do dplyr
„sbind_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
Wiązanie kolumn jako takich bez sprawdzania nazw zajęło tylko 1,3, podczas gdy sprawdzenie nazw kolumn i odpowiednie powiązanie zajęło tylko 1,5 sekundy więcej. W porównaniu do rozwiązania podstawowego jest to 14x szybsze i 18x szybsze niż dplyr
wersja.
attr<-
,class<-
i (chyba)rownames<-
wszystko modyfikować w miejscu.