4
votes

I like the idea of the pipe improving readability, but I've had difficulty using it because of how inflexible it feels. So far I've only succeeded when my goal is to straightforwardly pipe X through a set of functions h(g(f(x,foo),bar),stuff)

x %>%
f(foo) %>%
g(bar) %>%
h(stuff)

If I want to store an intermediate output so that I can have h(x,stuff,f(x,foo)), is that possible? I've tried

x %>% 
intermediate = f(foo) %>% 
g(bar)

but that fails. Assign doesn't work because the first argument is the name rather than the value; is there an opposite equivalent?

I know you can use "." to refer to x or portions of it multiple times, but is there a way to use only a portion of it initially? I want to perform different functions on different columns, such as

data.frame(x[,1],apply(.[,2:3],2,fun1),apply(.[,4],2,fun2))

but I can't figure out how to limit the first argument to only x[,1] instead of all of x. I can't use %>% select(1) %>% because then it will drop the rest forever. Is there a way to do this or should I just end the pipe, do these functions, and start another pipeline? Is the easiest solution to just put all of x into the data frame and then %>% select(1,5:9) %>%?

1
To do intermediate steps use %T>%. You may need to load magrittr first. Also, you might need to use {} around it like x %T>% {bah <- .} %>% more_stuff .Frank
Break it into two chains: BOD %>% round(0) -> temp; temp %>% log Also try: anscombe %>% { data.frame(A = .[,1], B = apply(.[,2:3],1,sum), C = apply(.[,4,drop = FALSE],1,sum)) }G. Grothendieck
Can you make an reproducible example? That would greatly improve the question and get you an answer.John Paul
Yeah, I guess you would need to use ->> or <<- instead. Though this may assign to the global env, which is not great, as MrFlick says below.Frank

1 Answers

2
votes

You could write a function to do the assignment that you can include in the chain. Something like

save_to <- function(x, v) {
    var <- substitute(v)
    eval(bquote(.(var) <- .(x)), envir=globalenv())
    x
}


library(magrittr)
x<-1:10
f<-function(x) x+1
g<-function(x) x*2
h<-function(x) paste(x, collapse=", ")    

x %>% f %>% g %>% save_to(z) %>% h
# [1] "4, 6, 8, 10, 12, 14, 16, 18, 20, 22"
z
#  [1]  4  6  8 10 12 14 16 18 20 22

Note that this saves the value to the global environment. For this reason it's probably not a great idea (functions with side effects are generally a bad design practice in functional languages). It would be better to break it up into different chains.

z <- x %>% f %>% g
z %>% h