una - El fregadero no libera el archivo
como destapar una tuberia (3)
Sé que la función sink()
se puede usar para desviar la salida R a un archivo, por ejemplo
sink(''sink-closing.txt'')
cat(''Hello world!'')
sink()
¿Hay un comando simple para cerrar todos los sumideros pendientes?
A continuación, elaboro mi pregunta.
Supongamos que mi script R abre un sink()
en un script R, pero hay un error en el script R que se produce antes de que el script cierre el sink()
. Puedo ejecutar el script R varias veces, tratando de corregir el error. Finalmente, quiero cerrar todos los lavabos e imprimir en la consola. ¿Cómo lo hago?
Finalmente, en aras de la concreción, proporciono un MWE para ilustrar el problema que enfrento.
En primer lugar, escribo un script R- sink-closing.R
que contiene un error.
sink(''sink-closing.txt'')
foo <- function() {
cat(sprintf(''Hello world! My name is %s/n'',
a.variable.that.does.not.exist))
}
foo()
sink()
A continuación, source
el script R varias veces, por ejemplo, 3 veces por error mientras trato de encontrar y corregir el error.
> 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
Ahora, supongamos que estoy depurando el script R y quiero imprimir en la consola. Puedo llamar a sink()
varias veces para cerrar los lavabos anteriores. Si lo llamo 3 veces, finalmente puedo imprimir en la consola como antes. ¿Pero cómo sé cuántos lavamanos necesito cerrar?
Basado en el comentario de @mnel:
sinkall <- function() {
i <- sink.number()
while (i > 0) {
sink()
i <- i - 1
}
}
Debe cerrar todos los lavamanos abiertos.
También puede encontrar este problema al tratar con dispositivos y gráficos, donde el número de dispositivos abiertos no se informa en ningún lugar. Para un caso más general puedes usar esto:
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.
EDITAR: sink
lanza una advertencia, no un error, así que modifiqué el código para que no se ejecute para siempre, ¡vaya!
Puede usar sink.number()
para decirle cuántos desvíos ya están configurados y luego llamar al sink
muchas veces. Poniéndolo en una función podría tener esto.
sink.reset <- function(){
for(i in seq_len(sink.number())){
sink(NULL)
}
}
closeAllConnections() # .........................