views:

66

answers:

3

if I enter

print(cat(""))

i get

NULL

I want to use cat() to print out the progress of an R script, but I don't understand why it is returning "NULL" at the end of all of my concatenated strings, and more importantly, how to get ti to stop?

Thanks in advance.

+4  A: 

All your answers are in the documentation for ?cat. The portions that answer your specific question are:

Arguments:

fill: a logical or (positive) numeric controlling how the output is
      broken into successive lines.  If ‘FALSE’ (default), only
      newlines created explicitly by ‘"\n"’ are printed.
      Otherwise, the output is broken into lines with print width
      equal to the option ‘width’ if ‘fill’ is ‘TRUE’, or the value
      of ‘fill’ if this is numeric.  Non-positive ‘fill’ values
      are ignored, with a warning.

... and ...

Value:

 None (invisible ‘NULL’).

So you can't stop print(cat(...)) from returning NULL because that's what cat returns. And you need to explicitly add newlines like cat("foo\n").

Joshua Ulrich
Thanks for your answer - I did read the documentation before posting the question, but it was still not clear to me if there was a way to stop it from printing "NULL" or why it prints null or why the value is "None" even though it clearly returns the string provided... I guess some of my misunderstanding is more related to the theoretical than the practical.
David
Well, the documentation can be terse and `print` and `cat` may seem like they do similar things. But `cat` _does not_ return the string provided, it _prints_ it. Subtle, but important, difference. It's also good practice to glance at the documentation pages for the functions in the "See Also" section.
Joshua Ulrich
as mentioned in response to @gunkster, I don't think I can get line breaks with paste() ...
David
@David - you can get newlines if you insert them: `cat(paste("foo","fi","\n","\n","bar\n"))` or `writeLines(paste("foo","fi","\n","\n","bar\n"))` for example. Or see my answer for a way of using `strwrap()` and `writeLines()` to handle wrapping in a nice clean manner.
Gavin Simpson
@ucfagls: you don't need both `cat(paste(...))`. `cat` automatically separates arguments with a space... which saves some typing. ;-)
Joshua Ulrich
@Joshua, +1 cheers. Had never realised that!
Gavin Simpson
+3  A: 

I have had the exact same problem. In a nutshell, cat() is a little wonky under R. You didn't go into great detail about how you are trying to use cat() but I would suggest looking at paste().

?paste

I think it may be what you are looking for.

Choens
+1, especially for using "wonky"
Joshua Ulrich
I started with the paste() function, but I couldn't get it to add line breaks, and cat() was recommended to me when I asked the r-help list about line breaks : http://tolstoy.newcastle.edu.au/R/e12/help/10/10/0104.html
David
@David - a `paste()` version of the example in that R-help message would be: `writeLines(paste("msg1","msg2", sep = "\n"))`. A version using `cat()` is not so nice as you have to add an extra `"\n"`: `cat(paste("msg1","msg2","\n", sep = "\n"))` or `cat(paste("msg1","msg2", sep = "\n"), "\n")`
Gavin Simpson
+2  A: 

For this, I often use writeLines(), in combination with strwrap(), and paste() to combine say the loop value if I'm printing out info on the current iteration. strwrap() handles wrapping long lines as required, and writeLines() means I don't have to remember to add a "\n" on the end of my cat() calls.

> writeLines(strwrap("a very very very very long long long long long long long long string, that is too wide for the current pager width"))
a very very very very long long long long long long long long string,
that is too wide for the current pager width

Here is an example using it to print out an iteration indicator:

for(i in 1:1000) {
    if(isTRUE(all.equal(i %% 100, 0)))
        writeLines(strwrap(paste("Iteration", i)))
    ## do something
}

Gives:

> for(i in 1:1000) {
+     if(isTRUE(all.equal(i %% 100, 0)))
+         writeLines(strwrap(paste("Iteration", i)))
+     ## do something
+ }
Iteration 100
Iteration 200
Iteration 300
Iteration 400
Iteration 500
Iteration 600
Iteration 700
Iteration 800
Iteration 900
Iteration 1000
Gavin Simpson
Thanks for tip on strwrap, never heard of that. Apparently stop and warning uses similar approach, so manual breaks are not needed.
VitoshKa