Leitura rápida de tabelas muito grandes como quadros de dados

504

Eu tenho tabelas muito grandes (30 milhões de linhas) que eu gostaria de carregar como quadros de dados em R. read.table()tem muitos recursos convenientes, mas parece que há muita lógica na implementação que atrasaria as coisas. No meu caso, suponho que conheço os tipos de colunas antes do tempo, a tabela não contém nenhum cabeçalho ou nome de linha e não possui caracteres patológicos com os quais eu tenha que me preocupar.

Eu sei que a leitura em uma tabela como uma lista usando scan()pode ser bastante rápida, por exemplo:

datalist <- scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0)))

Mas algumas das minhas tentativas de converter isso em um quadro de dados parecem diminuir o desempenho do anterior por um fator 6:

df <- as.data.frame(scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0))))

Existe um jeito melhor de fazer isso? Ou, possivelmente, uma abordagem completamente diferente do problema?

eytan
fonte

Respostas:

426

Uma atualização, vários anos depois

Essa resposta é antiga e R foi adiante. Ajustar read.tablepara correr um pouco mais rápido tem pouco e precioso benefício. Suas opções são:

  1. Usando vroomdo pacote tidyverse vroompara importar dados de arquivos delimitados por csv / tab diretamente para um R tibble.

  2. Usando freadem data.tablepara importar dados de arquivos CSV / delimitados por tabulação diretamente na R. Veja a resposta de mnel .

  3. Usando read_tablein readr(no CRAN de abril de 2015). Isso funciona como freadacima. O leia-me no link explica a diferença entre as duas funções ( readratualmente afirma ser "1,5-2x mais lenta" que data.table::fread).

  4. read.csv.rawfrom iotoolsfornece uma terceira opção para ler rapidamente arquivos CSV.

  5. Tentando armazenar o máximo de dados possível nos bancos de dados, em vez de arquivos simples. (Além de ser um meio de armazenamento permanente melhor, os dados são passados ​​para e de R em um formato binário, o que é mais rápido.) read.csv.sqlNo sqldfpacote, conforme descrito na resposta de JD Long , importa dados para um banco de dados SQLite temporário e os lê. em R. Veja também: o RODBCpacote e o verso depende da seção da página do DBIpacote . MonetDB.Rfornece um tipo de dados que finge ser um quadro de dados, mas na verdade é um MonetDB, aumentando o desempenho. Importe dados com sua monetdb.read.csvfunção. dplyrpermite trabalhar diretamente com dados armazenados em vários tipos de banco de dados.

  6. Armazenar dados em formatos binários também pode ser útil para melhorar o desempenho. Use saveRDS/ readRDS(veja abaixo), os pacotes h5ou rhdf5para o formato HDF5 ou write_fst/ read_fstdo fstpacote.


A resposta original

Existem algumas coisas simples para tentar, se você usa read.table ou scan.

  1. Set nrows= o número de registros em seus dados ( nmaxpol scan).

  2. Certifique-se comment.char=""de desativar a interpretação dos comentários.

  3. Defina explicitamente as classes de cada coluna usando colClassesin read.table.

  4. A configuração multi.line=FALSEtambém pode melhorar o desempenho na verificação.

Se nada disso funcionar, use um dos pacotes de criação de perfil para determinar quais linhas estão atrasando as coisas. Talvez você possa escrever uma versão reduzida com read.tablebase nos resultados.

A outra alternativa é filtrar seus dados antes de lê-los em R.

Ou, se o problema é que você precisa lê-lo regularmente, use esses métodos para ler os dados uma vez e salve o quadro de dados como um blob binário com save saveRDS, da próxima vez você pode recuperá-lo mais rapidamente com load readRDS.

Richie Cotton
fonte
4
Obrigado pelas dicas Richie. Fiz alguns testes e parece que os ganhos de desempenho com o uso das opções nrow e colClasses para read.table são bastante modestos. Por exemplo, a leitura de uma tabela de linha de ~ 7M leva 78s sem as opções e 67s com as opções. (nota: a tabela possui 1 coluna de caracteres, 4 colunas inteiras e li usando comment.char = '' e stringsAsFactors = FALSE). Usar save () e load () quando possível é uma ótima dica - uma vez armazenada com save (), a mesma tabela leva apenas 12 segundos para carregar.
Eytan
2
O pacote "pena" tem um novo formato binário que joga bonito com pandas quadros de dados do Python
rsoren
4
Acho que talvez você precise atualizar sua postagem novamente com relação ao pacote feather. Para ler dados featheré muito mais rápido que fread. Por exemplo, em um conjunto de dados de 4 GB que acabei de carregar, read_featherera cerca de 4,5 vezes mais rápido que fread. Para salvar dados fwriteainda é mais rápido. blog.dominodatalab.com/the-r-data-io-shootout
Z boson
2
Mas os tamanhos dos arquivos são muito maiores para penas do que com o RDS. Eu não acho que suporta compressão. O arquivo RDS tem 216 MB e o arquivo pena é de 4 GB. Portanto, featheré mais rápido para a leitura, mas usa muito mais espaço de armazenamento.
Z Higgs
@Zboson Se você precisar armazenar o quadro de dados em um arquivo que possa ser acessado pelo R e pelo Python, featheré uma boa opção. Se você se preocupa apenas em poder ler seus dados em R, rdsé preferível.
Richie Cotton
279

Aqui está um exemplo que utiliza freadda data.table1.8.7

Os exemplos vêm da página de ajuda para fread, com os horários no meu Windows XP Core 2 duo E8400.

library(data.table)
# Demo speedup
n=1e6
DT = data.table( a=sample(1:1000,n,replace=TRUE),
                 b=sample(1:1000,n,replace=TRUE),
                 c=rnorm(n),
                 d=sample(c("foo","bar","baz","qux","quux"),n,replace=TRUE),
                 e=rnorm(n),
                 f=sample(1:1000,n,replace=TRUE) )
DT[2,b:=NA_integer_]
DT[4,c:=NA_real_]
DT[3,d:=NA_character_]
DT[5,d:=""]
DT[2,e:=+Inf]
DT[3,e:=-Inf]

read.table padrão

write.table(DT,"test.csv",sep=",",row.names=FALSE,quote=FALSE)
cat("File size (MB):",round(file.info("test.csv")$size/1024^2),"\n")    
## File size (MB): 51 

system.time(DF1 <- read.csv("test.csv",stringsAsFactors=FALSE))        
##    user  system elapsed 
##   24.71    0.15   25.42
# second run will be faster
system.time(DF1 <- read.csv("test.csv",stringsAsFactors=FALSE))        
##    user  system elapsed 
##   17.85    0.07   17.98

read.table otimizado

system.time(DF2 <- read.table("test.csv",header=TRUE,sep=",",quote="",  
                          stringsAsFactors=FALSE,comment.char="",nrows=n,                   
                          colClasses=c("integer","integer","numeric",                        
                                       "character","numeric","integer")))


##    user  system elapsed 
##   10.20    0.03   10.32

medo

require(data.table)
system.time(DT <- fread("test.csv"))                                  
 ##    user  system elapsed 
##    3.12    0.01    3.22

sqldf

require(sqldf)

system.time(SQLDF <- read.csv.sql("test.csv",dbname=NULL))             

##    user  system elapsed 
##   12.49    0.09   12.69

# sqldf as on SO

f <- file("test.csv")
system.time(SQLf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F)))

##    user  system elapsed 
##   10.21    0.47   10.73

ff / ffdf

 require(ff)

 system.time(FFDF <- read.csv.ffdf(file="test.csv",nrows=n))   
 ##    user  system elapsed 
 ##   10.85    0.10   10.99

Em suma:

##    user  system elapsed  Method
##   24.71    0.15   25.42  read.csv (first time)
##   17.85    0.07   17.98  read.csv (second time)
##   10.20    0.03   10.32  Optimized read.table
##    3.12    0.01    3.22  fread
##   12.49    0.09   12.69  sqldf
##   10.21    0.47   10.73  sqldf on SO
##   10.85    0.10   10.99  ffdf
mnel
fonte
43
Ótima resposta, e o benchmarking é válido em outros contextos. Basta ler em um arquivo de 4 GB em menos de um minuto com fread. Tentou lê-lo com as funções básicas R e levou cerca de 15 horas.
Ari B. Friedman
1
meu benchmark sugere vantagens de velocidade ainda maiores para o read.csv no data.table. observe que data.table não é o padrão R, mas (infelizmente) "apenas" é compartilhado com agrado por seus criadores no CRAN. nem sequer é considerado padrão o suficiente para fazer a lista de pacotes R comum, e muito menos qualificar como um substituto para os quadros de dados. tem muitas vantagens, mas também alguns aspectos muito contra-intuitivos. convém usar as.data.frame (fread.csv ("test.csv")) com o pacote para retornar ao mundo padrão do quadro de dados R.
Ivo Welch
3
@mnel, você poderia executar novamente o benchmark e incluir readr?
Jangorecki
2
Segundo @jangorecki. Além disso, dado freadtem alguns concorrentes reais agora, poderia ser útil para adicionar valores de referência para otimizado freadde uso - especificando colClasses, etc.
MichaelChirico
1
@jangorecji @ MichaelChirico, o código fornecido é totalmente reproduzível, portanto, é fácil simular a readr ... re-executando o código, na máquina o tempo decorrido é duas vezes mais rápido, se não mais, para a maioria dos resultados, mesmo que eu esteja executando-o em uma rede (e versões bem atualizadas, já que já faz algum tempo) ... e com readr tenho 7 anos, mas também menos de um segundo quando executo uma segunda vez (0,66 s), suspeito que haja algum cache ou gargalo na rede. fread para a solução mais rápida mostrado aqui é a 2s do meu lado para comparaison (primeira vez correndo em 8.69s), por algum motivo mais lento)
R. Prost
249

Não vi essa pergunta inicialmente e fiz uma pergunta semelhante alguns dias depois. Vou retirar minha pergunta anterior, mas pensei em adicionar uma resposta aqui para explicar como costumava sqldf()fazer isso.

Houve pouca discussão sobre a melhor maneira de importar 2 GB ou mais de dados de texto em um quadro de dados R. Ontem escrevi um post sobre sqldf()como importar os dados para o SQLite como uma área de preparação e depois sugá-los do SQLite para o R. Isso funciona muito bem para mim. Consegui extrair 2 GB (3 colunas, linhas de 40 mm) de dados em <5 minutos. Por outro lado, o read.csvcomando foi executado a noite toda e nunca foi concluído.

Aqui está o meu código de teste:

Configure os dados de teste:

bigdf <- data.frame(dim=sample(letters, replace=T, 4e7), fact1=rnorm(4e7), fact2=rnorm(4e7, 20, 50))
write.csv(bigdf, 'bigdf.csv', quote = F)

Reiniciei o R antes de executar a seguinte rotina de importação:

library(sqldf)
f <- file("bigdf.csv")
system.time(bigdf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F)))

Deixei a seguinte linha rodar a noite toda, mas ela nunca foi concluída:

system.time(big.df <- read.csv('bigdf.csv'))
JD Long
fonte
1
Oi. Como você o utiliza como entrada para outros pacotes, como o zoo, projetados para serem usados ​​com todos os dados simultaneamente?
skan
@skan o objeto final é um quadro de dados. Então você precisa convertê-lo em um objeto de zoológico para usá-lo com o zoo. Veja os exemplos nos documentos do zoológico para ilustrações.
perfil completo de JD Long
@JD Long. Olá, o problema é que, quando você o converte em um objeto de zoológico, ele tenta encaixá-lo na memória. Se for muito grande, produz um erro. E se o resultado do objeto zoo (por exemplo, uma agregação de duas séries) também for necessário, ele também precisará ser um objeto sql ou ff.
skan
Não sei o que há de errado com o sqldf. Criei um arquivo simples de 1 GB no disco (com 2 colunas numéricas) e usei o DTSQL <- read.csv.sql ("f2.txt", dbname = tempfile ()) e ele tenta carregar todos os dados na memória. Amanhã vou tentar ff e revoscaler.
skan
1
@ o que m é mil, então mm é mil mil ou milhões. Eu provavelmente deveria ter capitalizado isso como MM. Mas acho que praticamente qualquer milhão de abreviações pode ser confuso para alguém se você tiver um público diversificado o suficiente. Na minha tentativa de ser excessivamente detalhado, desculpe-me por torná-lo mais confuso! accountingcoach.com/blog/what-does-m-and-mm-stand-for
JD Longo
73

Estranhamente, ninguém respondeu a parte inferior da pergunta por anos, mesmo sendo importante - data.framesão simplesmente listas com os atributos corretos; portanto, se você possui dados grandes, não deseja usar as.data.frameou similares para uma lista. É muito mais rápido simplesmente "transformar" uma lista em um quadro de dados no local:

attr(df, "row.names") <- .set_row_names(length(df[[1]]))
class(df) <- "data.frame"

Isso não faz cópia dos dados, portanto é imediato (ao contrário de todos os outros métodos). Assume que você já definiunames() a lista adequadamente.

[Quanto ao carregamento de dados grandes no R - pessoalmente, eu os despejo por coluna em arquivos binários e o uso readBin()- esse é de longe o método mais rápido (além do mmapping) e é limitado apenas pela velocidade do disco. A análise de arquivos ASCII é inerentemente lenta (mesmo em C) em comparação com dados binários.]

Simon Urbanek
fonte
6
Usar tracmemsugere isso attr<-e class<-faça cópias internamente. bit::setattrou data.table::setattrnão vai.
mnel
6
Talvez você tenha usado a ordem errada? Não há cópia se você usar df=scan(...); names(df)=...; attr...; class...- consulte tracemem()(testado em R 2.15.2)
Simon Urbanek
3
Você pode elaborar como despejar os grandes dados por coluna em arquivos binários?
dabsingh 14/09/16
32

Isso foi solicitado anteriormente no R-Help , portanto vale a pena revisar.

Uma sugestão era usar readChar()e, em seguida, manipular as strings no resultado com strsplit()e substr(). Você pode ver que a lógica envolvida no readChar é muito menor que a read.table.

Não sei se a memória é um problema aqui, mas você também pode querer dar uma olhada no pacote HadoopStreaming . Isso usa o Hadoop , que é uma estrutura do MapReduce projetada para lidar com grandes conjuntos de dados. Para isso, você usaria a função hsTableReader. Este é um exemplo (mas tem uma curva de aprendizado para aprender o Hadoop):

str <- "key1\t3.9\nkey1\t8.9\nkey1\t1.2\nkey1\t3.9\nkey1\t8.9\nkey1\t1.2\nkey2\t9.9\nkey2\"
cat(str)
cols = list(key='',val=0)
con <- textConnection(str, open = "r")
hsTableReader(con,cols,chunkSize=6,FUN=print,ignoreKey=TRUE)
close(con)

A idéia básica aqui é dividir a importação de dados em partes. Você pode ir até o ponto de usar uma das estruturas paralelas (por exemplo, neve) e executar a importação de dados em paralelo, segmentando o arquivo, mas provavelmente para grandes conjuntos de dados que não ajudarão, pois você encontrará restrições de memória, é por isso que reduzir o mapa é uma abordagem melhor.

Shane
fonte
Acabei de fazer um teste rápido e o readChar parece muito mais rápido do que o readLines por algum motivo inexplicável. No entanto, ainda é lento como o pecado em comparação com um simples teste C. No simples tarefa de leitura de 100 megas, R é de cerca de 5 - 10 vezes mais lento do que C
Jonathan Chang
1
Não entenda seu ponto de vista. O objetivo do Hadoop é manipular dados muito grandes, e era disso que se tratava a questão.
Shane
1
Apesar do nome, o hsTableReader não tem nada a ver com o Hadoop por si só, é para processar grandes dados em pedaços. Ele lê de con, um pedaço de linhas por vez, e passa cada pedaço como um data.frame para FUN para processamento. Com ignoreKey = FALSE, ele faz algum agrupamento extra por chave (a entrada na primeira coluna), o que é relevante para abordagens de Mapear / Reduzir.
DavidR
Oi. Como você usaria esses dados do Hadoop como entrada para outros pacotes, como o zoo, projetados para serem usados ​​com todos os dados simultaneamente?
skan
10

Uma alternativa é usar o vroompacote. Agora no CRAN. vroomnão carrega o arquivo inteiro, indexa onde cada registro está localizado e é lido mais tarde quando você o usa.

Pague apenas pelo que usar.

Consulte Introdução ao vroom , Introdução ao vroom e os benchmarks do vroom .

A visão geral básica é que a leitura inicial de um arquivo enorme será muito mais rápida e as modificações subsequentes nos dados poderão ser um pouco mais lentas. Portanto, dependendo do seu uso, pode ser a melhor opção.

Veja um exemplo simplificado dos benchmarks de vroom abaixo, as principais partes a serem observadas são os tempos de leitura super rápidos, mas operações ligeiramente semeadoras, como agregadas, etc.

package                 read    print   sample   filter  aggregate   total
read.delim              1m      21.5s   1ms      315ms   764ms       1m 22.6s
readr                   33.1s   90ms    2ms      202ms   825ms       34.2s
data.table              15.7s   13ms    1ms      129ms   394ms       16.3s
vroom (altrep) dplyr    1.7s    89ms    1.7s     1.3s    1.9s        6.7s
Hector Haffenden
fonte
5

Alguns pontos adicionais menores que vale a pena mencionar. Se você tiver um arquivo muito grande, poderá calcular rapidamente o número de linhas (se não houver cabeçalho) usando (onde bedGraphestá o nome do seu arquivo no diretório de trabalho):

>numRow=as.integer(system(paste("wc -l", bedGraph, "| sed 's/[^0-9.]*\\([0-9.]*\\).*/\\1/'"), intern=T))

Você pode então usar essa seja em read.csv, read.table...

>system.time((BG=read.table(bedGraph, nrows=numRow, col.names=c('chr', 'start', 'end', 'score'),colClasses=c('character', rep('integer',3)))))
   user  system elapsed 
 25.877   0.887  26.752 
>object.size(BG)
203949432 bytes
Stephen Henderson
fonte
4

Muitas vezes, acho que é apenas uma boa prática manter bancos de dados maiores dentro de um banco de dados (por exemplo, Postgres). Eu não uso nada muito maior que (nrow * ncol) ncell = 10M, que é bem pequeno; mas muitas vezes acho que quero que o R crie e mantenha gráficos intensivos de memória apenas enquanto consulta em vários bancos de dados. No futuro dos laptops de 32 GB, alguns desses tipos de problemas de memória desaparecerão. Mas o fascínio de usar um banco de dados para armazenar os dados e, em seguida, usar a memória de R para os resultados e gráficos resultantes da consulta ainda pode ser útil. Algumas vantagens são:

(1) Os dados permanecem carregados no seu banco de dados. Você simplesmente reconecta o pgadmin aos bancos de dados que deseja quando liga o laptop novamente.

(2) É verdade que R pode executar muito mais operações estatísticas e gráficas do que SQL. Mas acho que o SQL é melhor projetado para consultar grandes quantidades de dados do que R.

# Looking at Voter/Registrant Age by Decade

library(RPostgreSQL);library(lattice)

con <- dbConnect(PostgreSQL(), user= "postgres", password="password",
                 port="2345", host="localhost", dbname="WC2014_08_01_2014")

Decade_BD_1980_42 <- dbGetQuery(con,"Select PrecinctID,Count(PrecinctID),extract(DECADE from Birthdate) from voterdb where extract(DECADE from Birthdate)::numeric > 198 and PrecinctID in (Select * from LD42) Group By PrecinctID,date_part Order by Count DESC;")

Decade_RD_1980_42 <- dbGetQuery(con,"Select PrecinctID,Count(PrecinctID),extract(DECADE from RegistrationDate) from voterdb where extract(DECADE from RegistrationDate)::numeric > 198 and PrecinctID in (Select * from LD42) Group By PrecinctID,date_part Order by Count DESC;")

with(Decade_BD_1980_42,(barchart(~count | as.factor(precinctid))));
mtext("42LD Birthdays later than 1980 by Precinct",side=1,line=0)

with(Decade_RD_1980_42,(barchart(~count | as.factor(precinctid))));
mtext("42LD Registration Dates later than 1980 by Precinct",side=1,line=0)
rferrisx
fonte
3

Estou lendo dados muito rapidamente usando o novo arrow pacote. Parece estar em um estágio bastante inicial.

Especificamente, estou usando o formato colunar em parquet . Isso converte novamente em umdata.frame em R, mas você pode obter velocidades ainda mais profundas se não o fizer. Esse formato é conveniente, pois também pode ser usado no Python.

Meu principal caso de uso para isso está em um servidor RShiny bastante restrito. Por esses motivos, prefiro manter os dados anexados aos aplicativos (ou seja, fora do SQL) e, portanto, requer tamanho de arquivo pequeno e velocidade.

Este artigo vinculado fornece benchmarking e uma boa visão geral. Citei alguns pontos interessantes abaixo.

https://ursalabs.org/blog/2019-10-columnar-perf/

Tamanho do arquivo

Ou seja, o arquivo Parquet é metade do tamanho do arquivo CSV compactado com gzip. Uma das razões pelas quais o arquivo Parquet é tão pequeno é por causa da codificação de dicionário (também chamada de "compactação de dicionário"). A compactação de dicionário pode produzir uma compactação substancialmente melhor do que o uso de um compressor de bytes de uso geral como LZ4 ou ZSTD (que são usados ​​no formato FST). O Parquet foi projetado para produzir arquivos muito pequenos que são rápidos de ler.

Velocidade de leitura

Ao controlar por tipo de saída (por exemplo, comparando todas as saídas R data.frame uma com a outra), vemos o desempenho do Parquet, Feather e FST caem dentro de uma margem relativamente pequena. O mesmo vale para as saídas pandas.DataFrame. data.table :: fread é impressionantemente competitivo com o tamanho de arquivo de 1,5 GB, mas fica abaixo dos outros no CSV de 2,5 GB.


Teste Independente

Eu realizei alguns testes independentes em um conjunto de dados simulado de 1.000.000 de linhas. Basicamente, embaralhei várias coisas para tentar desafiar a compressão. Também adicionei um pequeno campo de texto de palavras aleatórias e dois fatores simulados.

Dados

library(dplyr)
library(tibble)
library(OpenRepGrid)

n <- 1000000

set.seed(1234)
some_levels1 <- sapply(1:10, function(x) paste(LETTERS[sample(1:26, size = sample(3:8, 1), replace = TRUE)], collapse = ""))
some_levels2 <- sapply(1:65, function(x) paste(LETTERS[sample(1:26, size = sample(5:16, 1), replace = TRUE)], collapse = ""))


test_data <- mtcars %>%
  rownames_to_column() %>%
  sample_n(n, replace = TRUE) %>%
  mutate_all(~ sample(., length(.))) %>%
  mutate(factor1 = sample(some_levels1, n, replace = TRUE),
         factor2 = sample(some_levels2, n, replace = TRUE),
         text = randomSentences(n, sample(3:8, n, replace = TRUE))
         )

Leia e escreva

Escrever os dados é fácil.

library(arrow)

write_parquet(test_data , "test_data.parquet")

# you can also mess with the compression
write_parquet(test_data, "test_data2.parquet", compress = "gzip", compression_level = 9)

A leitura dos dados também é fácil.

read_parquet("test_data.parquet")

# this option will result in lightning fast reads, but in a different format.
read_parquet("test_data2.parquet", as_data_frame = FALSE)

Testei a leitura desses dados em algumas das opções concorrentes e obtive resultados ligeiramente diferentes dos do artigo acima, o que é esperado.

avaliação comparativa

Esse arquivo não é nem do tamanho do artigo de referência; talvez essa seja a diferença.

Testes

  • rds: test_data.rds (20,3 MB)
  • parquet2_native: (14,9 MB com maior compactação e as_data_frame = FALSE)
  • parquet2: test_data2.parquet (14,9 MB com maior compactação)
  • parquet: test_data.parquet (40,7 MB)
  • fst2: test_data2.fst (27,9 MB com maior compactação)
  • fst: test_data.fst (76,8 MB)
  • fread2: test_data.csv.gz (23.6MB)
  • fread: test_data.csv (98,7MB)
  • feather_arrow: test_data.feather (157,2 MB lido com arrow)
  • feather: test_data.feather (157,2 MB lido com feather)

Observações

Para este arquivo em particular, freadé realmente muito rápido. Eu gosto do tamanho pequeno do parquet2teste altamente compactado . Posso investir tempo para trabalhar com o formato de dados nativo, em vez dedata.frame se realmente precisar da velocidade.

Aqui fsttambém é uma ótima opção. Eu usaria o fstformato altamente compactado ou o altamente compactado, parquetdependendo se precisava da troca de velocidade ou tamanho do arquivo.

Adão
fonte
0

Em vez da tabela read.t convencional, sinto que o medo é uma função mais rápida. Especificar atributos adicionais, como selecionar apenas as colunas necessárias, especificar colclasses e sequência, como fatores reduzirá o tempo necessário para importar o arquivo.

data_frame <- fread("filename.csv",sep=",",header=FALSE,stringsAsFactors=FALSE,select=c(1,4,5,6,7),colClasses=c("as.numeric","as.character","as.numeric","as.Date","as.Factor"))
Aayush Agrawal
fonte
0

Eu tentei tudo acima e [readr] [1] fez o melhor trabalho. Tenho apenas 8gb de RAM

Loop para 20 arquivos, 5 gb cada, 7 colunas:

read_fwf(arquivos[i],col_types = "ccccccc",fwf_cols(cnpj = c(4,17), nome = c(19,168), cpf = c(169,183), fantasia = c(169,223), sit.cadastral = c(224,225), dt.sitcadastral = c(226,233), cnae = c(376,382)))
Brun Ijbh
fonte