Q: In an R dplyr pipeline, how can I assign some intermediate output to a temp variable for use further down the pipeline?
My approach below works. But it assigns into the global frame, which is undesirable. There has to be a better way, right? I figured my approach involving the commented line would get the desired results. No dice. Confused why that didn't work.
df <- data.frame(a = LETTERS[1:3], b=1:3)
df %>%
filter(b < 3) %>%
assign("tmp", ., envir = .GlobalEnv) %>% # works
#assign("tmp", .) %>% # doesn't work
mutate(b = b*2) %>%
bind_rows(tmp)
a b
1 A 2
2 B 4
3 A 1
4 B 2
This does not create an object in the global environment:
df %>%
filter(b < 3) %>%
{
{ . -> tmp } %>%
mutate(b = b*2) %>%
bind_rows(tmp)
}
This can also be used for debugging if you use . ->> tmp
instead of . -> tmp
or insert this into the pipeline:
{ browser(); . } %>%
I often find the need to save an intermediate product in a pipeline. While my use case is typically to avoid duplicating filters for later splitting, manipulation and reassembly, the technique can work well here:
df %>%
filter(b < 3) %>%
{. ->> intermediateResult} %>% # this saves intermediate
mutate(b = b*2) %>%
bind_rows(intermediateResult)
pipeR
is a package that extends the capabilities of the pipe without adding different pipes (as magrittr
does). To assign, you pass a variable name, quoted with ~
in parentheses as an element in your pipe:
library(dplyr)
library(pipeR)
df %>>%
filter(b < 3) %>>%
(~tmp) %>>%
mutate(b = b*2) %>>%
bind_rows(tmp)
## a b
## 1 A 2
## 2 B 4
## 3 A 1
## 4 B 2
tmp
## a b
## 1 A 1
## 2 B 2
While the syntax is not terribly descriptive, pipeR
is very well documented.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With