2016-09-22 28 views
6

在R控制台上,我预计print(x)将始终给出与x相同的输出。我一直认为控制台使用print实际上是为所有事情做打印。但有一个额外的NULL这里从print`print(x)`不能给出与`x`相同的输出

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? 

该样本数据由data.table包创建的,但我觉得一般的问题仍然适用,即使不使用data.table时:什么功能/方法用来打印返回控制台处的值?

# R --vanilla # R version 3.2.3 
+1

请报告这是在github上的错误。 – eddi

+0

现在这样做@eddi。你的意思是用'data.table'作为打印方法的错误报告,是吗?许多答案(包括我自己的,我在进一步的实验后写的)表明'data.table'的'print'方法*应该*不可见地返回,但实际上它会显着返回。 –

+0

是的,它应该不可见地返回 – eddi

回答

3

这可能是由于打印的返回值。

?print

“打印”打印其参数,并返回它无形(经由“看不见的(X)”)。

所以print有一个返回值,在这种情况下恰好是NULL。另一方面,在控制台中键入一个变量会创建一个输出,但它不会返回任何内容,并且不会显示NULL

+0

做了一些实验后,我怀疑'cat(capture.output(x),'\ n',sep ='')'是脚本内最直接的方式,以相同的方式打印'x'即尊重可见性),就像在控制台上得到的那样。这是真的?这似乎有点复杂 –

+0

@AaronMcDaid我认为你是对的,但我不确定。也许我们可以拭目以待,看看是否会发布其他答案,以进一步阐明此事。顺便说一句有趣的问题。 – RHertel

+0

在问题的例子中,我只有在使用'print'的时候'NULL'。然而你说'print'应该返回一个*不可见* NULL。在这种情况下,为什么我们在这个调用中看到一个* visible *'NULL'来打印?也许'print'方法被认为*不可见地返回,但'data.table'' print'方法返回*可见的*? –

0

调用的打印方法取决于对象的类别。因此,有一个print.table,print.data.frame,print.factor等等,每个都有一个不同的函数来决定打印的内容。

试试这个

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

看一看功能

print.data.frame 
print.table 

你会看到什么是返回这取决于打印的S3方法不同的是所谓的,有许多方法来打印。

确切的打印你调用取决于你的data.table对象的类。

这也意味着你可以通过指定自定义类的对象,并创建自定义打印功能

class(object)<-"customclass" 

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

print(object) 
+0

不错的例子。 +1 – RHertel

+0

如果使用未明确键入“print”,那么文本如何打印到屏幕上?我认为代表用户的控制台总是被称为“print”“可以这么说,但我的问题中的例子却暗示了另一种说法 –

+0

另一方面,我并没有真正询问方法。不管使用哪种方法,为什么在问题的例子中有一个额外的'NULL'? –

8

更新创建打印自己的自定义S3方法:

的修复已经刚刚被合并在v1.10.5中。感谢Michael Chirico。

运行后:

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

预期它将工作:

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 

这可能是因为data.tableprint方法做了错误的事情。打印方法预计将无形地返回。但我怀疑data.table:::print.data.table正在返回明显

(更新:我刚刚提交a bug report to data.table不住他们,如果我已经分析了这个错误!)

?print

“打印”打印它的参数和返回它无形(通过'不可见(x)')。

以下是对可能发生的一个微小的演示:

> 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 

注意如何打字自身x简单地打印文本,但没有编号。但是输入print(x)也会导致打印号码。

然后,如果我安排这个印刷方法返回无形如下:

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

..然后print(x)给出了预期的输出

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

所以,当你在输入x控制台,控制台确实以您的名义呼叫print,并忽略来自print(可能是可见的)。但如果输入print(x),则返回值print将在打印出来时显示。


?print文档有点误导我认为。 print方法应该返回他们的说法,并认为如此无形中做是,但这些规则不执行

+0

感谢@RHertel为我指出了'print'不可见的文档。或者,根据我的理解,*应该*无形地返回,并且'print'方法的实现者预计会不可见地返回 –

+0

也许这个测试也很有趣:'print.Y < - function(){print(“我正在打印” );隐形(1729)};打印(print.Y())'。 – RHertel

+0

确实,来源有所不同。 'print.data.frame'的最后一行是'invisible(x)',而'data.table ::: print.data.table'有'print(toprint,right = TRUE,quote = quote)'和'invisible ()',所以后者返回NULL。但是,我不确定这是一个错误还是一个功能。当通过引用更新'data.table'对象时,我记得'knitr'的一些问题。 – Uwe