3

Question

How do I suppress := from printing to the console after extending data.table into a new class and writing a custom print method?

Example

In this example I'm extending data.table by adding extended.data.table to the class.

I'm also adding an attribute to one of the columns that I want to print in a specific format.

library(data.table)
## create data.table
dt_extend <- data.table(id = 1:5,
                        val = letters[1:5])

## create two attributes:
## - extend.data.table  onto data.table
## - extended           onto the 'val' column
setattr(dt_extend, 'class', c('extended.data.table', class(dt_extend)))
setattr(dt_extend[['val']], 'extended', 'print')

## Method to format the 'extended' column when printed
print.extended.data.table <- function(edt){

    ## find the 'extended' column
    cols <- sapply(edt, function(x) names(attributes(x)))
    cols <- names(which(cols == "extended"))

    ## more than one column can have the 'extended' attribute
    edt <- edt[,  
            lapply(.SD, function(y) { paste0("formatted: ", y) } ), 
            by = setdiff(names(edt), cols), 
            .SDcols = cols
            ]

    ## now call data.table print
    NextMethod()
}

## these all print as expected
dt_extend
dt_extend[1, .(val)]

str(dt_extend)
# Classes ‘extended.data.table’, ‘data.table’ and 'data.frame': 5 obs. of  2 variables:
#   $ id : int  1 2 3 4 5
# $ val: atomic  a b c d ...
# ..- attr(*, "extended")= chr "print"
# - attr(*, ".internal.selfref")=<externalptr>

Updating by-reference using := correctly updates the column, but it also prints to the console.

Why does this happen, and/or how do I stop it printing?

## why does this update AND print?
dt_extend[, val2 := val]

Looks like these are all related and the issues I'm describing:


Update

There is a line inside print.data.table that says

if (nrows <= 0L) return(invisible()) # ability to turn off printing

Where nrows is defined in the function arguments as

nrows=getOption("datatable.print.nrows")

Which is an option, that can be set by

options("datatable.print.nrows" = -1L)

setting this option does indeed suppress the print when using :=. Maybe I can be clever with this and override the given "datatable.print.nrows" option if the user has used :=?

SymbolixAU
  • 25,502
  • 4
  • 67
  • 139
  • Might be related. I was trying to do the opposite. https://stackoverflow.com/a/39626814/822162 – Clayton Stanley Jun 29 '17 at 16:48
  • Thanks @ClaytonStanley, I'll have a look into it, but I'm hoping there's a way of doing it without modifying / accessing different environments – SymbolixAU Jun 29 '17 at 21:52

1 Answers1

3

to stop printing you can do invisible(dt_extend[, val2 := val]) you can check this maybe https://github.com/Rdatatable/data.table/issues/1122

s.brunel
  • 1,003
  • 10
  • 24
  • Thanks for the suggestion. However, I'm after a solution that allows me to keep the intended functionality of `:=`, rather than having to call `invisible()` (as ultimately this will be going in a package of my own) – SymbolixAU Jun 29 '17 at 09:51
  • @SymbolixAU what is wrong about `invisible` if you have to write own `print` method anyway? just use it there. – jangorecki Aug 19 '17 at 09:58
  • @SymbolixAU I would go with PR to data.table so you won't need to maintain own "extended.data.table" class. – jangorecki Aug 19 '17 at 09:59
  • @jangorecki - I've just found [this FR 1091](https://github.com/Rdatatable/data.table/issues/1091), which implements what I'm after, so I think i'm sorted. – SymbolixAU Oct 18 '17 at 02:38