22

Is there a way to print or display the value of a variable while inside a function, as opposed to printing the value outside the function after the function has been called?

I am virtually certain there is and thought the code was called reveal or something similar, but I cannot recall the correct term.

my.function <- function(x) {

  y <- x^2
 #  reveal(y)
 #  display(y)

 # desired result is to print or display here:
 # [1] 16

  cat(y)
  print(y)
  return(y)  
}

x <- 4

my.function(x)
#16[1] 16
#[1] 16

cat(y), print(y) and return(y) all print outside the function. Thank you for any advice.

EDIT

I found a similar question here:

https://stat.ethz.ch/pipermail/r-help/2002-November/027348.html

The response to that question from Peter Dalgaard was to uncheck an option called buffered output under the Misc tab. However, that does not seem to be working in my case. Perhaps the questions are unrelated.

10
  • 1
    I am confused. What do you mean, they print outside the function? What you are saying is impossible, because 4 has not even been passed to the function... Commented Mar 30, 2014 at 3:59
  • The number 16 appears after the }. Commented Mar 30, 2014 at 4:00
  • Of course it does! There is no way to pass 4 to the function before defining it. Commented Mar 30, 2014 at 4:01
  • 2
    Take a look at ?debug, which will step through the function and allow you to inspect objects at different points in the function's execution. To give it a go, try debug(my.function); my.function(4), and then enter y at any point after its definition and before the call to return. Commented Mar 30, 2014 at 4:16
  • 2
    You can also try message which does a good job of "printing from within functions" -- I've used it for debugging with parallel operations, too. Commented Mar 30, 2014 at 6:14

3 Answers 3

32

I like to use the message function to print for debugging, since it seems to reach the console from whatever dark depths it might be emitting from. For example:

somefunc <- function(x) {
       message(paste('ok made it this far with x=',x))
       # some stuff to debug
       message(paste('ok made it this far with x^2=',x^2))
       # some more stuff to debug
       message(paste('ok made it to the end of the function with x^3=',x^3))
}
Sign up to request clarification or add additional context in comments.

1 Comment

Nice function! I had a print() wrapped around a prettyNum() that was returning 0.0001000000000001 in the console. Changing print() to message() gave me the 0.0001 I wanted. print() seems to ignore prettyNum() in some cases, not sure what it's all about...
21

You can put print() calls (or cat() calls for that matter) inside the function and if the execution reaches that point, then an output will be produced on the console even if an error later occurs later in execution. (It's possible that flush.console() will be needed if the IDE you are using is set for "buffered output".)

 > myf <- function(x){ print(x); y <- x^2; print(y); error() }
> myf(4)
[1] 4
[1] 16
Error in myf(4) : could not find function "error"

It's probably more elegant to use the browser() function as the debugging route. You set up its operation by changing options():

> options(error=recover)
> myf(4)
[1] 4
[1] 16
Error in myf(4) : could not find function "error"

Enter a frame number, or 0 to exit   

1: myf(4)

Selection: 1
Called from: top level 
Browse[1]> x
[1] 4
Browse[1]> y
[1] 16
Browse[1]>    # hit a <return> to exit the browser 

Enter a frame number, or 0 to exit   

1: myf(4)

Selection: 0   # returns you to the console

1 Comment

Very nice. Clear examples of the browser function and the debug function are valuable. I would upvote twice if I could.
8

When I asked this question I might have been thinking of the show function which allows you to see the values of a variable without including that variable in the return statement. Although, the show command prints values outside of the function.

my.function <- function(x) {
     y <- x^2
     show(y)
     show(length(y))
     z <- y + x
     return(z)
}

x <- 1:10

my.function(x)

 # [1]   1   4   9  16  25  36  49  64  81 100
 # [1] 10
 # [1]   2   6  12  20  30  42  56  72  90 110

EDIT: March 19, 2021

Another way to view results from inside a function is to send an object to a global variable. This might be helpful in locating errors inside a function.

my.function <- function(x) {
     y <- x^2
     y <<- y
     z <- y + x
     z <<- z
     return(z)
}
y
#[1]   1   4   9  16  25  36  49  64  81 100
z
#[1]   2   6  12  20  30  42  56  72  90 110
x <- 1:10
my.function(x)
#[1]   2   6  12  20  30  42  56  72  90 110

2 Comments

The show function is not necessarily going to return a value. It will display whatever is defined as the result of the show function for S4 objects. For S4 objects of a class without a specific show method defined, it calls showDefault and will output a message about its class and then iterate over the slots. For ordinary objects of a basic or S3 class, it just calls print. I suppose it is safer in the sense of not choking if the object is a list (as cat would).
I didn't think that <<- necessarily assigns in the global environment. Rather I believe it gets assigned in the calling environment, which might or might not be the global environment. However when I check that against the help page I find it "cause[s] a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment. "

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.