2014-06-30 1 views
5

Sto cercando di eseguire un semplice programma per estrarre tabelle dal codice html. Tuttavia, sembra esserci un problema di memoria con readHTMLTable nel pacchetto XML. C'è un modo per aggirare questo facilmente. Come in qualche modo specificando una memoria speciale per questo comando e quindi liberandolo manualmente.Soluzione alternativa alla perdita di memoria R con pacchetto XML

Ho provato a mettere questo in una funzione e ho provato a utilizzare gc() e diverse versioni di R e questo pacchetto e nulla sembra funzionare. Inizio a disperarmi.

Codice di esempio. Come eseguirlo senza esplodere la dimensione della memoria?

library(XML) 
a = readLines("http://en.wikipedia.org/wiki/2014_FIFA_World_Cup") 
while(TRUE) { 
    b = readHTMLTable(a) 
    #do something with b 
} 

Edit: Qualcosa di simile avviene ancora tutta la mia memoria:

library(XML) 
a = readLines("http://en.wikipedia.org/wiki/2014_FIFA_World_Cup") 
f <- function(x) { 
    b = readHTMLTable(x) 
    rm(x) 
    gc() 
    return(b) 
} 

for(i in 1:100) { 
    d = f(a) 
    rm(d) 
    gc() 
} 
rm(list=ls()) 
gc() 

Sto usando vincere 7 e provato con 32bit e 64bit.

+0

Ho avuto seri problemi di memoria usando il pacchetto 'XML' su Windows. La mia soluzione è di riavviare periodicamente R (salvando i dati in CSV). Ho mandato un'email all'autore del pacchetto. Ci siamo scambiati alcune e-mail, ma in pratica ha detto che non può/non esegue il debug di Windows. – rrs

+0

Ok. Riavviare R funziona ma non è un lavoro manuale così carino da fare ogni 5 minuti. Immagino che la sola strada da percorrere sia passare a Linux. XML è un pacchetto molto interessante ma purtroppo distrutto da questi problemi di memoria. – Pekka

risposta

0

Ho avuto un sacco di problemi con perdite di memoria nel pakackage XML anche (sotto Windows e Linux), ma il modo in cui l'ho risolto alla fine è stato rimuovere l'oggetto alla fine di ogni passaggio di elaborazione, cioè aggiungere un rm (b) e un gc() alla fine di ogni iterazione. Fammi sapere se questo funziona anche per te.

+0

Non aiuta all'interno del ciclo né dopo il ciclo. – Pekka

+0

Bene quello che ho fatto è stato mettere l'elaborazione XML in una funzione XMLproc che ha restituito l'output, e nella funzione in cui stavo chiamando XMLproc ho aggiunto rm (out) e gc(). Potresti controllare se questo funziona per te? –

+0

Non ho ottenuto nulla di simile a questo lavoro. Ho aggiunto qualcosa di ciò che ho provato nella domanda originale. – Pekka

0

Lo stesso problema qui, anche non facendo altro che leggere nel documento con doc <- xmlParse(...); root <- xmlRoot(doc), la memoria allocata a doc non viene mai rilasciata all'O/S (come monitorato nel Task Manager di Windows).

Una pazza idea che si possa provare è di utilizzare system("Rscript ...") per eseguire l'analisi XML in una sessione R separata, salvando l'oggetto R analizzato in un file, che viene quindi letto nella sessione R principale. Hacky, ma almeno garantirebbe che qualsiasi memoria venga inghiottita dall'analisi XML, viene rilasciata quando la sessione Rscript termina e non influisce sul processo principale!

+0

Ho risolto questo spostandomi in Python e BeautifulSoup molto tempo fa :) Ad ogni modo, apprezza il tuo aiuto. Proverò presto la tua soluzione. – Pekka

+0

Vedere anche la risposta che ho posto su http://stackoverflow.com/questions/23696391/memory-leak-when-using-package-xml-on-windows/ re utilizzando invece la nuova libreria xml2 (l'ho postata come risposta anche a questa domanda, ma qualcuno l'ha cancellato). –

0

A partire da XML 3.98-1.4 e R 3.1 su Win7, questo problema può essere risolto perfettamente utilizzando la funzione free(). Ma non funziona con readHTMLTable(). Il seguente codice funziona perfettamente.

library(XML) 
a = readLines("http://en.wikipedia.org/wiki/2014_FIFA_World_Cup") 
while(TRUE){ 
    b = xmlParse(paste(a, collapse = "")) 
    #do something with b 
    free(b) 
} 

Il pacchetto xml2 ha problemi simili e la memoria può essere rilasciato utilizzando la funzione remove_xml() seguito da gc().