rbindlist
jest zoptymalizowaną wersją programu do.call(rbind, list(...))
, która jest znana z tego, że działa wolno podczas używaniarbind.data.frame
Gdzie to naprawdę się wyróżnia
Kilka pytań, które pokazują, gdzie rbindlist
są błyski
Szybkie wektoryzowane łączenie list danych.frames według wiersza
Problem z konwersją długiej listy data.frames (~ 1 milion) do pojedynczej data.frame przy użyciu do.call i ldply
Mają testy porównawcze, które pokazują, jak szybko może to być.
rbind.data.frame jest powolny z jakiegoś powodu
rbind.data.frame
dużo sprawdza i dopasowuje według nazwy. (tzn. rbind.data.frame uwzględni fakt, że kolumny mogą być w różnych rzędach i pasować według nazwy), rbindlist
nie wykonuje tego rodzaju kontroli i łączy się według pozycji
na przykład
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
Inne ograniczenia rbindlist
Jest używany do walki do czynienia z factors
uwagi na błąd, który został już ustalony:
rbindlist two data.tables, gdzie jeden ma współczynnik, a drugi ma typ znaku dla kolumny ( Bug # 2650 )
Ma problemy ze zduplikowanymi nazwami kolumn
zobacz
Komunikat ostrzegawczy: w rbindlist (allargs): NA wprowadzone przez wymuszenie: możliwy błąd w data.table? ( Błąd # 2384 )
rownames rbind.data.frame mogą być frustrujące
rbindlist
może obsłużyć lists
data.frames
i data.tables
, i zwróci dane.table bez nazw wywołań
możesz dostać się w chaos rownames używając do.call(rbind, list(...))
see
Jak uniknąć zmiany nazw wierszy podczas używania rbind wewnątrz do.call?
Wydajność pamięci
Jeśli chodzi o pamięć, rbindlist
jest zaimplementowana w C
, więc jest wydajna, używa setattr
do ustawiania atrybutów przez odniesienie
rbind.data.frame
jest zaimplementowany w programie R
, wykonuje wiele przypisań i zastosowań attr<-
( class<-
i rownames<-
wszystko to (wewnętrznie) utworzy kopie utworzonej ramki data.frame.
attr<-
,class<-
i (chyba)rownames<-
wszystko modyfikować w miejscu.DF = data.frame(a=1:3); .Internal(inspect(DF)); tracemem(DF); attr(DF,"test") <- "hello"; .Internal(inspect(DF))
.rbind.data.frame
ma specjalną logikę „przechwytywania” - gdy jej pierwszym argumentem jest adata.table
, wywołuje.rbind.data.table
zamiast tego, co trochę sprawdza, a następnie wywołujerbindlist
wewnętrznie. Więc jeśli masz jużdata.table
obiekty do powiązania, prawdopodobnie różnica w wydajności międzyrbind
irbindlist
.rbindlist
jest w stanie dopasowywać według nazw (use.names=TRUE
), a także wypełniać brakujące kolumny (fill=TRUE
). Zaktualizowałem ten , ten i ten post. Czy masz coś przeciwko edycji tego, czy mogę to zrobić? Tak czy inaczej jest dla mnie w porządku.dplyr::rbind_list
jest również dość podobnyPrzez
v1.9.2
,rbindlist
ewoluował dość mocno, wdrażając wiele funkcji, w tym: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ń: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 programierbind.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
„suse.names
funkcję odv1.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
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.źródło