17

I've come across this problem before, but just wrote the export function outside of the chain. Is there a way to include a write.csv statement within a dplyr chain?

library(dplyr)

data_set %>%
filter(Date == Sys.Date() - 1 | Date == Sys.Date()) %>%
write.csv('data_set_twodays.csv', row.names = F) %>%
filter(Date = Sys.Date()) %>%
write.csv('data_set_today.csv', row.names = F)
NULL
smci
  • 32,567
  • 20
  • 113
  • 146
maloneypatr
  • 3,562
  • 4
  • 23
  • 33
  • 1
    I assume the chain takes the return value of each "link" and passes it to the next. Since there is no return from `write.csv` this probably won't work. You could wrap `write.csv` and make sure to return the data... then maybe... – Justin May 27 '14 at 20:31
  • please take a look at my answer. I believe it is more useful for others who have the same need. – kmace Oct 03 '17 at 21:45

2 Answers2

26

This appeared to work for me in version 0.2:

mtcars %>% filter(cyl == 4) %>% write.csv(.,file = "~/Desktop/piping.csv")
joran
  • 169,992
  • 32
  • 429
  • 468
  • 5
    wow, this dplyr stuff is really beginning to look like a new language... Like unix pipes meet lisp or something. – Stephen Henderson May 27 '14 at 21:04
  • 3
    Since the data is the first argument to `write.csv()` you don't need `.` or the explicit argument name, `file`. – hadley Jun 04 '14 at 13:21
  • 4
    @hadley Any way to make this work with `group_by`? e.g. `df %>% group_by(SomeGroup) %>% write.csv(paste0(SomeGroup, ".csv"))` – eenblam May 27 '16 at 19:12
  • 1
    Not a `dplyr` answer, but I remembered that `split` exists after posting. Assuming you didn't need the SomeGroup column in the result: `dl = split(df, df$SomeGroup); for (somegroup in dl) {write.csv(select(somegroup, -Somegroup), paste0(first(somegroup$Somegroup), ".csv"))` – eenblam May 27 '16 at 19:26
  • See https://stackoverflow.com/a/41233405 for using `group_by` followed by `do` function call to export data frame. – Samir Aug 16 '17 at 02:21
  • The answer will not work mid-pipe which was what the OP asked for. See @kmace's answer which does work mid-pipe. – Evgenii Jul 17 '20 at 06:08
11

The T pipe is what you're looking for:

%T>% will run the function, but pass the input as output

library(dplyr)
library(magrittr)

data_set %>%
filter(Date == Sys.Date() - 1 | Date == Sys.Date()) %T>%
write.csv('data_set_twodays.csv', row.names = F) %>%
filter(Date = Sys.Date()) %T>%
write.csv('data_set_today.csv', row.names = F) 

people often use it to plot an intermediate without breaking their pipes!

From the docs:

rnorm(200) %>%
matrix(ncol = 2) %T>%
plot %>% # plot usually does not return anything. 
colSums
kmace
  • 1,994
  • 3
  • 23
  • 39