2013-02-08 11 views
5

Ich habe eine Funktion erstellt, die in lesen genannt wird und dann eine data.table zurück:Tricks zur Vermeidung doppelter Speicherzuweisung beim Zurückgeben von data.table oder data.frame in R?

read.in.data <- function(filename) 
{ 
    library(data.table) 
    data.holder<-read.table(filename, skip=1) 
    return(data.table(data.holder)) 
} 

Ich habe aus der Beobachtung meiner RAM als Funktionsabläufe bemerkt, dass R in 2 Schritten, dies zu verarbeiten scheint (oder zumindest ist das meine beste Schätzung für das, was vor sich geht). Wenn ich beispielsweise eine 1,5-GB-Datei (15 Spalten mit insgesamt 136 Zeichen pro Zeile) lade, scheint R 1) die Daten einzulesen und 1,5 GB RAM zu verwenden und dann 2) weitere 1,5 GB RAM für die Rückkehr.

Gibt es einige Tricks, um eine Funktion zu erstellen, um eine data.table (oder data.frame für diese Angelegenheit) zu erstellen und die data.table zurückzugeben, ohne doppelte Arbeitsspeicher zu benötigen? Oder muss ich die gesamte Verarbeitung für die data.table innerhalb der Funktion ausführen, in der die Tabelle erstellt wird?

Beobachtungen: Wenn ich diesen Code zweimal hintereinander ausführen, wird der Speicher nicht gelöscht; Da ich nur 8 GB RAM habe, schlägt die Funktion fehl. Überspringe ich den Schritt des Speicherns der "read.table" in einer Variablen (wie unten gezeigt), bekomme ich keinen Vorteil. Ich würde das auf keinen Fall machen wollen, da ich gerne die data.table bereinigen möchte, bevor ich sie zurückschicke. Eine Behebung meines Problems würde es mir auch ermöglichen, größere Dateien zu verarbeiten, ohne den Arbeitsspeicher zu verlieren.

library(data.table) 
read.in.data <- function(filename) 
{ 
    data.holder <- read.table(filename, skip=1) 
    dt <- data.table(data.holder[[1]]) 
    names(dt) <- names(data.holder)[1] 
    data.holder[[1]] <- NULL 

    for(n in names(data.holder)) { 
    dt[, `:=`(n, data.holder[[n]]) ] 
    data.holder[[n]] <- NULL 
    } 
    return(dt) 
} 

(ungetestet)

Es wird nicht schneller sein,:

short.read.trk <- function(fntrk) 
{ 
    library(data.table) 
    return(data.table(read.table(fntrk, skip=1))) 
} 
+4

Ich fühle deinen Schmerz. Versuchen Sie fread() in v1.8.7. Es erstellt direkt eine data.table, so dass der (kopierende) data.table() -Wrapper vermieden werden kann, und außerdem effizienter als die read.table (sogar mit allen bekannten Tricks). –

+0

Danke, ich werde versuchen, fread(), sobald 1.8.7 hat einen Build auf R-Schmiede (zZ listet als "nicht bauen"). – Docuemada

+0

Hoppla - danke, dass du mich informiert hast - ich schaue mal ... –

Antwort

2

Wenn Speichereinsparungen meistens ist, was Sie wollen, können Sie es eine Spalte zu einer Zeit umwandeln könnte in der Tat ist es wahrscheinlich langsamer. Aber es sollte weniger Speicherverschwendung sein.

+0

Danke, das ist ein interessanter Ansatz. Ich werde es implementieren, wenn ich am Montag Zugriff auf den Datensatz habe, und diesen Kommentar mit den Ergebnissen bearbeiten. – Docuemada

+1

+1 Interessanter Ansatz. Das könnte wirklich sehr schnell sein. Andere Ansätze zum Testen sind 'as.data.table()' anstelle von 'data.table()' und (nur für Experten): 'setattr (Daten," Klasse ", c (" data.frame "," data. Tabelle "))'. –

+0

+1 Ich mag den Ansatz, "NULL" zu verwenden, um den Speicher niedrig zu halten. Ich habe es versucht, wenn ich Tische zusammenbinde. Zum Beispiel versuchte ich es mit etwas wie dt <-do.call ("rbind", Liste (dt, dt.holder)), gefolgt von dt.holder <-NULL. Der obige Ansatz änderte jedoch nicht den gesamten verwendeten RAM. Wenn ich mein ursprüngliches Skript mit dem vorgeschlagenen Skript verglichen habe, war die RAM-Nutzung die gleiche. – Docuemada

Verwandte Themen