2013-01-08 11 views
7

Sto provando a scrivere un frame di dati in un file gzip ma avendo problemi.scrivere un file gzip dal frame di dati

Ecco il mio esempio di codice:

df1 <- data.frame(id = seq(1,10,1), var1 = runif(10), var2 = runif(10)) 

gz1 <- gzfile("df1.gz","w") 
writeLines(df1) 

Errore in writeLines(df1): non valido 'testo' argomento

Qualche suggerimento?

EDIT: un esempio di linea del vettore carattere sto cercando di scrivere è:

0 | var1:1.5 var2:.55 var7:1250 

L'etichetta classe/y-variabile viene separato dalle x-vars da un "|" e variabile i nomi sono separati dai valori con ":" e gli spazi tra le variabili.

EDIT2: Mi scuso per la formulazione/format della questione, ma ecco i risultati: Vecchio metodo:

system.time(write(out1, file="out1.txt")) 
# user system elapsed 
# 9.772 17.205 86.860 

Nuovo metodo:

writeGzFile <- function(){ 
    gz1 = gzfile("df1.gz","w"); 
    write(out1, gz1); 
    close(gz1) 
} 

system.time(writeGzFile()) 
# user system elapsed 
# 2.312 0.000 2.478 

Grazie a tutti molto per aiutandomi a capirlo.

+0

Come viene spesso chiesto il rhelp: "Quale problema stai cercando di risolvere". –

+0

Suggerimento: la risposta al commento @DWin non è "Come si scrive un frame di dati in un file gzip?" – Spacedman

+0

La domanda più lunga sarebbe "È più veloce scrivere un file .txt o un file .gz da R?" – screechOwl

risposta

16

writeLines prevede un elenco di stringhe. Il modo più semplice per scrivere questo in un file gzip sarebbe

df1 <- data.frame(id = seq(1,10,1), var1 = runif(10), var2 = runif(10)) 
gz1 <- gzfile("df1.gz", "w") 
write.csv(df1, gz1) 
close(gz1) 

Questo scriverà come csv zippato. Vedi anche write.table e write.csv2 per modi alternativi di scrivere il file.

EDIT: Sulla base dei aggiornamenti del post su formato desiderato, ho fatto la seguente helper (rapidamente gettati insieme, probabilmente ammette tonnellate di semplificazione):

function(df) { 
    rowCount <- nrow(df) 
    dfNames <- names(df) 
    dfNamesIndex <- length(dfNames) 
    sapply(1:rowCount, function(rowIndex) { 
     paste(rowIndex, '|', 
      paste(sapply(1:dfNamesIndex, function(element) { 
       c(dfNames[element], ':', df[rowIndex, element]) 
      }), collapse=' ') 
     ) 
    }) 
} 

Così il risultato è simile

a <- data.frame(x=1:10,y=rnorm(10)) 
writeLines(myser(a)) 
# 1 | x : 1 y : -0.231340933021948 
# 2 | x : 2 y : 0.896777389870928 
# 3 | x : 3 y : -0.434875004781075 
# 4 | x : 4 y : -0.0269824962632977 
# 5 | x : 5 y : 0.67654540494899 
# 6 | x : 6 y : -1.96965253674725 
# 7 | x : 7 y : 0.0863177759402661 
# 8 | x : 8 y : -0.130116466571162 
# 9 | x : 9 y : 0.418337557610229 
# 10 | x : 10 y : -1.22890714891874 

E tutto ciò che è necessario è passare il file gz per scrivereLine per ottenere l'output desiderato.

+0

Per le persone che utilizzano VW, vedere anche questa risposta per le opzioni più veloci di 'writeLines': http://stackoverflow.com/a/41215573/3576984 – MichaelChirico

4

Per scrivere qualcosa in un file gzip è necessario "serializzarlo" in testo. Per gli oggetti R si può avere una pugnalata a che, utilizzando dput:

gz1 = gzfile("df1.gz","w") 
dput(df1, gz1) 
close(gz1) 

Tuttavia hai appena scritto una rappresentazione testuale del telaio dati nel file. Questo sarà probabilmente meno efficiente dell'uso di save(df1,file="df1.RData") per salvarlo in un file di dati R nativo. Chiediti: perché lo sto salvando come file .gz?

In un test rapido con alcuni numeri casuali, il file gz era 54k, il.file di RDATA era 34k

+0

Grazie. Il motivo per cui sto scrivendo su .gz è che l'output è un file di input per un altro programma che legge i file .gz. In altre parole sta lasciando l'ecosistema R. Altrimenti userei .RData. – screechOwl

+0

Quindi basta gzip il file .RData? No, non funzionerà, perché gzip è una compressione che non ti dice nulla sul formato dei dati nel file quando non è compresso. È un file CSV con gzip, un file NetCDF con gzip, un file RData con gzip? Non ci hai detto. – Spacedman

+0

Spiacente, lo sto usando come un file di input per un programma chiamato vowpal wabbit. Ha delimitanti strani usando '|', ':' e ''. – screechOwl

Problemi correlati