Lectura rápida de tablas muy grandes como marcos de datos


504

Tengo tablas muy grandes (30 millones de filas) que me gustaría cargar como marcos de datos en R. read.table()tiene muchas características convenientes, pero parece que hay mucha lógica en la implementación que ralentizaría las cosas. En mi caso, supongo que conozco los tipos de columnas con anticipación, la tabla no contiene ningún encabezado de columna o nombre de fila, y no tiene caracteres patológicos de los que deba preocuparme.

Sé que leer en una tabla como una lista usando scan()puede ser bastante rápido, por ejemplo:

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

Pero algunos de mis intentos de convertir esto en un marco de datos parecen disminuir el rendimiento de lo anterior en un factor de 6:

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

¿Hay una mejor manera de hacer esto? ¿O posiblemente un enfoque completamente diferente del problema?

Respuestas:


426

Una actualización, varios años después.

Esta respuesta es antigua y R ha seguido adelante. Ajustar read.tablepara correr un poco más rápido tiene muy poco beneficio. Sus opciones son:

  1. Uso vroomdel paquete tidyverse vroompara importar datos de archivos delimitados por csv / tab directamente en un R tibble.

  2. El uso freadde data.tablepara importar datos de archivos CSV / delimitado por tabuladores directamente en R. Véase la respuesta de mnel .

  3. Uso read_tableen readr(en CRAN desde abril de 2015). Esto funciona muy parecido a lo freadanterior. El archivo Léame en el enlace explica la diferencia entre las dos funciones ( readractualmente afirma ser "1.5-2x más lento" que data.table::fread).

  4. read.csv.rawfrom iotoolsofrece una tercera opción para leer rápidamente archivos CSV.

  5. Intentando almacenar tantos datos como puedas en bases de datos en lugar de archivos planos. (Además de ser un mejor medio de almacenamiento permanente, los datos se pasan hacia y desde R en un formato binario, que es más rápido). read.csv.sqlEn el sqldfpaquete, como se describe en la respuesta de JD Long , importa datos a una base de datos SQLite temporal y luego los lee en R. Véase también: el RODBCpaquete, y el reverso depende de la sección de la página del DBIpaquete . MonetDB.Rle ofrece un tipo de datos que pretende ser un marco de datos pero que es realmente un MonetDB debajo, lo que aumenta el rendimiento. Importar datos con su monetdb.read.csvfunción. dplyrle permite trabajar directamente con datos almacenados en varios tipos de bases de datos.

  6. Almacenar datos en formatos binarios también puede ser útil para mejorar el rendimiento. Utilice saveRDS/ readRDS(consulte a continuación), los paquetes h5o rhdf5para el formato HDF5, o write_fst/ read_fstdel fstpaquete.


La respuesta original

Hay un par de cosas simples para probar, ya sea que use read.table o scan.

  1. Set nrows= el número de registros en sus datos ( nmaxen scan).

  2. Asegúrese comment.char=""de desactivar la interpretación de los comentarios.

  3. Defina explícitamente las clases de cada columna usando colClassesin read.table.

  4. La configuración multi.line=FALSEtambién puede mejorar el rendimiento en el escaneo.

Si ninguna de estas cosas funciona, utilice uno de los paquetes de perfiles para determinar qué líneas están ralentizando las cosas. Quizás pueda escribir una versión reducida read.tablebasada en los resultados.

La otra alternativa es filtrar sus datos antes de leerlos en R.

O, si el problema es que tiene que leerlo regularmente, use estos métodos para leer los datos una vez, luego guarde el marco de datos como un blob binario con save saveRDS, la próxima vez que pueda recuperarlo más rápido con load readRDS.


44
Gracias por los consejos Richie. Hice una pequeña prueba, y parece que las ganancias de rendimiento con el uso de las opciones nrow y colClasses para read.table son bastante modestas. Por ejemplo, leer una tabla de filas de ~ 7M tarda 78 segundos sin las opciones y 67 segundos con las opciones. (nota: la tabla tiene 1 columna de caracteres, 4 columnas enteras, y leí usando comment.char = '' y stringsAsFactors = FALSE). Usar save () y load () cuando sea posible es un gran consejo: una vez almacenado con save (), esa misma tabla solo tarda 12 segundos en cargarse.
Eytan

2
El paquete "feather" tiene un nuevo formato binario que juega bien con los marcos de datos de los pandas de Python
rsoren

44
Creo que quizás necesites actualizar tu publicación nuevamente con respecto al paquete feather. Para leer datos featheres mucho más rápido que fread. Por ejemplo, en un conjunto de datos de 4GB que acabo de cargar read_featherfue aproximadamente 4.5 veces más rápido que fread. Para guardar datos fwritees aún más rápido. blog.dominodatalab.com/the-r-data-io-shootout
Z boson

2
Pero los tamaños de archivo son mucho más grandes para las plumas que con RDS. No creo que sea compatible con la compresión. El archivo RDS es de 216 MB y el archivo de plumas es de 4 GB. Por featherlo tanto, es más rápido para leer, pero utiliza mucho más espacio de almacenamiento.
Z boson

@Zboson Si necesita almacenar el marco de datos en un archivo al que se pueda acceder desde R y Python, entonces featheres una buena opción. Si solo le importa poder leer sus datos en R, rdses preferible.
Richie Cotton

279

Aquí hay un ejemplo que utiliza freaddesde data.table1.8.7

Los ejemplos provienen de la página de ayuda fread, con los tiempos en mi 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]

tabla de lectura estándar

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 optimizado

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

fread

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

En resumen:

##    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

43
Gran respuesta, y la evaluación comparativa es válida en otros contextos. Simplemente lea en un archivo de 4GB en menos de un minuto con fread. Había intentado leerlo con las funciones básicas de R y me llevó unas 15 horas.
Ari B. Friedman

1
mi punto de referencia sugiere ventajas de velocidad aún mayores para read.csv en data.table. tenga en cuenta que data.table no es R estándar, pero (lamentablemente) "simplemente" muy bien compartido por sus creadores en CRAN. ni siquiera se considera lo suficientemente estándar como para hacer la lista común de paquetes R, y mucho menos califica como un reemplazo para los marcos de datos. Tiene muchas ventajas, pero también algunos aspectos muy contraintuitivos. es posible que desee utilizar as.data.frame (fread.csv ("test.csv")) con el paquete para volver al mundo estándar del marco de datos R.
ivo Welch

3
@mnel, ¿podría volver a ejecutar el punto de referencia e incluirlo readr?
jangorecki

2
Segundo @jangorecki. Además, dado que ahora freadtiene algunos competidores reales, podría ser útil agregar puntos de referencia para un freaduso optimizado , especificando colClasses, etc.
MichaelChirico

1
@jangorecji @ MichaelChirico, el código proporcionado es completamente reproducible, por lo que es sencillo simular el lector ... volver a ejecutar el código, en mi máquina el tiempo transcurrido es el doble de rápido, si no más, para la mayoría de los resultados, aunque lo estoy ejecutando en una red (y versiones bien actualizadas ya que hace algún tiempo) ... y con el lector estoy en 7s pero también menos de un segundo cuando corro una segunda vez (0.66s), sospecho que hay algún almacenamiento en caché o algún cuello de botella en la red. fread para la solución más rápida que se muestra aquí es a los 2 segundos de mi lado para comparar (la primera vez que se ejecuta a las 8,69 segundos) por alguna razón más lenta)
R. Prost

249

No vi esta pregunta inicialmente y formulé una pregunta similar unos días después. Voy a tomar mi pregunta anterior, pero pensé agregar una respuesta aquí para explicar cómo solía sqldf()hacer esto.

Se ha debatido poco sobre la mejor manera de importar 2 GB o más de datos de texto en un marco de datos R. Ayer escribí una publicación de blog sobre el uso sqldf()para importar los datos a SQLite como un área de ensayo, y luego succionarlos de SQLite a R. Esto funciona muy bien para mí. Pude obtener 2 GB (3 columnas, filas de 40 mm) de datos en <5 minutos. Por el contrario, el read.csvcomando se ejecutó toda la noche y nunca se completó.

Aquí está mi código de prueba:

Configure los datos de prueba:

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

Reinicié R antes de ejecutar la siguiente rutina de importación:

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

Dejé correr la siguiente línea toda la noche pero nunca se completó:

system.time(big.df <- read.csv('bigdf.csv'))

1
Hola. ¿Cómo lo usaría como entrada para otros paquetes, como el zoológico, diseñados para ser utilizados con todos los datos simultáneamente?
skan

@skan el objeto final es un marco de datos. Por lo tanto, debe convertirlo en un objeto de zoológico para usarlo con el zoológico. Mire los ejemplos en los documentos del zoológico para obtener ilustraciones.
JD Long

@JD Long. Hola, el problema es que cuando lo conviertes en un objeto de zoológico, intenta colocarlo en la memoria. Si es demasiado grande, produce un error. Y si el resultado del objeto zoo (por ejemplo, una agregación de dos series) también es demasiado, también debería ser un objeto sql o ff.
skan

No sé qué le pasa a sqldf. Creé un archivo simple de 1GB en el disco (con 2 columnas numéricas) y usé DTSQL <- read.csv.sql ("f2.txt", dbname = tempfile ()) e intenta cargar todos los datos en la memoria. Mañana intentaré ff y revoscaler en su lugar.
skan

1
@ lo que m es mil, entonces mm es mil mil o millones. Probablemente debería haberlo capitalizado como MM. Pero encuentro que casi cualquier millón de abreviaturas pueden ser confusas para alguien si tienes una audiencia lo suficientemente diversa. En mi intento de ser demasiado detallado, ¡lamento haberlo hecho más confuso! accountingcoach.com/blog/what-does-m-and-mm-stand-for
JD Long

73

Curiosamente, nadie respondió la parte inferior de la pregunta durante años a pesar de que esta es una lista importante con data.framesimplemente los atributos correctos, por lo que si tiene datos grandes que no desea usar as.data.frameo similares para una lista. Es mucho más rápido simplemente "convertir" una lista en un marco de datos in situ:

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

Esto no hace una copia de los datos, por lo que es inmediato (a diferencia de todos los demás métodos). Se supone que ya ha establecido names()en la lista en consecuencia.

[En cuanto a la carga de datos grandes en R, personalmente, los vuelco por columna en archivos binarios y los uso readBin(), ese es, con mucho, el método más rápido (aparte de mmapping) y solo está limitado por la velocidad del disco. Analizar archivos ASCII es inherentemente lento (incluso en C) en comparación con los datos binarios.]


66
Usar tracmemsugiere eso attr<-y class<-hacer copias internamente. bit::setattro data.table::setattrno lo hará.
mnel

66
¿Quizás usaste el orden incorrecto? No hay copia si la usa df=scan(...); names(df)=...; attr...; class...- vea tracemem()(probado en R 2.15.2)
Simon Urbanek

3
¿Puede explicar cómo volcar los datos grandes por columna en archivos binarios?
dabsingh

32

Esto se preguntó anteriormente en R-Help , por lo que vale la pena revisarlo.

Una sugerencia fue usar readChar()y luego manipular cadenas en el resultado con strsplit()y substr(). Puede ver que la lógica involucrada en readChar es mucho menor que read.table.

No sé si la memoria es un problema aquí, pero es posible que también desee echar un vistazo al paquete HadoopStreaming . Esto usa Hadoop , que es un marco de MapReduce diseñado para manejar grandes conjuntos de datos. Para esto, usaría la función hsTableReader. Este es un ejemplo (pero tiene una curva de aprendizaje para aprender 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)

La idea básica aquí es dividir la importación de datos en fragmentos. Incluso podría ir tan lejos como para usar uno de los marcos paralelos (por ejemplo, nieve) y ejecutar la importación de datos en paralelo segmentando el archivo, pero lo más probable es que para conjuntos de datos grandes que no ayuden, ya que se encontrará con restricciones de memoria, Es por eso que map-reduce es un mejor enfoque.


Acabo de hacer una prueba rápida y readChar parece ser mucho más rápido que incluso readLines por alguna razón inexplicable. Sin embargo, todavía es lento como el pecado en comparación con una simple prueba de C. En la simple tarea de leer 100 megas, R es aproximadamente 5 - 10 veces más lento que C
Jonathan Chang

1
No entiendo tu punto. El objetivo de Hadoop es manejar datos muy grandes, que es de lo que se trataba la pregunta.
Shane

1
A pesar del nombre, hsTableReader no tiene nada que ver con Hadoop per se, es para procesar grandes datos en piezas. Se lee de con, un trozo de filas a la vez, y pasa cada trozo como data.frame a FUN para su procesamiento. Con ignoreKey = FALSE, realiza una agrupación adicional por clave (la entrada en la primera columna), que es relevante para los enfoques de Mapa / Reducir.
DavidR

Hola. ¿Cómo usaría estos datos de Hadoop como entrada para otros paquetes como zoo, diseñados para ser utilizados con todos los datos simultáneamente?
skan

10

Una alternativa es usar el vroompaquete. Ahora en CRAN. vroomno carga todo el archivo, indexa dónde se encuentra cada registro y se lee más tarde cuando lo usa.

Solo paga por lo que usas.

Consulte Introducción a vroom , Comience con vroom y los puntos de referencia de vroom .

La descripción básica es que la lectura inicial de un archivo enorme será mucho más rápida y las modificaciones posteriores a los datos pueden ser un poco más lentas. Entonces, dependiendo de cuál sea su uso, podría ser la mejor opción.

Vea un ejemplo simplificado de los puntos de referencia de vroom a continuación, las partes clave para ver son los tiempos de lectura súper rápidos, pero las operaciones ligeramente más reducidas como el agregado, 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

5

Unos puntos adicionales menores que vale la pena mencionar. Si tiene un archivo muy grande, puede calcular sobre la marcha el número de filas (si no hay encabezado) usando (donde bedGraphestá el nombre de su archivo en su directorio de trabajo):

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

A continuación, puede utilizar ya sea en que 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

4

Muchas veces creo que es una buena práctica mantener bases de datos más grandes dentro de una base de datos (por ejemplo, Postgres). No uso nada mucho más grande que (nrow * ncol) ncell = 10M, que es bastante pequeño; pero a menudo encuentro que quiero que R cree y contenga gráficos intensivos en memoria solo mientras realizo consultas desde múltiples bases de datos. En el futuro de las computadoras portátiles de 32 GB, algunos de estos tipos de problemas de memoria desaparecerán. Pero el atractivo de usar una base de datos para contener los datos y luego usar la memoria de R para los resultados de la consulta y los gráficos resultantes aún puede ser útil. Algunas ventajas son:

(1) Los datos permanecen cargados en su base de datos. Simplemente vuelva a conectar en pgadmin a las bases de datos que desee cuando vuelva a encender su computadora portátil.

(2) Es cierto que R puede realizar muchas más operaciones estadísticas y gráficas ingeniosas que SQL. Pero creo que SQL está mejor diseñado para consultar grandes cantidades de datos 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)

3

Estoy leyendo datos muy rápidamente usando el nuevo arrowpaquete. Parece estar en una etapa bastante temprana.

Específicamente, estoy usando el formato columnar de parquet . Esto convierte de nuevo a a data.frameen R, pero puede obtener aceleraciones aún más profundas si no lo hace. Este formato es conveniente ya que también se puede usar desde Python.

Mi principal caso de uso para esto es en un servidor RShiny bastante restringido. Por estas razones, prefiero mantener los datos adjuntos a las aplicaciones (es decir, fuera de SQL) y, por lo tanto, requieren un tamaño de archivo pequeño y velocidad.

Este artículo vinculado proporciona evaluaciones comparativas y una buena descripción general. He citado algunos puntos interesantes a continuación.

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

Tamaño del archivo

Es decir, el archivo Parquet es la mitad de grande que incluso el CSV comprimido. Una de las razones por las que el archivo Parquet es tan pequeño es por la codificación del diccionario (también llamada "compresión del diccionario"). La compresión de diccionario puede producir una compresión sustancialmente mejor que el uso de un compresor de bytes de uso general como LZ4 o ZSTD (que se usan en el formato FST). Parquet fue diseñado para producir archivos muy pequeños que son rápidos de leer.

Velocidad de lectura

Cuando se controla por tipo de salida (por ejemplo, comparando todas las salidas de datos de R de marco entre sí), vemos que el rendimiento de Parquet, Feather y FST cae dentro de un margen relativamente pequeño entre sí. Lo mismo se aplica a las salidas pandas.DataFrame. data.table :: fread es impresionantemente competitivo con el tamaño de archivo de 1,5 GB, pero está por detrás de los demás en el CSV de 2,5 GB.


Prueba independiente

Realicé algunas evaluaciones comparativas independientes en un conjunto de datos simulado de 1,000,000 de filas. Básicamente barajé un montón de cosas para intentar desafiar la compresión. También agregué un campo de texto corto de palabras aleatorias y dos factores simulados.

Datos

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))
         )

Lee y escribe

Escribir los datos es 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)

Leer los datos también es 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)

Probé la lectura de estos datos con algunas de las opciones de la competencia, y obtuve resultados ligeramente diferentes a los del artículo anterior, que es de esperar.

evaluación comparativa

Este archivo no es tan grande como el artículo de referencia, así que tal vez esa sea la diferencia.

Pruebas

  • rds: test_data.rds (20.3 MB)
  • parquet2_native: (14.9 MB con mayor compresión y as_data_frame = FALSE)
  • parquet2: test_data2.parquet (14.9 MB con mayor compresión)
  • parquet: test_data.parquet (40.7 MB)
  • fst2: test_data2.fst (27.9 MB con mayor compresión)
  • 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 de lectura con arrow)
  • feather: test_data.feather (157,2 MB de lectura con feather)

Observaciones

Para este archivo en particular, en freadrealidad es muy rápido. Me gusta el pequeño tamaño de archivo de la parquet2prueba altamente comprimida . Puedo invertir el tiempo para trabajar con el formato de datos nativo en lugar de data.framesi realmente necesito acelerar.

Aquí fsttambién hay una gran opción. Usaría el fstformato altamente comprimido o el altamente comprimido parquetdependiendo de si necesitaba la velocidad o el tamaño del archivo.


0

En lugar de la read.table convencional, creo que fread es una función más rápida. Especificar atributos adicionales como seleccionar solo las columnas requeridas, especificar colclasses y cadenas como factores reducirá el tiempo necesario para importar el archivo.

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"))

0

He intentado todo lo anterior y [readr] [1] hizo el mejor trabajo. Solo tengo 8 gb de RAM

Bucle para 20 archivos, 5 gb cada uno, 7 columnas:

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)))
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.