2013-09-10 11 views
22

So che la funzione sink() può essere utilizzata per deviare l'output R in un file, ad es.Sink non rilascia file

sink('sink-closing.txt') 
cat('Hello world!') 
sink() 

C'è un semplice comando per chiudere tutti i lavelli in sospeso?

Di seguito, elaboro la mia domanda.

Supponiamo che il mio script R apre sink() in uno script R, ma c'è un errore nello script R che si verifica prima che lo script chiuda lo sink(). Posso eseguire lo script R più volte, cercando di correggere l'errore. Infine, voglio chiudere tutti i lavandini e stampare sulla console. Come faccio a farlo?

Infine, nell'interesse della concretezza, fornisco un MWE per illustrare il problema che affronto.

Per prima cosa, scrivo uno script R sink-closing.R che presenta un errore.

sink('sink-closing.txt') 

foo <- function() { 
    cat(sprintf('Hello world! My name is %s\n', 
       a.variable.that.does.not.exist)) 
} 

foo() 

sink() 

Successivamente, ho source le più volte R-script, dicono 3 volte per errore mentre cerco di trovare e correggere il bug.

> source('~/Dropbox/cookbook/r-cookbook/sink-closing.R') 
Error in sprintf("Hello world! My name is %s\n", a.variable.that.does.not.exist) : 
    object 'a.variable.that.does.not.exist' not found 

Ora, supponiamo di eseguire il debug dello script R e di voler stampare sulla console. Posso chiamare più volte sink() per chiudere i lavandini precedenti. Se lo chiamo 3 volte, posso finalmente stampare sulla console come prima. Ma come faccio a sapere quanti lavandini devo chiudere?

+1

È possibile utilizzare 'sink.number'? – mnel

risposta

28

È possibile utilizzare sink.number() per indicare quante deviazioni sono già impostate e quindi chiamare più volte sink. Mettere in una funzione si potrebbe avere questo

sink.reset <- function(){ 
    for(i in seq_len(sink.number())){ 
     sink(NULL) 
    } 
} 
+1

Un'altra WIN per leggere * tutti * la documentazione nel file di aiuto! :-) –

9

Basato su @ di mnel commento:

sinkall <- function() { 
    i <- sink.number() 
    while (i > 0) { 
    sink() 
    i <- i - 1 
    } 
} 

chiudere tutti i pozzi aperti.

È inoltre possibile riscontrare questo problema quando si tratta di dispositivi e grafici, in cui il numero di dispositivi aperti non viene segnalato da nessuna parte. Per un caso più generale si potrebbe usare questo:

stopWhenError <- function(FUN) { 
    tryCatch({ 
    while(TRUE) { 
     FUN() 
    } 
    }, warning = function(w) { 
    print("All finished!") 
    }, error = function(e) { 
    print("All finished!") 
    }) 
} 

stopWhenError(sink) # for sink. 
stopWhenError(dev.off) # close all open plotting devices. 

EDIT: sink getta un avvertimento non un errore così ho modificato il codice in modo che non funziona sempre, urla!

+0

Il suggerimento di usare 'tryCatch' è buono. –

23
closeAllConnections() # ......................... 
+4

... ora perché non dovrebbero collegarsi a quello o menzionarlo nel file di aiuto del sink? – Dason

+0

Non nascondevano esattamente il fatto che si trattava di un tipo di connessione. E c'è un link alla pagina 'connection'. Quindi è diventato un collegamento a due hop a "? ShowConnections". –

+7

@Dason - Probabilmente perché 'closeAllConnections' è uno strumento piuttosto grezzo da utilizzare per questo scopo, in quanto chiuderà qualsiasi altra connessione aperta, non solo i" sink "attualmente aperti. –

Problemi correlati