Aaron McDaid
Aaron McDaid

Reputation: 27183

`print(x)` not giving same output as `x`

At the R console, I expected that print(x) will always give the same output as x. I had always assumed that print is used by the console to actually do the printing for everything. But there is an extra NULL here from print:

library(data.table)

print(data.table(1)[0])
# Empty data.table (0 rows) of 1 col: V1
# NULL                                          # why is this 'NULL' printed here?

data.table(1)[0]
# Empty data.table (0 rows) of 1 col: V1
                                              # .. but no 'NULL' here?

This sample data is created by the data.table package, but I think the general question still applies even when not using data.table: what function/method is used to print return values at the console?

# R --vanilla  # R version 3.2.3

Upvotes: 6

Views: 184

Answers (3)

Aaron McDaid
Aaron McDaid

Reputation: 27183

Update :

The fix has just been merged in v1.10.5. Thanks to Michael Chirico.

After running:

install.packages('data.table', type = 'source',
                 repos = 'http://Rdatatable.github.io/data.table')

It will work as expected:

library(data.table)
# data.table 1.10.5 IN DEVELOPMENT built 2017-05-18 00:04:56 UTC; travis
#   The fastest way to learn (by data.table authors):  https://www.datacamp.com/courses/data-analysis-the-data-table-way
#   Documentation: ?data.table, example(data.table) and  browseVignettes("data.table")
#   Release notes, videos and slides: http://r-datatable.com

print(data.table(1)[0])
# Empty data.table (0 rows) of 1 col: V1

data.table(1)[0]
# Empty data.table (0 rows) of 1 col: V1

It might be because the print method for data.table is doing the wrong thing. Print methods are expected to return invisibly. But I suspect data.table:::print.data.table is returning visibly.

(Update: I've just submitted a bug report to data.table. Apologies to them if I've analyzed this incorrectly! )

From ?print:

‘print’ prints its argument and returns it invisibly (via ‘invisible(x)’).

Here is a tiny demo of what might be happening:

> x=list()
> class(x) <- 'X'
> print.X <- function(x) { print("I am printing"); return(1729); }
> x
[1] "I am printing"
> print(x)
[1] "I am printing"
[1] 1729

Note how typing x on its own simply prints the text, but no number. But typing print(x) causes the number to be printed also.

Then, if I arrange for this print method to return invisibly as follows:

> print.X <- function(x) { print("I am printing"); return(invisible(1729)); }

.. then print(x) gives the expected output

> print(x)
[1] "I am printing"

So, when you type x at the console, the console does call print on your behalf and ignores the return value from print (which may be visible). But if you type print(x), then the return value of print will be printed if it is visible.


The ?print documentation is a bit misleading I think. print methods are supposed to return their argument and are supposed to do so invisibly, but these rules are not enforced

Upvotes: 8

Morgan Ball
Morgan Ball

Reputation: 790

The print method called depends on the class of the object. As such there is a print.table, print.data.frame,print.factor,etc, each of these has a different function that determines what is printed.

Try this

x<-NULL
print.data.frame(x)
print.table(x)

Have a look at the functions

print.data.frame
print.table

You'll see what is returned is different depending on what S3 method of print is called and there are many ways to print.

The exact print you are calling depends on the class of your data.table object.

It also means you can create your own custom S3 method for printing by assigning a custom class to your object and creating a custom print function

class(object)<-"customclass"

print.customclass<-function(object,...){
   body of function
}

print(object)

Upvotes: 0

RHertel
RHertel

Reputation: 23818

This could be due to the return value of print.

From ?print:

‘print’ prints its argument and returns it invisibly (via ‘invisible(x)’).

So print has a return value, which happens to be NULL in this case. On the other hand, typing a variable in the console creates an output, but it does not return anything, and NULL is not displayed.

Upvotes: 3

Related Questions