[R] Using str() in a function.

peter dalgaard pdalgd at gmail.com
Thu Jul 14 02:42:56 CEST 2011

On Jul 14, 2011, at 01:48 , David Winsemius wrote:

> On Jul 13, 2011, at 7:31 PM, andrewH wrote:
>> Thanks, David & Dennis, that is very helpful.
>> Let me state what I think I have learned, to see if I understand it
>> correctly. Then I have two remaining questions.
>> If a function contains more than one expression in its {}, it always returns
>> the value of the last evaluated expression in its definition, and only the
>> last object -- unless you previously use the return() function on an object
>> before the last expression, in which case, the value of that expression is
>> returned instead. And in either case, explicit or implicit return(), the
>> returned expression is evaluated, and returned, first -- before any other
>> expressions are evaluated, and any side effects also occur before any other
>> expressions are evaluated. (Though I am unsure in what order expressions are
>> evaluated if  objects in the returned expression are defined by other
>> expressions before it in the function.  The chain of evaluation -- and of
>> any side effects of that evaluation -- propogates backwards, maybe?).
> Not sure. There may be a console stack. I've never explored that question.

Andrew is being seriously confused. The return(ans) is of course executed when you get to it, returning the value of `ans` and terminating the function. Anything after that is _ignored_. There is no such thing as a "previous return()" affecting what str() does -- that would be like asking whether it is legal to  marry your widow's sister...

>> The print() command inside a function sends the object it contains to the
>> currently-defined printer, as a side-effect, without returning it.
> No. Read the first part of ?print.  `print`() _does_ return its argument,
> > b <- print("a")
> [1] "a"
> > b
> [1] "a"
> .... but it returns it in the environment where it is called so it will "evaporate" after the function completes. The cat() function behaves as you describe. I don't have a good handle on the order of the side-effect and the return of objects.
>> The
>> difference between return() and print() is that if something is returned, R
>> checks to see if the value of the function is assigned or otherwise nested
>> in a larger evaluated expression. Is so, a copy is moved to the assigned
>> object and the original is deleted. If not, it is printed to the current
>> device and then deleted. If you print() it, it does not check for assignment
>> or use before sending it to the printer and deleting it.
>> A lot of functions, e.g. str(), have as their explicit or implict return an
>> expression which does not create an object. In this case, the function
>> returns a NULL. If you do not want to print the NULL or other returned
>> object, you make the returned argument invisible().
>> But there are still things here I do not understand.  The function that
>> Dennis Murphy provided does print the str() output last instead of first,
>> because its final expression is invisible() rather than str(). But, it still
>> prints out (and returns - I checked) a NULL.  e.g.
>> GG<-c(1:5)
>> testXa <- function(X) {
>>    print(summary(X))
>>    print(str(X))
>>    invisible()     # returns nothing
>> }
>>> testXa(GG)
>>  Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
>>     1       2       3       3       4       5
>> int [1:5] 1 2 3 4 5
>> # Here is my latest version, of the function, which does exactly what I
>> want:
>> testXf <- function(X) {
>>    print("Summary:"); print(summary(X))
>>    print("Structure:");  invisible(str(X))
>> }
>> testXf(GG)
>> [1] "Summary:"
>>  Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
>>     1       2       3       3       4       5
>> [1] "Structure:"
>> int [1:5] 1 2 3 4 5
>> So, two questions:
>> 1. In Dennis's function, the str() results are printed last because they are
>> no longer returned, as invisible() is now the last expression. But why does
>> his function still print a visible NULL?
> Because NULL was what was returned by str()

... and printed by the enclosing print(). The printing by str() itself has nothing to do with whether it was returned. 

>> 2. My function, above, makes the NULL value returned by str() invisible. But
>> invisible(str(X)) is the last expression evaluated, so why does the
>> side-effect printing of str() results happen last instead of first?
> That I do not know. I do know that there is console buffering and that some people need to flush.console() to get output before a function completes is computations.

str() prints last because the side effect of the preceding print()s causes them to print before str() is ever called. 

Peter Dalgaard
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com

More information about the R-help mailing list