2015-05-08 11 views
8

Esiste un modo per generare il risultato di una pipeline ad ogni passaggio senza eseguirlo manualmente? (ad esempio senza selezionare ed eseguire solo i blocchi selezionati)Passaggio attraverso una pipeline con risultati intermedi

Spesso mi trovo a gestire una linea linea per linea per ricordare cosa stava facendo o quando sto sviluppando qualche analisi.

Ad esempio:

library(dplyr) 

mtcars %>% 
    group_by(cyl) %>% 
    sample_frac(0.1) %>% 
    summarise(res = mean(mpg)) 
# Source: local data frame [3 x 2] 
# 
# cyl res 
# 1 4 33.9 
# 2 6 18.1 
# 3 8 18.7 

che avevo per selezionare ed eseguire:

mtcars %>% group_by(cyl) 

e poi ...

mtcars %>% group_by(cyl) %>% sample_frac(0.1) 

e così via ...

Ma selezionando e CMD/CTRL + ENTER in RStudio lascia un metodo più efficiente a desiderare.

Questo può essere fatto nel codice?

C'è una funzione che prende un oleodotto e corse/digerisce riga per riga mostrando uscita ad ogni passo nella console e si continua con enter come in demos(...) o examples(...) del pacchetto di guide

+0

Controllare la funzione 'debug()' di R. È vicino a quello che vuoi. Potresti usarlo con le istruzioni 'print()'. Questo post su [Cross Validated] (http://stats.stackexchange.com/questions/13535/running-an-r-script-line-by-line) parla di più. –

risposta

1

È facile con la catena di funzioni magrittr. Per esempio definire una funzione my_chain con:

foo <- function(x) x + 1 
bar <- function(x) x + 1 
baz <- function(x) x + 1 
my_chain <- . %>% foo %>% bar %>% baz 

e ottenere il risultato finale di una catena come:

 > my_chain(0) 
    [1] 3 

è possibile ottenere una lista di funzioni con functions(my_chain) e definire una funzione "passo-passo" come questo :

stepper <- function(fun_chain, x, FUN = print) { 
    f_list <- functions(fun_chain) 
    for(i in seq_along(f_list)) { 
    x <- f_list[[i]](x) 
    FUN(x) 
    } 
    invisible(x) 
} 

Ed eseguire la catena con interposto funzione print:

stepper(my_chain, 0, print) 

# [1] 1 
# [1] 2 
# [1] 3 

O con attesa di input da parte dell'utente:

stepper(my_chain, 0, function(x) {print(x); readline()}) 
2

Aggiungi stampa :

+0

Ho capito che la stampa restituisce il suo argomento e quindi funziona, ma non è molto più breve/più veloce/più conveniente della semplice selezione manuale ed esecuzione di blocchi. –

+0

@andrewwong Dicci di più, perché avresti bisogno di eseguirlo riga per riga, ancora più importante perché vorresti vedere l'output di stampa uno per uno? – zx8754

+1

domanda aggiornata. Voglio uno stepper interattivo nella console o un documento di markdown automatico magico con tutti gli intermedi generati. grazie per i tuoi pensieri! –

1

IMHO magrittr è per lo più utile in modo interattivo, cioè quando sto esplorando i dati o la costruzione di una nuova formula/modello.

In questi casi, memorizzare i risultati intermedi in variabili distinte richiede molto tempo e distrazione, mentre i tubi mi permetta di concentrarsi sui dati, invece di digitare:

x %>% foo 
## reason on results and 
x %>% foo %>% bar 
## reason on results and 
x %>% foo %>% bar %>% baz 
## etc. 

Il problema qui è che non lo so in anticipo quale sarà la pipa finale, come in @bergant.

Digitare, come in @ zx8754,

x %>% print %>% foo %>% print %>% bar %>% print %>% baz 

aggiunge a molto in testa e, per me, sconfigge l'intero scopo di magrittr.

Essenzialmente magrittr manca un operatore di semplice che sia stampe e tubi risultati.
La buona notizia è che sembra abbastanza facile per le imbarcazioni uno:

`%P>%`=function(lhs, rhs){ print(lhs); lhs %>% rhs } 

Ora è possibile stampare un tubo:

1:4 %P>% sqrt %P>% sum 
## [1] 1 2 3 4 
## [1] 1.000000 1.414214 1.732051 2.000000 
## [1] 6.146264 

ho scoperto che se si definisce/utilizza un combinazioni di tasti per %P>% e %>%, il flusso di lavoro di prototipazione è molto semplificato (vedere Emacs ESS o RStudio).

3

È possibile selezionare quali risultati stampare utilizzando il tee-operator (%T>%) e print(). Il tee-operatore è utilizzato esclusivamente per effetti collaterali come la stampa.

# i.e. 
mtcars %>% 
    group_by(cyl) %T>% print() %>% 
    sample_frac(0.1) %T>% print() %>% 
    summarise(res = mean(mpg))