suppress messages displayed by "print" instead of "message" or "warning" in R - r

Many R packages I work with involve functions that give all their messages and warnings through commands to print() calls rather than commands to message() or warning(). I'd like to be able to silence these functions progress indicators, etc, but the standard supressWarnings() or supressMessages doesn't do it. Is there a way I can just suppressPrint?
For example:
silly_developer_function <- function(x){
print("Thanks for using my function!!")
if(is(x, "numeric"))
print("warning, x should be a character")
x
}
I'd like to have a simple function suppressPrint() that I could wrap around a call to this function that would suppress the warning and useless messages (but still print the return value).

Well, those packages are buggy to start with. Use of print() for anything but side-effect in print implementations is a serious mistake.
That said, you can simply use capture.output() to collect the output from such code instead of printing it. So for the above it would be
capture.output(x <- silly_developer_function(...))
print(x)

Another hacky way is to override the default print function. It will affect some functionality, such as printing the body of functions, but objects with their own print methods still get returned as usual.
print <- function(...) {}
> silly_developer_function("a")
[1] "a"
> silly_developer_function(1)
[1] 1

Related

How to hide warning messages from self-written function in R?

I am running an ordinary R script in which I have a self-written function. The function makes use of rm() which often produces warnings I do not want to appear in console output. Any of these solutions:
hiding warnings from rm usage from this particular self-written function,
hiding warnings from all usages of rm (globally for an R session)
would satisfy me.
foo.function <- function(){
rm(foo.object)
print("foo")
}
foo.function()
# [1] "foo"
# Warning message:
# In rm(foo.object) : object 'foo.object' not found
For these particular case of object not found, you may use something like this:
if(exists("foo.object")) rm(foo.object)
If you want to hide other warnings as well, just use suppressWarnings().

Suppress all output from the compute.es functions

I'm using the compute.es package (http://cran.r-project.org/web/packages/compute.es/compute.es.pdf) to compute effect sizes. Now, when using one of the functions from this package, the result is printed even though you assign it to a vector, and I would like to surpress this.
For example,
library("compute.es")
mes(5,5,5,5,5,5,level=95,dig=2,id=NULL,data=NULL)
prints a lot of information. By using capture.output like so
library("compute.es")
capture.output(mes(5,5,5,5,5,5,level=95,dig=2,id=NULL,data=NULL))
a lot of it gets suppressed, but not all. I've had no luck with sink() (which breaks the whole function) or invisible() either.
How can I suppress all printed information from this function?
Version 0.2-4 of the compute.es package has a 'verbose' argument, so e.g.:
require(compute.es) # VERSION => 0.2-4
des(.3, 30, 30, verbose=FALSE) # WILL SUPPRESS PRINTING TO CONSOLE
This function is really bi-polar. Some things are printed using cat, others using message. In addition to what you've tried you can also try suppressMessages.
This worked for me.
x <- capture.output(suppressMessages(mes(5,5,5,5,5,5,level=95,dig=2,id=NULL,data=NULL)))
Alternatively, you can hack the function (use the source!) and cut out all the cat and message statements. Another way would be to add another argument to the function (like verbose) and turn on/off messages by putting them inside an if clause. E.g.
if (!is.null(data)) {
if (verbose) {
cat("\n")
message(" EFFECT SIZE CALCULATION (FOR VECTOR INPUT)")
cat("\n")
}
...

Problems with reassignInPackage

I am trying to understand the way the YourCast R package works and make it work with my data.
For example, if a function produces errors, I
get the source code of that function using YourCast:::bad.fn
add outputs of critical
values at critical stages
use reassignInPackage(name="original.fn", package="YourCast", value="my.fn")
Once I find the cause of the error, I fix it in the function and reassign it in the package.
However, for some strange reason this does not work for non-hidden functions.
For example:
install.packages("YourCast")
Library(YourCast)
YourCast:::check.depvar
This will print the hidden function check.depvar. One line if (all(ix == 1:3)) will produce an error message if any of the x is missing.
Thus, I change the whole function to the following and replace the original formula:
mzuba.check.depvar <- function(formula)
{
return (grepl("log[(]",as.character(formula)[2]))
}
reassignInPackage("check.depvar",
pkgName="YourCast",
mzuba.check.depvar)
rm(mzuba.check.depvar)
Now YourCast:::check.depvar will print my version of that function, and everything is fine.
However
YourCast::yourcast or YourCast:::yourcast or simply yourcast will print the non-hidden function yourcast. Suppose I want to change that function as well.
reassignInPackage(name="yourcast",
pkgName="YourCast",
value=test)
Now, YourCast::yourcast and YourCast:::yourcast will print the new, modified version but yourcast still gives the old version!
That might not a problem if I could simply call YourCast::yourcast instead of yourcast, but that produces some kind of error that I can't trace back because suddenly R-Studio does not print error messages at all anymore!, although it still does something if it is capable to:
> Uagh! do something!
> 1 + 1
[1] 2
> Why no error msg?
>
Restarting the R-session will solve the error-msg problem, though.
So my question is: How do I reassign non-hidden functions in packages?
Furthermore (this would faciliate testing a lot), is there a way to make all hidden functions available without using the ::: operator? I.e., How to export all functions from a package?

If (something got printed) x=false, how to do this in R?

So I am using a function in R that uses compiled fortran code. While using this function, lsoda, in package deSolve. I get messages printed to the screen like
DLSODA- At current T (=R1), MXSTEP (=I1) steps
taken on this call before reaching TOUT
In above message, I =
[1] 5000
In above message, R =
[1] 21.31629
The problem is that the above is not a "warning" or an "error"; the is.null(warnings()) evaluates to TRUE after I see this message. If it were a warning I could just write x = is.null(warnings()) and that would do the trick. I could use tryCatch for errors, but what about messages that are neither errors or warnings?
The reason I ask, is that this function is called in a while loop, inside a for loop. I want the while loop to break if this message gets printed, and then for the outer for loop to move onto the next iteration. Normally you'd use tryCatch to do something like this but because there is no error, I have no idea how to do this
You can redirect the output and then check whether lsoda printed something:
out <- capture.output(lsoda(...))
if(length(grep("In above message", out))!=0) {
# error
}
We basically check whether any of the lines printed by lsoda contains the string In above message. If you need to use the result from lsoda, you can also run like this:
out <- capture.output(result <- lsoda(...))
As suggested, you can also use grepl:
if(any(grepl("In above message", out))) {
# error
}

Is there a sensible way to do something like docstrings in R?

This is not just a coding style question. If you know python (and I think also Ruby has something like this), you can have a docstring in a function, such that you can readily get that string by issuing a "help" command. e.g.:
def something(t=None):
'''Do something, perhaps to t
t : a thing
You may not want to do this
'''
if t is not None:
return t ** 2
else:
return 'Or maybe not'
Then help(something) returns the following:
Help on function something in module __main__:
something(t=None)
Do something, perhaps to t
t : a thing
You may not want to do this
The way things work in R, you can get the full text of the defined code snippet, so you could see comments (including those at the beginning of the function), but that can be a lot of scrolling and visual filtering. Is there any better way?
I recently wrote a package to do just this task. The docstring package allows one to write their documentation as roxygen style comments within the function they are documenting. For example one could do
square <- function(x){
#' Square a number
return(x^2)
}
and then to view the documentation either call the docstring function
docstring(square)
or use the built in ? support and do
?square
The comments can either be a single chunk like shown above or fully roxygen style to take advantage of some of the keywords provided
square <- function(x){
#' Square a number
#'
#' Calculates the square of the input
#'
#' #param x the input to be squared
return(x^2)
}
This is on CRAN now: https://cran.r-project.org/package=docstring so you can just install using
install.packages("docstring")
or if you want the latest development version you can install from github:
library(devtools)
install_github("dasonk/docstring")
You can add any attributes you like to R objects, including function. So something like
describe <- function(obj) attr(obj, "help")
foo <- function(t=NULL) ifelse(!is.null(t), t^2, "Or maybe not")
attr(foo, "help") <- "Here is the help message"
produces more or less the desired output
> foo(2)
[1] 4
> foo()
[1] "Or maybe not"
> describe(foo)
[1] "Here is the help message"
Sort-of -- look at the roxygen2 package on CRAN (vignette here). You write a declarative header, and among other things a help page is created for you when you 'roxygen-ize' your sources.
It may not be the easiest package to use, see here on SO for questions pertaining to it as well as its mailing list. But it probably is the closest match.
RStudio helps you to create documentation quite easily.
See their documentation for more information.
The new reference class system has something very similar to docstrings for documenting methods of a class. Here is an example:
Something <- setRefClass("Something",
methods=list(
something=function(t=NULL) {
"Do something, perhaps to t
t : a thing
You may not want to do this
"
if(!is.null(t))
t^2
else
"Or maybe not"
}
))
a <- Something$new()
a$something(2)
a$something()
Something$help("something") ## to see help page
I had another idea as I'm finally wrapping my head around the fact that "R is a (very poor) LISP". Specifically, you can get access to the source code (usually) using the deparse command. So, this function would be a start towards defining your own custom source-code parsing help function:
docstr <- function(my.fun) {
# Comments are not retained
# So, we can put extra stuff here we don't want
# our docstr users to see
'This is a docstring that will be printed with extra whitespace and quotes'
orig.code.ish <- deparse(my.fun)
print(orig.code.ish[3])
}
docstr(docstr)
The above illustrates that deparse really does deparse, and is different from what you'd print at the REPL prompt if you typed docstr: quotes are changed to (default) double-quotes, opening curly brace gets moved to the second line, and blank lines (including comments) are removed. This actually helps a lot if you want to design a robust function. Would be trivial to look for e.g., opening and closing quotes down through the first line that doesn't start with a quote.
Another way to do it would be to get the list of call objects that make up the body list with body(docstr). The string would be in body(docstr)[[2]]. I have to admit that I'm a bit out of my depth here, as I don't fully understand the return value of body, and don't know where to find documentation! In particular, note that body(docstr)[2] returns an object of type and mode 'call'.
This latter approach seems much more LISPy. I'd love to hear other's thoughts on the general idea, or have pointers to actual language reference materials for this!

Resources