Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Killing ghost NULL console outputs?

Tags:

r

edit: added full code

I made an S4 method for 'plot' that appears to be working, except it outputs some stray NULL to the console and I can't figure out where it's coming from. Here's the top level code:

print(plot(x = flux, y = 1, fastplot = TRUE, quietly = TRUE))

And the class:

flux <- setClass(
  # Set the class name
  "flux",
  slots = c(
     raw.data = "list",
     source.files = "character",
     data = "matrix",
     time = "POSIXct",
     datatype = "character",
     metadata = "data.frame"
  )
)

And the method:

setMethod("plot",
      signature(x = "flux"),
      function (x, y, ...) {
        CheckFluxObject(x)
        params <- LoadDefaults(flux = x)
        # Interpret 'plot' arguments
        par.restore <- par(no.readonly = TRUE)
        on.exit(expr = par(par.restore), add = TRUE)
        arguments <- list(...)
        if (!("fastplot" %in% names(arguments))) {
          fastplot <- FALSE
        } else {
          fastplot <- arguments$fastplot
          arguments$fastplot <- NULL
        }
        if (!("quietly" %in% names(arguments))) {
          quietly <- FALSE
        } else {
          quietly <- arguments$quietly
          arguments$quietly <- NULL
        }
        par(ask=!(fastplot))
        if (!("ylab" %in% arguments)) {
          ylab <- params["units"]
        } else {
          ylab <- arguments$ylab
          arguments$ylab <- NULL
        }
        # Pull relevant 'flux' class object data
        data <- slot(x, "data")
        if (missing("y")) {
          y <- 1:ncol(data)
        } else {
          stopifnot(
            is.integer(y),
            all(y %in% 1:ncol(data))
          )
        }
        # Bulk function execution
        if (quietly == FALSE) {
          message("Plotting data traces:")
        }
        plot.obj <- plot.new()
        print("NULL is in the 'for' loop...")
        for (i in y){
          main <- colnames(data)[i]
          plot.obj <- plot(slot(x, "time"), data[, i], main = main,
                           xlab = "Time", ylab = ylab, unlist(arguments))
          print(plot.obj)
        }
        print("but is it also here??")
        # Clean-up and exit
        if (quietly == FALSE) {
          message("Done plotting.")
        }
        if (length(y) == 1) {
          invisible(plot.obj)
        }
        print("or here??")
        invisible(NULL)
      }
)

The output for that is:

[1] "NULL is in the 'for' loop..."
NULL
[1] "but is it also here??"
[1] "or here??"
NULL

If I throw in another print("what about here??") after the invisible(NULL), then it does this:

[1] "NULL is in the 'for' loop..."
NULL
[1] "but is it also here??"
[1] "or here??"
[1] "what about here??"
[1] "what about here??"

Is there some behavior of the function return or print commands that I'm not anticipating? The CheckFluxObject function just checks to make sure all the slots are filled.

like image 894
brandonEm Avatar asked Jun 04 '26 16:06

brandonEm


1 Answers

I'll leave this here till a better answer pops up, if ever:

Apparently the print method for plot objects returns a NULL, and if you're trying to generate a plot within a function it seems like the best way to do that is using invisible(plot.object) or invisible(plot(x, y, ...)), NOT print.

I'm still not sure where the 2nd NULL is coming from...

edit: Found the second one! Just like the print(plot.obj) in the method itself, the print in the top-level code was throwing a NULL. Dropping all of the print commands killed all of the ghosts.

like image 175
brandonEm Avatar answered Jun 07 '26 23:06

brandonEm



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!