Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

r

data.table

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
like image 406
Aaron McDaid Avatar asked Sep 22 '16 15:09

Aaron McDaid


2 Answers

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

like image 114
Aaron McDaid Avatar answered Sep 29 '22 03:09

Aaron McDaid


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.

like image 28
RHertel Avatar answered Sep 29 '22 02:09

RHertel