2016-09-22 9 views
6

Na konsoli R oczekiwałem, że print(x) będzie zawsze dawało to samo wyjście co x. Zawsze zakładałem, że konsola używa print do faktycznego drukowania wszystkiego. Ale jest dodatkowa NULL tutaj od print:`print (x)` nie daje tego samego wyjścia co `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? 

Dane próbka jest tworzony przez pakiet data.table, ale myślę, że ogólna kwestia nadal ma zastosowanie nawet wtedy, gdy nie jest używany data.table: co funkcja/metoda służy do drukowania powrót wartości na konsoli?

# R --vanilla # R version 3.2.3 
+1

Proszę zgłosić to jako błąd na github. – eddi

+0

Robiąc to teraz @eddi. Miałeś na myśli raport o błędzie z 'data.table' dla ich metody drukowania, tak ?. Wiele odpowiedzi (w tym moja własna, którą napisałem po dalszych eksperymentach) sugerują, że 'data'table'' print' method * powinna * zwracać niewidocznie, ale w rzeczywistości zwraca się widocznie. –

+0

tak, powinien powrócić niewidoczny – eddi

Odpowiedz

3

Może to być spowodowane wartością zwracaną przez drukowanie.

Od ?print:

„drukuj” drukuje swój argument i zwraca go niewidocznie (przez „niewidzialne (x)”).

Więc print ma wartości zwracanej, co zdarza się NULL w tym przypadku. Z drugiej strony, wpisanie zmiennej w konsoli tworzy dane wyjściowe, ale nic nie zwraca, a NULL nie jest wyświetlany.

+0

Po przeprowadzeniu niektórych eksperymentów podejrzewam, że 'cat (capture.output (x), '\ n', sep = '') jest najbardziej bezpośrednim sposobem, w obrębie skryptu, drukowania' x' w ten sam sposób (tj. respektowanie widoczności), jak na konsoli. Czy to prawda? Wydaje się nieco skomplikowany –

+0

@AaronMcDaid Zakładam, że masz rację, ale nie jestem pewien. Może możemy poczekać i zobaczyć, czy zostaną opublikowane inne odpowiedzi, które rzucą więcej światła na tę sprawę. Interesujące pytanie, przy okazji. – RHertel

+0

W przykładzie w pytaniu, otrzymuję 'NULL' tylko jeśli używam' print'. Jednak mówisz, że 'print' powinien zwrócić * niewidoczny * NULL. W takim przypadku, dlaczego widzimy * widoczny * 'NULL' w tym wywołaniu do drukowania? Być może metody 'print' są * przypuszczalnie * zwracane niewidocznie, ale metoda' data.table' 'print' zwraca * widocznie *? –

0

Wywoływana metoda drukowania zależy od klasy obiektu. Jako takie istnieje print.table, print.data.frame, print.factor, etc, każdy z nich ma inną funkcję, która określa, co jest drukowane.

Spróbuj

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

Wystarczy popatrzeć na funkcje

print.data.frame 
print.table 

Zobaczysz co jest zwracany jest różna w zależności od tego, co S3 metoda druku nazywa i istnieje wiele sposobów, aby wydrukować.

Dokładny druk, do którego dzwonisz, zależy od klasy obiektu data.table.

Oznacza to również można stworzyć swój własny sposób niestandardowy S3 do drukowania poprzez przypisanie niestandardowej klasy do obiektu oraz tworzenie funkcji niestandardowych druku

class(object)<-"customclass" 

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

print(object) 
+0

Dobry przykład. +1 – RHertel

+0

Jeśli użycie nie oznacza jawnie "print", to w jaki sposób tekst zostanie wydrukowany na ekranie? Zakładałem, że konsola zawsze nazywa się "print" w imieniu użytkownika ", że tak powiem, ale przykład w moim pytaniu sugeruje inaczej. –

+0

W innej notatce, tak naprawdę nie pytałem o metody. Niezależnie od użytej metody, dlaczego istnieje dodatkowy "NULL" w przykładzie w pytaniu? –

8

Aktualizacja:

Rozwiązaniem właśnie zostały scalone w v1.10.5. Podziękowania dla Michaela Chirico.

po uruchomieniu:

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

To będzie działać zgodnie z oczekiwaniami:

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 

To może być fakt, że metoda print dla data.table robi coś złego. Oczekuje się, że metody drukowania zwrócą niewidoczny .Ale podejrzewam, że data.table:::print.data.table zwraca widocznie.

(Update: Właśnie składać a bug report to data.table przeprosiny nich gdybym Zbadaliśmy to nieprawidłowo.!)

Od ?print:

'drukuj' drukuje swój argument i zwraca go niewidoczny (przez "niewidzialny (x)").

Oto mały pokaz tego, co może się dziać:

> 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 

Uwaga jak wpisując x na własną rękę po prostu drukuje tekst, ale nie ilość. Ale wpisanie numeru print(x) powoduje również wydrukowanie numeru.

Następnie, jeśli zorganizować ta metoda druku, aby powrócić niewidocznie następująco:

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

.. następnie print(x) daje oczekiwany wynik

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

Więc, po wpisaniu w x konsola, konsola wywołuje w twoim imieniu print i ignoruje wartość zwracaną z print (która może być widoczna). Ale jeśli wpiszesz print(x), to zwrócona wartość print zostanie wydrukowana, jeśli jest widoczna.


Dokumentacja jest nieco myląca. print metody są rzekomą aby powrócić swoje argumenty i są powinien zrobić tak niewidzialnie, ale te zasady nie są egzekwowane

+0

Dzięki @RHertel za skierowanie mnie w stronę dokumentów, które 'print' wrócą niewidocznie. Lub, w mojej interpretacji, * powinien * powrócić niewidocznie i że implementatorzy metod 'print' mają powrócić niewidocznie –

+0

. Może ten test jest również interesujący:' print.Y <- function() {print ("Drukuję"); niewidoczny (1729)}; print (print.Y()) '. – RHertel

+0

Rzeczywiście istnieje różnica w źródłach. Ostatnia linia 'print.data.frame' jest' niewidoczna (x) 'podczas gdy' data.table ::: print.data.table' ma 'print (toprint, right = TRUE, quote = quote)' and 'invisible() ', więc ten ostatni zwraca' NULL'. Jednak nie jestem pewien, czy jest to błąd lub funkcja. Pamiętam pewne problemy z 'knitr' podczas aktualizowania obiektu' data.table' przez odniesienie. – Uwe