web-dev-qa-db-fra.com

R lisant un énorme csv

J'ai un énorme fichier csv. Sa taille est d'environ 9 Go. J'ai 16 Go de RAM. J'ai suivi les conseils de la page et les ai mis en œuvre ci-dessous.

If you get the error that R cannot allocate a vector of length x, close out of R and add the following line to the ``Target'' field: 
--max-vsize=500M 

Je reçois toujours l'erreur et les avertissements ci-dessous. Comment lire le fichier de 9 Go dans mon R? J'ai R 64 bits 3.3.1 et j'exécute la commande ci-dessous dans le rstudio 0.99.903. J'ai Windows Server 2012 R2 Standard, OS 64 bits.

> memory.limit()
[1] 16383
> answer=read.csv("C:/Users/a-vs/results_20160291.csv")
Error: cannot allocate vector of size 500.0 Mb
In addition: There were 12 warnings (use warnings() to see them)
> warnings()
Warning messages:
1: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
2: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
3: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
4: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
5: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
6: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
7: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
8: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
9: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
10: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
11: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)
12: In scan(file = file, what = what, sep = sep, quote = quote,  ... :
  Reached total allocation of 16383Mb: see help(memory.size)

------------------- Update1

Mon premier essai basé sur la réponse suggérée

> thefile=fread("C:/Users/a-vs/results_20160291.csv", header = T)
Read 44099243 rows and 36 (of 36) columns from 9.399 GB file in 00:13:34
Warning messages:
1: In fread("C:/Users/a-vsingh/results_tendo_20160201_20160215.csv",  :
  Reached total allocation of 16383Mb: see help(memory.size)
2: In fread("C:/Users/a-vsingh/results_tendo_20160201_20160215.csv",  :
  Reached total allocation of 16383Mb: see help(memory.size)

------------------- Update2

mon 2ème essai basé sur la réponse suggérée est comme ci-dessous

thefile2 <- read.csv.ffdf(file="C:/Users/a-vs/results_20160291.csv", header=TRUE, VERBOSE=TRUE, 
+                    first.rows=-1, next.rows=50000, colClasses=NA)
read.table.ffdf 1..
Error: cannot allocate vector of size 125.0 Mb
In addition: There were 14 warnings (use warnings() to see them)

Comment pourrais-je lire ce fichier dans un seul objet afin que je puisse analyser toutes les données en une seule fois

------------------ mise à jour 3

Nous avons acheté une machine chère. Il a 10 cœurs et 256 Go de RAM. Ce n'est pas la solution la plus efficace mais cela fonctionne au moins dans un avenir proche. J'ai regardé les réponses ci-dessous et je ne pense pas qu'elles résolvent mon problème :( J'apprécie ces réponses. Je veux effectuer l'analyse du panier de marché et je ne pense pas qu'il n'y ait pas d'autre moyen que de conserver mes données dans la RAM

19
user2543622

Assurez-vous que vous utilisez R 64 bits, pas seulement Windows 64 bits, afin d'augmenter votre allocation RAM sur les 16 Go).

De plus, vous pouvez lire le fichier par morceaux:

file_in    <- file("in.csv","r")
chunk_size <- 100000 # choose the best size for you
x          <- readLines(file_in, n=chunk_size)

Vous pouvez utiliser data.table pour gérer plus efficacement la lecture et la manipulation de fichiers volumineux:

require(data.table)
fread("in.csv", header = T)

Si nécessaire, vous pouvez exploiter la mémoire de stockage avec ff:

library("ff")
x <- read.csv.ffdf(file="file.csv", header=TRUE, VERBOSE=TRUE, 
                   first.rows=10000, next.rows=50000, colClasses=NA)
17
Hack-R

Vous voudrez peut-être envisager de tirer parti d'un traitement sur disque et de ne pas avoir cet objet entier dans la mémoire de R. Une option consisterait à stocker les données dans une base de données appropriée, puis à y accéder par R. dplyr est capable de gérer une source distante (il écrit en fait les instructions SQL pour interroger la base de données). Je viens de tester cela avec un petit exemple (seulement 17 500 lignes), mais j'espère que cela répond à vos besoins.

Installer SQLite

https://www.sqlite.org/download.html

Entrez les données dans une nouvelle base de données SQLite

  • Enregistrez les éléments suivants dans un nouveau fichier nommé import.sql

CREATE TABLE tableName (COL1, COL2, COL3, COL4); .separator , .import YOURDATA.csv tableName

Oui, vous devrez spécifier vous-même les noms des colonnes (je crois) mais vous pouvez également spécifier leurs types ici si vous le souhaitez. Cela ne fonctionnera pas si vous avez des virgules n'importe où dans vos noms/données, bien sûr.

  • Importez les données dans la base de données SQLite via la ligne de commande

sqlite3.exe BIGDATA.sqlite3 < import.sql

Pointez dplyr vers la base de données SQLite

Comme nous utilisons SQLite, toutes les dépendances sont déjà gérées par dplyr.

library(dplyr) my_db <- src_sqlite("/PATH/TO/YOUR/DB/BIGDATA.sqlite3", create = FALSE) my_tbl <- tbl(my_db, "tableName")

Faites votre analyse exploratoire

dplyr écrira les commandes SQLite nécessaires pour interroger cette source de données. Sinon, il se comportera comme une table locale. La grande exception sera que vous ne pouvez pas interroger le nombre de lignes.

my_tbl %>% group_by(COL2) %>% summarise(meanVal = mean(COL3))

#>  Source:   query [?? x 2]
#>  Database: sqlite 3.8.6 [/PATH/TO/YOUR/DB/BIGDATA.sqlite3]
#>  
#>         COL2    meanVal
#>        <chr>      <dbl>
#>  1      1979   15.26476
#>  2      1980   16.09677
#>  3      1981   15.83936
#>  4      1982   14.47380
#>  5      1983   15.36479
9
Jonathan Carroll

Cela peut ne pas être possible sur votre ordinateur. Dans certains cas, data.table Occupe plus d'espace que son homologue .csv.

DT <- data.table(x = sample(1:2,10000000,replace = T))
write.csv(DT, "test.csv") #29 MB file
DT <- fread("test.csv", row.names = F)   
object.size(DT)
> 40001072 bytes #40 MB

Deux MOO plus grands:

DT <- data.table(x = sample(1:2,1000000000,replace = T))
write.csv(DT, "test.csv") #2.92 GB file
DT <- fread("test.csv", row.names = F)   
object.size(DT)
> 4000001072 bytes #4.00 GB

Il y a un surcoût naturel pour stocker un objet dans R. Sur la base de ces chiffres, il y a environ un facteur de 1,33 lors de la lecture des fichiers. Cependant, cela varie en fonction des données. Par exemple, en utilisant

  • x = sample(1:10000000,10000000,replace = T) donne un facteur à peu près 2x (R: csv).

  • x = sample(c("foofoofoo","barbarbar"),10000000,replace = T) donne un facteur de 0,5x (R: csv).

Sur la base du maximum, votre fichier de 9 Go nécessiterait un potentiel de 18 Go de mémoire pour être stocké dans R, sinon plus. En fonction de votre message d'erreur, il est beaucoup plus probable que vous rencontriez des contraintes de mémoire dure par rapport à un problème d'allocation. Par conséquent, simplement lire votre fichier dans des mandrins et consolider ne fonctionnerait pas - vous auriez également besoin de partitionner votre analyse + workflow. Une autre alternative consiste à utiliser un outil en mémoire comme SQL.

6
Chris

Ce serait une pratique horrible, mais selon la façon dont vous devez traiter ces données, cela ne devrait pas être trop mauvais. Vous pouvez modifier votre mémoire maximale que R est autorisé à utiliser en appelant memory.limit(new)new un entier avec le nouveau memory.limit De R dans [ ~ # ~] mb [~ # ~] . Ce qui se passera, c'est lorsque vous frappez la contrainte matérielle, Windows commencera à paginer la mémoire sur le disque dur (pas la pire chose au monde, mais cela ralentira considérablement votre traitement).

Si vous exécutez ceci sur une version serveur de la pagination Windows, cela fonctionnera probablement (probablement) différemment de Windows 10. Je pense que cela devrait être plus rapide car le système d'exploitation du serveur devrait être optimisé pour ce genre de choses.

Essayez de commencer avec quelque chose du genre 2 Go (ou memory.limit(memory.limit()*2)) et si cela sort BEAUCOUP plus grand que cela, je dirais que le programme finira par être trop lent une fois qu'il est chargé en mémoire. À ce stade, je recommanderais d'en acheter plus RAM ou de trouver un moyen de traiter les pièces.

1
Adam

Vous pouvez essayer de diviser votre traitement sur la table. Au lieu d'opérer sur le tout, placez toute l'opération dans une boucle for et faites-le 16, 32, 64 ou autant de fois que vous le souhaitez. Toutes les valeurs dont vous avez besoin pour un calcul ultérieur peuvent être enregistrées. Ce n'est pas aussi rapide que d'autres articles, mais il reviendra certainement.

x = number_of_rows_in_file / CHUNK_SIZE
for (i in c(from = 1, to = x, by = 1)) {
    read.csv(con, nrows=CHUNK_SIZE,...)
}

J'espère que cela pourra aider.

0
Woody1193