Eu tenho um código que em um local termina com uma lista de quadros de dados que eu realmente quero converter em um único quadro de big data.
Eu recebi alguns indicadores de uma pergunta anterior que estava tentando fazer algo semelhante, mas mais complexo.
Aqui está um exemplo do que estou começando (isso é bastante simplificado para ilustração):
listOfDataFrames <- vector(mode = "list", length = 100)
for (i in 1:100) {
listOfDataFrames[[i]] <- data.frame(a=sample(letters, 500, rep=T),
b=rnorm(500), c=rnorm(500))
}
Atualmente, estou usando isso:
df <- do.call("rbind", listOfDataFrames)
do.call("rbind", list)
idioma é o que eu já usei antes. Por que você precisa da inicialunlist
?Respostas:
Use bind_rows () do pacote dplyr:
fonte
.id = "column_label"
adiciona os nomes de linha exclusivos com base nos nomes dos elementos da lista.dplyr
é uma ferramenta rápida e sólida de usar, alterei isso para a resposta aceita. Os anos, eles voam!Uma outra opção é usar uma função plyr:
Isso é um pouco mais lento que o original:
Meu palpite é que usar
do.call("rbind", ...)
será a abordagem mais rápida que você encontrará, a menos que você possa fazer algo como (a) usar matrizes em vez de data.frames e (b) pré-alocar a matriz final e atribuí-la a ela, em vez de aumentá-la. .Editar 1 :
Com base no comentário de Hadley, aqui está a versão mais recente
rbind.fill
do CRAN:Isso é mais fácil do que o rbind e marginalmente mais rápido (esses tempos são mantidos em várias execuções). E até onde eu entendo, a versão do
plyr
on github é ainda mais rápida que isso.fonte
I()
poderia substituirdata.frame
em sualdply
chamadamelt.list
em remodelar (2)do.call(function(...) rbind(..., make.row.names=F), df)
é útil se você não desejar os nomes de nomes de usuário exclusivos gerados automaticamente.Para fins de completude, pensei que as respostas a essa pergunta exigiam uma atualização. "Meu palpite é que o uso
do.call("rbind", ...)
será a abordagem mais rápida que você encontrará ..." Provavelmente era verdade para maio de 2010 e algum tempo depois, mas por volta de setembro de 2011 uma nova funçãorbindlist
foi introduzida nadata.table
versão 1.8.2 do pacote , com uma observação de que "Isso faz o mesmo quedo.call("rbind",l)
, mas muito mais rápido". Quão rápido?fonte
ldply
um monte de quadros de dados longos e fundidos. De qualquer forma, recebi uma aceleração incrível usando suarbindlist
sugestão.dplyr::rbind_all(listOfDataFrames)
também fará o truque.rbindlist
mas que acrescenta os quadros de dados por coluna? algo como uma lista cbind?do.call()
estava em uma lista de quadros de dados há 18 horas e ainda não tinha terminado, obrigado !!!Código:
Sessão:
ATUALIZAÇÃO : Execute novamente 31 de janeiro de 2018. Funcionou no mesmo computador. Novas versões de pacotes. Sementes adicionadas para os amantes de sementes.
ATUALIZAÇÃO : Execute novamente 06-Aug-2019.
fonte
set.seed
), mas vi algumas diferenças no pior desempenho.rbindlist
Na verdade, tivemos o melhor do pior caso, bem como melhor caso típico nos meus resultadosHá também
bind_rows(x, ...)
emdplyr
.fonte
Aqui está outra maneira de fazer isso (basta adicioná-lo às respostas, porque
reduce
é uma ferramenta funcional muito eficaz que muitas vezes é negligenciada como um substituto para os loops. Nesse caso em particular, nenhum deles é significativamente mais rápido que o call.c)usando a base R:
ou, usando o tidyverse:
fonte
Como isso deve ser feito no sentido inverso:
fonte
map
sebind_rows
pode obter uma lista de quadros de dados?Um visual atualizado para aqueles que desejam comparar algumas das respostas recentes (eu queria comparar a solução purrr para dplyr). Basicamente, combinei respostas do @TheVTM e do @rmf.
Código:
Informações da sessão:
Versões do pacote:
fonte
A única coisa que
data.table
falta às soluções é a coluna identificadora para saber de qual quadro de dados na lista os dados são provenientes.Algo assim:
O
idcol
parâmetro adiciona uma coluna (.id
) identificando a origem do quadro de dados contida na lista. O resultado seria algo parecido com isto:fonte