rrastersnowsnowfall

Suppress start-up messages when loading a library to snowfall cluster with sfLibrary


Example of the code I am running below.

library(snowfall)
library(snow)

sfInit(parallel = TRUE, cpus = 3)

sfLibrary(raster)
Library raster loaded.
Library raster loaded in cluster.

I want to stop sfLibrary from printing the messages. I can't figure out how. Help please...

Thanks.

EDIT 1: This does not work:

suppressMessages(sfLibrary(raster))

Library raster loaded.

EDIT 2: This does not work:

suppressPackageStartupMessages(sfLibrary(raster))

Library raster loaded.

Library raster loaded in cluster.


Solution

  • Use the Source.

    If you look at the source code for sfLibrary, specifically where it prints those messages, you'll see that is uses sfCat. Tracing that down (same file), it uses cat.

    I know of two ways to prevent cat from dumping onto the console: capture.output and sink.

    1. capture.output: "evaluates its arguments with the output being returned as a character string or sent to a file".

      cat("quux4\n")
      # quux4
      invisible(capture.output(cat("quux5\n")))
      cat("quux6\n")
      # quux6
      

      Since capture.output returns the captured output visibly as a character vector, wrapping it in invisible or storing the return value into a variable (that is ignored and/or removed) will prevent its output on the console.

    2. sink: "send R output to a file".

      cat("quux1\n")
      # quux1
      sink("ignore_me.txt")
      cat("quux2\n")
      sink(NULL) # remove the sink
      cat("quux3\n")
      # quux3
      

    I personally find the use of sink (in general) to be with some risks, especially in automation. One good example is that knitr uses sink when capturing the output for code chunks; nested calls to sink have issues. An astute reader will notice that capture.output uses sink, so neither is better in that regard.

    Looking again at the source (first link above),

    else {
      ## Load message in slave logs.
      sfCat( paste( "Library", .sfPars$package, "loaded.\n" ) )
    
      ## Message in masterlog.
      message( paste( "Library", .sfPars$package, "loaded in cluster.\n" ) )
    }
    

    you'll see that it also calls message, which is not caught by capture.output by default. You can always use capture.output(..., type="message"), but then you aren't capturing the cat output as well. So you are left with having to capture both types, either with nested capture.output or with suppressMessages.

    I suggest you can either use suppressMessages(invisible(capture.output(sfLibrary(raster)))) or write some helper function that does that for you.