7

Sometimes print needs two attempts to print a data.table:

> library(data.table)
> 
> rm(list=ls())
> 
> Tbl <- fread( input = "Nr; Value
+                        Nr 1;46.73
+                        Nr 2;49.02
+                        Nr 3;50.62
+                        Nr 4;49.80
+                        Nr 5;50.15",
+               sep    = ";",
+               header = TRUE,
+               colClasses = c("character","numeric") )
> print(Tbl)
     Nr Value
1: Nr 1 46.73
2: Nr 2 49.02
3: Nr 3 50.62
4: Nr 4 49.80
5: Nr 5 50.15
> Tbl <- Tbl[, Nr := as.numeric( gsub( "Nr ", "", Tbl$Nr ))]
> print(Tbl)
> print(Tbl)
   Nr Value
1:  1 46.73
2:  2 49.02
3:  3 50.62
4:  4 49.80
5:  5 50.15
> 

Not so a data.frame:

> rm(list=ls())
> 
> DF <- read.table( text = "Nr; Value
+                           Nr 1;46.73
+                           Nr 2;49.02
+                           Nr 3;50.62
+                           Nr 4;49.80
+                           Nr 5;50.15",
+                   sep    = ";",
+                   header = TRUE,
+                   colClasses = c("character","numeric"))
> 
> DF$Nr <- as.numeric( gsub( "Nr ", "", DF$Nr ))
> print(DF)
  Nr Value
1  1 46.73
2  2 49.02
3  3 50.62
4  4 49.80
5  5 50.15
> 

If the code is contained in a script file, the data.table is printed immediately:

> source(path_to_Script_1,echo=TRUE,prompt.echo="(script)   ",max.deparse.length=500)

(script)   library(data.table)

(script)   rm(list=ls())

(script)   Tbl <- fread( input = "Nr; Value
+                        Nr 1;46.73
+                        Nr 2;49.02
+                        Nr 3;50.62
+                        Nr 4;49.80
+                        Nr 5;50.15",
+               sep    = ";",
+               header = TRUE,
+               colClasses = c("character","numeric") )

(script)   Tbl <- Tbl[, Nr := as.numeric( gsub( "Nr ", "", Tbl$Nr ))]

(script)   print(Tbl)
   Nr Value
1:  1 46.73
2:  2 49.02
3:  3 50.62
4:  4 49.80
5:  5 50.15
> 

But if print(Tbl) is omitted from the script file, print on the console again needs two attempts:

> source(path_to_Script_2,echo=TRUE,prompt.echo="(script)   ",max.deparse.length=500)

(script)   library(data.table)

(script)   rm(list=ls())

(script)   Tbl <- fread( input = "Nr; Value
+                        Nr 1;46.73
+                        Nr 2;49.02
+                        Nr 3;50.62
+                        Nr 4;49.80
+                        Nr 5;50.15",
+               sep    = ";",
+               header = TRUE,
+               colClasses = c("character","numeric") )

(script)   Tbl <- Tbl[, Nr := as.numeric( gsub( "Nr ", "", Tbl$Nr ))]
> print(Tbl)
> print(Tbl)
   Nr Value
1:  1 46.73
2:  2 49.02
3:  3 50.62
4:  4 49.80
5:  5 50.15
> 

Can anybody tell me when ans why print needs two attempts? I'm using R version 3.2.2:

> R.version
               _                           
platform       x86_64-w64-mingw32          
arch           x86_64                      
os             mingw32                     
system         x86_64, mingw32             
status                                     
major          3                           
minor          2.2                         
year           2015                        
month          08                          
day            14                          
svn rev        69053                       
language       R                           
version.string R version 3.2.2 (2015-08-14)
nickname       Fire Safety   

Operating system is Windows 7.

mra68
  • 2,960
  • 1
  • 10
  • 17
  • 6
    care to remove all the +'s and >'s so the code can be easily run by someone attempting to answer your question? – Matthew Plourde Dec 14 '15 at 15:05
  • 3
    [probably related](http://stackoverflow.com/questions/32988099/data-table-objects-not-printed-after-returned-from-function) – Cath Dec 14 '15 at 15:07
  • Why does it make a difference if `print(Tbl)` is contained in a script file or not? – mra68 Dec 14 '15 at 15:18
  • 4
    Why do you use `Tbl <-` together with assigning a column by reference? That's a useless copy. Just use `Tbl[, Nr := as.numeric( gsub( "Nr ", "", Tbl$Nr ))]`, which modifies the data.table in place. – Roland Dec 14 '15 at 15:20
  • long story short just add `[ ]` if you want to be _sure_ it's going to print – MichaelChirico Dec 14 '15 at 16:34
  • 3
    Also nice to **not** put `rm(list = ls())` in code someone my copy-paste and run without reading carefully. If you need to remove a specific object for the example to work, be specific `rm(Tbl)`. – Gregor Thomas Dec 14 '15 at 16:57

1 Answers1

4

Quoting the NEWS (1. bug fix in version 1.9.6):

if (TRUE) DT[,LHS:=RHS] no longer prints, #869 and #1122. Tests added. To get this to work we've had to live with one downside: if a := is used inside a function with no DT[] before the end of the function, then the next time DT or print(DT) is typed at the prompt, nothing will be printed. A repeated DT or print(DT) will print. To avoid this: include a DT[] after the last := in your function. If that is not possible (e.g., it's not a function you can change) then DT[] at the prompt is guaranteed to print.

<- is a function. Of course, you shouldn't use <- there at all. It creates an unnecessary copy (since := modifies the data.table column in place) and is therefore inefficient.

Roland
  • 127,288
  • 10
  • 191
  • 288