rbindlist
é uma versão otimizada do.call(rbind, list(...))
, conhecida por ser lenta ao usarrbind.data.frame
Onde ele realmente se destaca
Algumas perguntas que mostram onde rbindlist
estão os brilhos
Mesclagem vetorizada rápida da lista de data.frames por linha
Problemas ao converter uma lista longa de data.frames (~ 1 milhão) em data.frame único usando do.call e ldply
Eles têm referências que mostram quão rápido pode ser.
rbind.data.frame é lento, por um motivo
rbind.data.frame
faz muitas verificações e corresponde ao nome. (ou seja, rbind.data.frame levará em consideração o fato de que as colunas podem estar em ordens diferentes e serem correspondidas por nome), rbindlist
não faz esse tipo de verificação e se unirá por posição
por exemplo
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
Algumas outras limitações do rbindlist
É usado para lutam para lidar com factors
, devido a um bug que, desde então, foram corrigidos:
rbindlist dois data.tables em que um possui fator e outro possui tipo de caractere para uma coluna ( Bug # 2650 )
Tem problemas com nomes de colunas duplicados
consulte
Mensagem de aviso: no rbindlist (allargs): NAs introduzidas por coerção: possível bug no data.table? ( Bug # 2384 )
Os nomes de rbind.data.frame podem ser frustrantes
rbindlist
pode lidar com lists
data.frames
e data.tables
, e irá retornar um data.table sem rownames
você pode entrar em uma confusão de rownames usando do.call(rbind, list(...))
see
Como evitar renomear linhas ao usar rbind dentro de do.call?
Eficiência de memória
Em termos de memória rbindlist
é implementada C
, assim como é eficiente em termos de memória , ela usa setattr
para definir atributos por referência
rbind.data.frame
é implementado R
, ele faz muitas atribuições e usa attr<-
( class<-
e rownames<-
todos os quais criarão (internamente) cópias do data.frame criado).
attr<-
,class<-
e (acho)rownames<-
todas as modificações são feitas no local.DF = data.frame(a=1:3); .Internal(inspect(DF)); tracemem(DF); attr(DF,"test") <- "hello"; .Internal(inspect(DF))
.rbind.data.frame
possui uma lógica especial de "seqüestro" - quando seu primeiro argumento é adata.table
, ele chama.rbind.data.table
, o que faz uma pequena verificação e depois chamarbindlist
internamente. Portanto, se você já possuidata.table
objetos para vincular, provavelmente há pouca diferença de desempenho entrerbind
erbindlist
.rbindlist
capaz de corresponder por nomes (use.names=TRUE
) e também preencher colunas ausentes (fill=TRUE
). Eu atualizei este , este e este post. Você se importa de editar este ou está tudo bem se eu fizer? De qualquer maneira é bom para mim.dplyr::rbind_list
também é bem parecidoPor
v1.9.2
,rbindlist
evoluiu bastante, implementando muitos recursos, incluindo:Além disso, em
v1.9.2
,rbind.data.table
também ganhou umfill
argumento, que permite vincular preenchendo colunas ausentes, implementadas em R.Agora
v1.9.3
, há ainda mais melhorias nesses recursos existentes:rbind.data.frame
diminui bastante devido principalmente às cópias (que o @mnel também aponta) que poderiam ser evitadas (passando para C). Eu acho que essa não é a única razão. A implementação para verificar / combinar nomes de colunas emrbind.data.frame
também pode ficar mais lenta quando houver muitas colunas por data.frame e existirem muitos data.frames a serem vinculados (como mostrado na referência abaixo).No entanto, essa
rbindlist
falta (ed) de certos recursos (como verificar níveis de fator ou nomes correspondentes) tem um peso muito pequeno (ou nenhum) para que seja mais rápido do querbind.data.frame
. É porque eles foram cuidadosamente implementados em C, otimizados para velocidade e memória.Aqui está uma referência que destaca a ligação eficiente, enquanto faz a correspondência por nomes de colunas, usando também
rbindlist
ouse.names
recurso dev1.9.3
. O conjunto de dados consiste em 10000 quadros de dados, cada um com tamanho 10 * 500.NB: esta referência foi atualizada para incluir uma comparação com
dplyr
asbind_rows
A ligação de colunas como tal, sem verificar os nomes, levou apenas 1,3, enquanto que a verificação dos nomes das colunas e a ligação, levaram apenas 1,5 segundos a mais. Comparado à solução base, isso é 14x mais rápido e 18x mais rápido que
dplyr
a versão.fonte