[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
>> NULL
>> 
>> # 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