Algo como o seguinte deve resultar em cada quadro de dados como um elemento separado em uma única lista:
temp = list.files(pattern="*.csv")
myfiles = lapply(temp, read.delim)
Isso pressupõe que você tenha esses CSVs em um único diretório - seu diretório de trabalho atual - e que todos eles tenham a extensão em minúscula .csv
.
Se você deseja combinar esses quadros de dados em um único quadro de dados, consulte as soluções em outras respostas usando coisas como do.call(rbind,...)
, dplyr::bind_rows()
ou data.table::rbindlist()
.
Se você realmente deseja cada quadro de dados em um objeto separado, mesmo que isso seja desaconselhável, faça o seguinte com assign
:
temp = list.files(pattern="*.csv")
for (i in 1:length(temp)) assign(temp[i], read.csv(temp[i]))
Ou, sem assign
e para demonstrar (1) como o nome do arquivo pode ser limpo e (2) mostrar como usar list2env
, você pode tentar o seguinte:
temp = list.files(pattern="*.csv")
list2env(
lapply(setNames(temp, make.names(gsub("*.csv$", "", temp))),
read.csv), envir = .GlobalEnv)
Mas, novamente, geralmente é melhor deixá-los em uma única lista.
A5C1D2H2I1M1N2O1R2T1
fonte
assign
estiver tentando escrever uma função para executar a versão atualizada desta resposta usando ... Se desejar que os valores atribuídos residam no ambiente global, definainherits=T
.Uma
tidyverse
solução rápida e sucinta : (mais que o dobro da velocidade da Base Rread.csv
)e o data.table 's
fread()
pode até reduzir esses tempos de carregamento pela metade novamente. (por 1/4 do tempo Base R )O
stringsAsFactors = FALSE
argumento mantém o fator do quadro de dados livre (e, como aponta o marbel, é a configuração padrãofread
)Se a conversão de tipo estiver sendo atrevida, você pode forçar todas as colunas a serem como caracteres com o
col_types
argumento.Se você deseja mergulhar em subdiretórios para construir sua lista de arquivos para vincular eventualmente, inclua o nome do caminho e registre os arquivos com seus nomes completos na sua lista. Isso permitirá que o trabalho de ligação continue fora do diretório atual. (Pensando nos nomes de caminho completos como operando como passaportes para permitir o movimento de volta pelas 'fronteiras' do diretório.)
Como Hadley descreve aqui (aproximadamente na metade do caminho):
Recurso bônus - adicionando nomes de arquivos aos registros por solicitação de recurso Niks nos comentários abaixo:
* Adicione original
filename
a cada registro.Código explicado: crie uma função para anexar o nome do arquivo a cada registro durante a leitura inicial das tabelas. Em seguida, use essa função em vez da
read_csv()
função simples .(As abordagens de manipulação de
read_plus()
tipos e manipulação de subdiretórios também podem ser tratadas dentro da função da mesma maneira que ilustrada na segunda e terceira variantes sugeridas acima.)Caso de Uso de Middling
Caso de uso maior
Variedade de casos de uso
Linhas: contagem de arquivos (1000, 100, 10)
Colunas: tamanho final do quadro de dados (5MB, 50MB, 500MB)
(clique na imagem para ver o tamanho original)
Os resultados da base R são melhores para os menores casos de uso em que a sobrecarga de trazer as bibliotecas C de ronronar e dplyr supera os ganhos de desempenho observados ao executar tarefas de processamento em maior escala.
se você quiser executar seus próprios testes, poderá achar este script bash útil.
bash what_you_name_this_script.sh "fileName_you_want_copied" 100
criará 100 cópias do seu arquivo numeradas seqüencialmente (após os 8 caracteres iniciais do nome do arquivo e um sublinhado).Atribuições e apreciações
Agradecimentos especiais a:
map_df()
aqui .fread()
. (Eu preciso estudardata.table
.)fonte
readAddFilename <- function(flnm) { read_csv(flnm) %>% mutate(filename = flnm) }
basta soltá-lo nomap_df
lugar da leitura simplesread_csv()
que está lá agora. Posso atualizar a entrada acima para mostrar a função e como ela se encaixaria no pipe se você ainda tiver dúvidas ou acha que será útil.read_csv
é muito mais lento do quefread
. Eu incluiria uma referência se você disser que algo é mais rápido. Uma idéia é criar 30 arquivos de 1 GB e lê-los, seria um caso em que o desempenho é importante.fread()
e dplyr ' sread_csv()
: 14,2 vs 19,9 segundos. TBH, eu só estava comparando a base R com o dplyr e comoread_csv()
é cerca de 2-4x mais rápido que oread.csv()
, o benchmarking não parecia necessário. No entanto, foi interessante darfread()
uma volta e fazer uma pausa para verificar resultados de benchmark mais completos. Obrigado novamente!Aqui estão algumas opções para converter os arquivos .csv em um data.frame usando a base R e alguns dos pacotes disponíveis para leitura de arquivos em R.
Isso é mais lento que as opções abaixo.
Editar: - Mais algumas opções extras usando
data.table
ereadr
Uma
fread()
versão, que é uma função dodata.table
pacote. Esta é de longe a opção mais rápida em R .Usando readr , que é outro pacote para ler arquivos csv. É mais lento que
fread
, mais rápido que a base R, mas tem funcionalidades diferentes.fonte
data.table
versão que deve melhorar o desempenho.do.call
Além de usar
lapply
ou alguma outra construção de loop no R, você pode mesclar seus arquivos CSV em um arquivo.No Unix, se os arquivos não tinham cabeçalhos, é tão fácil quanto:
ou, se houver cabeçalhos, e você puder encontrar uma string que corresponda a cabeçalhos e apenas a cabeçalhos (por exemplo, suponha que todas as linhas de cabeçalho comecem com "Idade"), você faria:
Eu acho que no Windows você poderia fazer isso com
COPY
eSEARCH
(ouFIND
algo assim) na caixa de comando do DOS, mas por que não instalarcygwin
e obter o poder do shell de comando do Unix?fonte
Git
instalação?Este é o código que desenvolvi para ler todos os arquivos csv no R. Ele criará um quadro de dados para cada arquivo csv individualmente e titulará esse quadro como nome original do arquivo (removendo espaços e o arquivo .csv). Espero que você ache útil!
fonte
As três principais respostas de @ A5C1D2H2I1M1N2O1R2T1, @leerssej e @marbel são basicamente as mesmas: aplique o fread em cada arquivo e depois rbind / rbindlist as tabelas de dados resultantes. Eu costumo usar o
rbindlist(lapply(list.files("*.csv"),fread))
formulário.Isso é melhor do que outras alternativas internas R e é bom para um pequeno número de csvs grandes, mas não é o melhor para um grande número de csvs pequenos quando a velocidade importa. Nesse caso, pode ser muito mais rápido usá-lo pela primeira vez
cat
, como sugere o @Spacedman na resposta da quarta posição. Vou adicionar alguns detalhes sobre como fazer isso no R:No entanto, e se cada csv tiver um cabeçalho?
E se você tiver tantos arquivos que o
*.csv
shell glob falhe?E se todos os arquivos tiverem um cabeçalho E houver muitos arquivos?
E se o csv concatenado resultante for muito grande para a memória do sistema?
Com cabeçalhos?
Finalmente, e se você não quiser todos os .csv em um diretório, mas um conjunto específico de arquivos? (Além disso, todos eles têm cabeçalhos.) (Este é o meu caso de uso.)
e isso é sobre a mesma velocidade que o gato xargs fread simples :)
Nota: para data.table anterior à v1.11.6 (19 de setembro de 2018), omita o
cmd=
defread(cmd=
.Adendo: usar o mclapply da biblioteca paralela no lugar de lapply serial, por exemplo,
rbindlist(lapply(list.files("*.csv"),fread))
também é muito mais rápido do que o rbindlist lapply fread.Hora de ler 121401 csvs em uma única tabela de dados. Cada csv possui 3 colunas, uma linha de cabeçalho e, em média, 4.510 linhas. A máquina é uma VM GCP com 96 núcleos:
Resumindo, se você está interessado em velocidade e possui muitos arquivos e muitos núcleos, o fread xargs cat é cerca de 50x mais rápido que a solução mais rápida nas 3 principais respostas.
fonte
Na minha opinião, a maioria das outras respostas é obsoleta
rio::import_list
, o que é uma linha sucinta:Quaisquer argumentos extras são passados para
rio::import
.rio
pode lidar com quase qualquer formato de arquivo que o R possa ler, e usa-data.table
o semprefread
que possível, portanto deve ser rápido também.fonte
O uso de
plyr::ldply
aproximadamente um aumento de velocidade de 50% ao ativar a.parallel
opção durante a leitura de arquivos 400 csv com aproximadamente 30 a 40 MB cada. O exemplo inclui uma barra de progresso do texto.fonte
fread
ouuser-defined functions
? Obrigado!?ldply
mostra...
outros argumentos passados para.fun
. Usandofread, skip = 100
oufunction(x) fread(x, skip = 100)
quer trabalharfunction(x) fread(x, skip = 100)
não funcionou para mim, mas fornecer argumentos adicionais após o nome da função vazia fez o truque. Obrigado novamente!Com base no comentário do dnlbrk, o assign pode ser consideravelmente mais rápido que o list2env para arquivos grandes.
Ao definir o argumento full.names como true, você obterá o caminho completo para cada arquivo como uma sequência de caracteres separada em sua lista de arquivos, por exemplo, List_of_file_paths [1] será algo como "C: / Users / Anon / Documents / Pasta_com_arquivos_csv / arquivo1.csv "
Você pode usar o fread do pacote data.table ou o R read.csv base em vez do read_csv. A etapa file_name permite que você organize o nome para que cada quadro de dados não permaneça com o caminho completo do arquivo como seu nome. Você pode estender seu loop para fazer outras coisas na tabela de dados antes de transferi-lo para o ambiente global, por exemplo:
fonte
Este é o meu exemplo específico para ler vários arquivos e combiná-los em um quadro de dados:
fonte
rbindlist()
fromdata.table
Os códigos a seguir devem fornecer a velocidade mais rápida para big data, desde que você tenha muitos núcleos no computador:
Atualizado em 2020/04/16: Como encontro um novo pacote disponível para computação paralela, uma solução alternativa é fornecida usando os seguintes códigos.
fonte
Eu gosto da abordagem usando
list.files()
,lapply()
elist2env()
(oufs::dir_ls()
,purrr::map()
elist2env()
). Isso parece simples e flexível.Como alternativa, você pode tentar o pequeno pacote { tor } ( para-R ): Por padrão, importa arquivos do diretório ativo para uma lista (
list_*()
variantes) ou para o ambiente global (load_*()
variantes).Por exemplo, aqui eu leio todos os arquivos .csv do meu diretório de trabalho em uma lista usando
tor::list_csv()
:E agora carrego esses arquivos no meu ambiente global com
tor::load_csv()
:Se você precisar ler arquivos específicos, poderá combinar o caminho do arquivo com
regexp
,ignore.case
einvert
.Para ainda mais flexibilidade, use
list_any()
. Ele permite que você forneça a função de leitor via argumento.f
.Passe argumentos adicionais via ... ou dentro da função lambda.
fonte
Foi solicitado que eu adicionasse essa funcionalidade ao pacote R do stackoverflow. Dado que é um pacote tinyverse (e não pode depender de pacotes de terceiros), aqui está o que eu vim com:
Ao parametrizar a função de leitor e redutor, as pessoas podem usar data.table ou dplyr, se assim o desejarem, ou apenas usar as funções R básicas que são boas para conjuntos de dados menores.
fonte