2015-10-07 7 views
27

Desidero modificare un data.table all'interno di una funzione. Se utilizzo la funzione := all'interno della funzione, il risultato viene stampato solo per la seconda chiamata.oggetti data.table non stampati dopo il rinvio dalla funzione

Guardate la seguente figura:

library(data.table) 
mydt <- data.table(x = 1:3, y = 5:7) 

myfunction <- function(dt) { 
    dt[, z := y - x] 
    dt 
} 

Quando chiamo solo la funzione, la tabella non viene stampato (che è il comportamento standard Tuttavia, se risparmio il ritornato data.table in un nuovo oggetto. , non viene stampato in prima convocazione, solo per il secondo.

myfunction(mydt) # nothing is printed 
result <- myfunction(mydt) 
result # nothing is printed 
result # for the second time, the result is printed 
mydt                  
# x y z 
# 1: 1 5 4 
# 2: 2 6 4 
# 3: 3 7 4 

Potrebbe spiegare perché questo accade e come prevenirlo?

+4

Leggi questo: https://github.com/Rdatatable/data.table/blob/master /NEWS.md#bug-fixes-3. Il primo BUG che è stato corretto nella v 1.9.6 –

+0

Vedere la sezione 2.23 delle FAQ di 'data.table' (' vignette ("datatable-faq", package = "data.table") ') – Uwe

risposta

29

Come David Arenburg menziona in un comment, la risposta può essere trovata here. È stato corretto un bug nella versione 1.9.6 ma la correzione ha introdotto questo aspetto negativo.

Uno dovrebbe chiamare DT[] alla fine della funzione per evitare questo comportamento.

myfunction <- function(dt) { 
    dt[, z := y - x][] 
} 
myfunction(mydt) # prints immediately 
# x y z 
# 1: 1 5 4 
# 2: 2 6 4 
# 3: 3 7 4 
+5

' DT [] 'è necessario solo quando la stampa di data.table è soppressa , quindi quando usi le funzioni ': =' o 'set *' – jangorecki

0

Mi dispiace se io non dovrei postare qualcosa qui che non è un risposta, ma il mio post è troppo lungo per un commento.

vorrei far notare che la soluzione di janosdivenyi di aggiungere un finale []-dt non sempre dare i risultati sperati (anche quando si utilizza data.table 1.9.6 o 1.10.4) come faccio io qui di seguito.

Gli esempi seguenti mostrano che se dt è l'ultima riga nella funzione si ottiene il comportamento desiderato senza la presenza del trascinamento [], ma se dt non inizia l'ultima riga nella funzione poi un strascicando [] è necessario per ottenere il comportamento desiderato.

Il primo esempio mostra che senza trascinamento [] su dt otteniamo il comportamento previsto quando dt inizia nell'ultima riga della funzione

mydt <- data.table(x = 1:3, y = 5:7) 

myfunction <- function(dt) { 
    df <- 1 
    dt[, z := y - x] 
} 

myfunction(mydt) # Nothing printed as expected 

mydt # Content printed as desired 
## x y z 
## 1: 1 5 4 
## 2: 2 6 4 
## 3: 3 7 4 

Aggiunta di un trascinamento [] su dt dà comportamento imprevisto

mydt <- data.table(x = 1:3, y = 5:7) 

myfunction <- function(dt) { 
    df <- 1 
    dt[, z := y - x][] 
} 

myfunction(mydt) # Content printed unexpectedly 
## x y z 
## 1: 1 5 4 
## 2: 2 6 4 
## 3: 3 7 4 

mydt # Content printed as desired 
## x y z 
## 1: 1 5 4 
## 2: 2 6 4 
## 3: 3 7 4 

Spostamento df <- 1 a dopo il dt senza interruzione [] restituisce unexpec Ted comportamento

mydt <- data.table(x = 1:3, y = 5:7) 

myfunction <- function(dt) { 
    dt[, z := y - x] 
    df <- 1 
} 

myfunction(mydt) # Nothing printed as expected 

mydt # Nothing printed unexpectedly 

Spostamento df <- 1 dopo il dt con un trailing [] dà l'atteso comportamento

mydt <- data.table(x = 1:3, y = 5:7) 

myfunction <- function(dt) { 
    dt[, z := y - x][] 
    df <- 1 
} 

myfunction(mydt) # Nothing printed as expected 

mydt # Content printed as desired 
## x y z 
## 1: 1 5 4 
## 2: 2 6 4 
## 3: 3 7 4 
+1

Penso che tu stia in parte confondendo come funzionano le funzioni. Tutte le funzioni restituiscono un valore. Se non si scrive un'istruzione esplicita 'return (x)', viene restituito l'ultimo valore nella funzione. 'df <- 1' restituisce il valore' 1' invisibilmente', mentre 'DT [, x: = y] []' restituisce 'DT', stampato. – Frank

+1

Grazie per questa spiegazione. Non ho capito. Immagino sia il bit "return invisibly" che mi ha catturato. Sono stato anche confuso dall'aspetto "copia per riferimento" delle tabelle di dati. Ho passato anni a giocare con quegli esempi cercando di dare un senso a loro. Adesso vedi perché non rispondo alle domande su questo forum :-) – Paul

Problemi correlati