tags:

views:

72

answers:

3

I am trying to use cat() as functions inside apply(). I can almost make R do what I want, but I'm getting some very confusing (to me) NULLS at the end of the return. Here is a silly example, to highlight what I'm getting.

val1 <- 1:10
val2 <- 25:34
values <- data.frame(val1, val2)
apply(values, 1, function(x) cat(x[1], x[2], fill=TRUE))

This "works" in that R accepts it and it runs, but I don't understand the results.

> apply(values, 1, function(x) cat(x[1], x[2], fill=TRUE))
1 25
2 26
3 27
4 28
5 29
6 30
7 31
8 32
9 33
10 34
NULL

But, I want to get:

> apply(values, 1, function(x) cat(x[1], x[2], fill=TRUE))
1 25
2 26
3 27
4 28
5 29
6 30
7 31
8 32
9 33
10 34

So, how do I remove that final NULL?

A: 

Do you really need the apply() to loop through your content?

> print(values, row.names=FALSE)
 val1 val2
    1   25
    2   26
    3   27
    4   28
    5   29
    6   30
    7   31
    8   32
    9   33
   10   34
Dirk Eddelbuettel
Do I need to use apply for my example? -- No. The example is just a simplified situation that highlights the problem I am having. I'm actually taking a bunch of numbers, from rows in a data.frame and providing something sensible for a report.
Choens
I fear you may be misunderstanding matters. In an `apply()` you do not use `cat()` but rather slice, dice, aggregate and ... return a value. Your failure to do so it at the root of the NULL display.
Dirk Eddelbuettel
I always thought the use of apply was to use a function on an object without using a loop. In this case, I want to "aggregate" by concatenating a bunch of strings. paste() appears to do what I thought cat() would do.
Choens
+1  A: 

The NULL is the R interpreter printing the value of the expression you typed in - the apply. You can either assign it somewhere:

junk = apply(values, 1, function(x) cat(x[1], x[2], fill=TRUE))

in which case it wont get printed, or wrap it in 'invisible':

invisible(apply(values, 1, function(x) cat(x[1], x[2], fill=TRUE)))

Note that its only when you run this interactively that each line is printed, if it's in a function you won't see it.

Spacedman
invisible() works. I also discovered that paste() works in the way I expected it to.
Choens
A: 

As Dirk pointed out this is not the way to print thing in R. Usually you would assign the result to a variable and then print it. No side effects, so to say.

Your problem stems from the cat functions, which prints to the terminal as a side effect, but returns NULL.

Try

a <- cat("blabla\n")  
a

If you really want to use apply for printing, there are two solutions. Wrap into invisible call

invisible(apply(values, 1, function(x) invisible(cat(x[1], x[2], fill=TRUE))))

or, just assign the result (NULL) to a temporary value

t <- apply(values, 1, function(x) invisible(cat(x[1], x[2], fill=TRUE)))
VitoshKa
Too many languages. Too little time. cat() didn't work the way I expected it to. paste() does. I don't technically want to print them, I just want to take a bunch of stuff and concatenate it together into a string.
Choens
My initial post should not have included print(). That was misleading on my part. I misunderstood the use of cat() and find that paste() appears to work as I want.
Choens