Sink does not release file

17,781

Solution 1

You can use sink.number() to tell you how many diversions are already set and then call sink that many times. Putting it into a function you could have this

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

Solution 2

closeAllConnections()   # .........................

Solution 3

Based on @mnel's comment:

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

Should close all open sinks.

You may also encounter this problem when dealing with devices and plots, where the number of open devices isn't reported anywhere. For a more general case you could use this:

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 throws a warning not an error so I've modified the code so that it won't run forever, whoops!

Share:
17,781
I Like to Code
Author by

I Like to Code

Updated on June 25, 2022

Comments

  • I Like to Code
    I Like to Code about 2 years

    I know that the sink() function can be used to divert R output into a file, e.g.

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

    Is there a simple command to close all outstanding sinks?

    Below, I elaborate on my question.

    Suppose that my R-script opens a sink() in an R-script, but there is an error in the R-script which occurs before the script closes the sink(). I may run the R-script multiple times, trying to fix the error. Finally, I want to close all the sinks and print to the console. How do I do so?

    Finally, in the interest of concreteness, I provide a MWE to illustrate the problem I face.

    First, I write an R-script sink-closing.R which has an error in it.

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

    Next, I source the R-script multiple times, say 3 times by mistake as I try to find and fix the 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
    

    Now, suppose that I am debugging the R-script and want to print to the console. I can call sink() multiple times to close the earlier sinks. If I call it 3 times, then I can finally print to the console as before. But how do I know how many sinks I need to close?