2010-11-02 33 views
2

J'ai un assez grand fichiers csv (1.2gb ... grand à la RAM de 2 Go sur un de mes ordinateurs). Pour chaque entrée dans une colonne, je voudrais ajouter "1C" afin que je puisse joindre/fusionner avec une autre table de données/db.Ajouter le suffixe à la colonne des entrées dans le fichier csv (ou dans la base de données SQLite)

Si le fichier n'était pas si grand, il serait facile d'utiliser read.csv pour importer à data puis utiliser data$symbol <- paste(data$symbol, "1C", sep=""). Mais maintenant, je reçois l'avertissement can't allocate vector of size x.

Est-ce une solution manuelle, comme scan(), ma seule option? (J'ai un peu peur de corrompre mes données) Merci!

Répondre

7

L'utilisation scan ne va pas vous aider si vous pouvez déjà obtenir vos données dans R.

Assurez-vous data a uniquement les colonnes dont vous avez besoin de fusionner, et exécuter gc() avant d'essayer votre commande paste (gc sera aide si vous êtes proche de la limite de votre limite de mémoire).

Si cela échoue, regardez certaines des solutions dans this thread.


MISE À JOUR:
Et si vous arrive d'utiliser une saveur de * nix, ou si vous avez RTools installé sur Windows, vous pouvez le faire avec gawk. Si vos données sont dans foo.csv et que vous souhaitez ajouter le "C1" à la deuxième colonne, cela va créer un nouveau fichier, bar.csv, avec "C1" ajouté à la deuxième colonne.

compy: /home/josh 
> cat foo.csv 
1,one,2,two 
3,three,4,four 
5,five,6,six 

compy: /home/josh 
> gawk -F "," '{OFS=","; $2=($2 "1C"); print}' <foo.csv> bar.csv 

compy: /home/josh 
> cat bar.csv 
1,one1C,2,two 
3,three1C,4,four 
5,five1C,6,six 

Ce sera probablement plus rapide que R et consommera une quantité négligeable de mémoire.

+0

@Joshua - Merci pour le lien! Mais après avoir récupéré tout le csv en RAM, je n'ai pas assez de mémoire pour me coller à lui-même (même avec une boucle élément par élément). Avant de faire la fusion, je sélectionne juste quelques colonnes de la base de données SQLite qui contient mes données, donc il n'y a pas de problème de mémoire. Je préférerais ajouter le "1C" avant d'ajouter le csv à la base de données pour que je puisse y faire un "join" au lieu d'un 'merge' dans R. Merci! –

+0

@Joshua - Je suis soit sur Ubuntu ou OSX, donc je vais essayer! –

+0

@Joshua - Merci! Exactement ce que je cherchais! Je suis toujours un nub à Linux, donc j'ai besoin de creuser plus dans ces outils de base! –

12

C'est un peu moche, mais vous pouvez lire le fichier, ligne par ligne et le mettre dans un autre fichier, ligne par ligne. De cette façon, vous ne liriez jamais le tout en mémoire. Ce ne serait pas différent de l'approche awk de Joshua, mais en utilisant R (et considérablement plus lent). L'exemple suivant était celui que j'avais bricolé pour enlever des signes de dollar et des signes de pourcentage d'un CSV. Vous pouvez modifier la logique au milieu pour faire la logique que vous voulez.

con <- file(inputFile, open = "r") 
con2 <- file(temporaryFile, open = "w") 

while (length(oneLine <- readLines(con, n = 1, warn = FALSE)) > 0) { 
    oneLine <- gsub("%", "", oneLine)  #strip out the percent signs 
    oneLine <- gsub("\\$", "", oneLine) #strip out the dollar signs 
    cat(oneLine, file = con2, sep = "\n") #spit the line back out 
    } 

close(con) 
close(con2) 
+0

@JD - Merci! J'aime aussi ça ... –

+0

Vous pouvez développer ceci en lisant des morceaux du fichier .csv et obtenir au moins une accélération. –

+0

@roman, oui, c'est un bon point. –

2

Lecture seule une colonne et ce que je suppose peut-être un chef de file identifiant unique pour fusionner plus tard les opérations en mémoire:

twocol <- read.table(file="what.csv", colClasses=("numeric", "character", rep("NULL", <number-of-remaining-columns>) , sep=",") 
twocol$V2 <- paste(twocol$V2, "1C", sep="") 
merge(twocol, otherdf, by.x="V1" , ....) 
+0

Merci! C'est semblable à ce que je faisais. Mon ordinateur de bureau est un peu vieux et ne pouvait pas gérer les deux premières lignes. La 'merge' était bien b/c je sous-entais dans SQLite avant la fusion, de sorte qu'il fusionnait des dataframes beaucoup plus petit que le fichier csv d'origine. –

0

Ajoute 1C à la deuxième colonne:

perl -F, -lane '$F[1] .= "1C"; print join ",", @F' file.csv

Ces options de ligne de commande sont utilisées:

  • boucle -n autour de chaque ligne du fichier d'entrée
  • -l avant le traitement supprime les nouvelles lignes, et les ajoute à la suite de retour
  • -a mode autosplit - lignes d'entrée séparées dans le tableau @F. Par défaut, scinder sur les espaces.
  • -e exécuter le code perl
  • -F modificateur de autosplit, dans ce cas se divise sur ,

@F est le tableau de mots dans chaque ligne, indexée en commençant par $F[0]
.= est le "append à" opérateur