Por v1.9.2
, rbindlist
evoluiu bastante, implementando muitos recursos, incluindo:
- Escolhendo a
SEXPTYPE
coluna mais alta durante a encadernação - implementada no v1.9.2
fechamento da FR # 2456 e Bug # 4981 .
- Manipulando
factor
colunas corretamente - implementado pela primeira vez no v1.8.10
fechamento do Bug # 2650 e estendido aos fatores ordenados de ligação com cuidado v1.9.2
também, fechando o FR # 4856 e o Bug # 5019 .
Além disso, em v1.9.2
, rbind.data.table
também ganhou um fill
argumento, que permite vincular preenchendo colunas ausentes, implementadas em R.
Agora v1.9.3
, há ainda mais melhorias nesses recursos existentes:
rbindlist
ganha um argumento use.names
, que por padrão é FALSE
para compatibilidade com versões anteriores.
rbindlist
também ganha um argumento fill
, que por padrão também é FALSE
para compatibilidade com versões anteriores.
- Esses recursos são todos implementados em C e escritos com cuidado para não comprometer a velocidade ao adicionar funcionalidades.
- Como
rbindlist
agora pode corresponder por nomes e preencher as colunas ausentes, rbind.data.table
basta ligar rbindlist
agora. A única diferença é que, use.names=TRUE
por padrão rbind.data.table
, para compatibilidade com versões anteriores.
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 que rbind.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
o use.names
recurso de v1.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
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
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.
attr<-
,class<-
e (acho)rownames<-
todas as modificações são feitas no local.