2015-07-19 22 views
8

Voglio finire un tubo con un operatore di assegnazione in R.Come si termina una pipe con un operatore di assegnazione?

il mio obiettivo (in pseudo R):

data %>% analysis functions %>% analyzedData 

in cui i dati e analyzedData sono entrambi un data.frame.

Ho provato alcune varianti di questo, ognuno con un unico messaggio di errore. alcune iterazioni che ho provato:

data %>% analysis functions %>% -> analyzedData 
data %>% analysis functions %>% .-> analyzedData 
data %>% analysis functions %>% <-. analyzedData 
data %>% analysis functions %>% <- analyzedData 

Messaggi di errore:

Error in function_list[[k]](value) : 
    could not find function "analyzedData" 
Error: object 'analyzedData' not found 
Error: unexpected assignment in: .. 

Aggiornamento: il modo in cui ho capito per fare questo è:

data %>% do analysis %>% {.} -> analyzedData 

In questo modo, per risolvere i problemi/esegue il debug di un pipe lungo, è possibile rilasciare queste due linee nella pipe per ridurre al minimo il riesecuzione del codice e isolare il problema.

data %>% pipeline functions %>% 
    {.}-> tempWayPoint 
    tmpWayPoint %>% 
more pipeline functions %>% {.} -> endPipe 
+3

' analyzeData <- data %>% analisi functions' – scoa

+0

Il tuo titolo è un po 'fuorviante; ciò che vuoi veramente fare è inserire un incarico in un oleodotto, non concluderlo. –

risposta

6

E 'probabilmente più facile fare l'assegnazione come la prima cosa (come SCOA menziona), ma se si vuole veramente mettere alla fine si potrebbe usare assign

mtcars %>% 
    group_by(cyl) %>% 
    summarize(m = mean(hp)) %>% 
    assign("bar", .) 

che conterrà l'output in "bar"

In alternativa è possibile utilizzare semplicemente l'operatore ->. Lei parla nella tua domanda, ma sembra che si usa qualcosa come

mtcars %>% -> yourvariable 

invece di

mtcars -> yourvariable 

che non si desidera avere %>% davanti al ->

+0

Grazie, questo sembra fare il trucco. Conoscete i meriti relativi dell'uso di '{.} -> endPipe' vs 'assign ("endPipe",.)'? Vedo che assegnare ti permette di specificare l'ambiente come argomento. A parte questo, è meglio dell'altro se siamo interessati solo all'assegnazione dell'ambiente attuale? Sono solo differenze stilistiche? –

+0

Ho provato questo, ma l'assegnazione non funziona. Il codice valuta, ma non ottengo un nuovo oggetto chiamato "bar". – ccoffman

+0

@ccoffman Dovresti ottenere un nuovo oggetto chiamato 'bar'. Verrebbe valutato nell'ambiente corrente, quindi se lo stai facendo all'interno di una funzione e poi cerchi "bar" dopo che la funzione è stata chiusa, yeah "bar" non esisterà più. Questo è più un problema di scoping però. – Dason

2

Update: il modo in cui ho capito per fare questo è: data %>% do analysis %>% {.} -> analyzedData

In questo modo, per risolvere i problemi/debug di un tubo lungo, è possibile eliminare questi due linee nel vostro tubo per ridurre al minimo il codice replica e per isolare il problema.

data %>% pipeline functions %>% 
    {.}-> tempWayPoint 
    tmpWayPoint %>% 
more pipeline functions %>% {.} -> endPipe 

Se si dispone di un modo migliore per farlo, fatemelo sapere.

+2

Non è necessario '%>% {.}'. Puoi semplicemente fare 'pipeline_functions -> tmpWaypoint'. –

4

Si può pensare a una catena di condotte come una funzione multilinea, che funziona come ogni altra funzione multilinea. Il solito modo per salvare l'uscita è per assegnarlo sulla prima riga:

analyzedData <- data %>% analysis functions 

come si farebbe:

plot <- ggplot(data,aes(x=x,y=x)) + 
    geom_point() 
5

Sembra stai cercando di decorare l'operatore della pipeline %>% con l'effetto collaterale della creazione di un nuovo oggetto. Si potrebbe presumere che si possa usare l'operatore di assegnazione -> per questo, ma non funzionerà in una pipeline.Questo perché -> ha una precedenza inferiore rispetto agli operatori definiti dall'utente come %>%, che compromettono l'analisi: la tua pipeline verrà analizzata come (initial_stages) -> (final_stages) che è priva di senso.

Una soluzione è quella di sostituire -> con una versione definita dall'utente. Mentre noi siamo, potremmo anche utilizzare il pacchetto lazyeval, per assicurare che possa creare l'oggetto in cui si suppone di andare:

`%->%` <- function(value, x) 
{ 
    x <- lazyeval::lazy(x) 
    assign(deparse(x$expr), value, x$env) 
    value 
} 

Un esempio di questo è in uso:

smry <- mtcars %>% 
    group_by(cyl) %->% # ->, not > 
    tmp %>% 
    summarise(m=mean(mpg)) 

tmp 
#Source: local data frame [32 x 11] 
#Groups: cyl 
# 
# mpg cyl disp hp drat wt qsec vs am gear carb 
#1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 
#2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 
#3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 
#4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 
#5 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 
#.. ... ... ... ... ... ... ... .. .. ... ... 

smry 
#Source: local data frame [3 x 2] 
# 
# cyl  m 
#1 4 26.66364 
#2 6 19.74286 
#3 8 15.10000 
Problemi correlati