Przez v1.9.2, rbindlistewoluował dość mocno, wdrażając wiele funkcji, w tym:
- Wybieranie najwyższej
SEXPTYPEz kolumn podczas wiązania - zaimplementowane w v1.9.2zamykaniu FR # 2456 i Bug # 4981 .
factorPrawidłowa obsługa kolumn - najpierw zaimplementowana w v1.8.10zamykaniu 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.tablerównież zyskał fillargument, który pozwala do wiązania poprzez wypełnienie brakujących kolumn, realizowany w R.
Teraz w v1.9.3tych istniejących funkcjach wprowadzono jeszcze więcej ulepszeń:
rbindlistotrzymuje argument use.names, który domyślnie służy FALSEdo wstecznej kompatybilności.
rbindlistrównież zyskuje argument fill, który domyślnie służy również FALSEkompatybilności wstecznej.
- Wszystkie te funkcje są zaimplementowane w C i starannie napisane, aby nie zmniejszać szybkości podczas dodawania funkcjonalności.
- Ponieważ
rbindlistmożna teraz dopasowywać według nazw i wypełniać brakujące kolumny, rbind.data.tablepo prostu wywołuje rbindlistteraz. Jedyną różnicą jest to, że use.names=TRUEdomyślnie for rbind.data.table, w celu zapewnienia zgodności wstecznej.
rbind.data.framespowalnia 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.framemoż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 rbindlistbrak 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.namesfunkcję 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ż dplyrwersja.
attr<-,class<-i (chyba)rownames<-wszystko modyfikować w miejscu.