Jason
Jason

Reputation: 1130

Failures using dplyr package to generate plot file

I using the dplyr package in R to make plots and have difficulties saving plots in pdf format.

I have a data frame with several groups of data, and I want to plot each group of data and save the plots in pdf. I tried to use do and group_by in the dplyr package, but the pdf file was not generated. There was no error message.

rm(list = ls())

library(dplyr)

df=data.frame(x = c(rep('a',10),rep('b',10)),y = c(1:20))

plt = function(df)
{
  pdf('plt1.pdf')

  plot(df$x,df$y)

  dev.off()

  return(data.frame())
}

plt(df)

df %>% group_by(x) %>% do(data.frame(plot(.$y)))

I also tried lapply/sapply and similar code didn't work either.

Can any one help me with this?

Upvotes: 0

Views: 82

Answers (3)

ulfelder
ulfelder

Reputation: 5335

If you want to put all of the plots in a single PDF and don't mind using ggplot, you can do something like this:

library(dplyr)
library(ggplot2)
library(gridExtra)

# i'm using a different test data set to make scatter plots
set.seed(1)
df <- data.frame(id = rep(c("a", "b"), each = 10),
                 var1 = rnorm(20),
                 var2 = rnorm(20),
                 stringsAsFactors = FALSE)

# make a list of plots, one for each group (id)
plotlist <- lapply(unique(df$id), function(x)

  df %>%
    filter(id == x) %>%
    qplot(x = var1, y = var2, data = ., main = x)

)

# use marrangeGrob from gridExtra to get an arranged version of that list
mg = marrangeGrob(plotlist, nrow = 2, ncol = 1)

# now use ggsave to write a pdf with the plots arranged as specified in the
# previous step to the working directory; see documentation for ways to tinker
# with layout, file type, etc.
ggsave("myplots.pdf", mg)

Upvotes: 2

Marco Sandri
Marco Sandri

Reputation: 24262

Here is a solution for your problem:

rm(list = ls())
library(dplyr)
df=data.frame(x = c(rep('a',10),rep('b',10)),y = c(1:20))

plt = function(k, dtset) {
 pdf(paste('plt',k,'.pdf',sep=""))
 plot(dtset$y)
 dev.off()
}
plt(1, df)

grps <- unique(df$x)
for (k in seq_along(grps)) {
 plt(k, subset(df, df$x==grps[k]))
}

Upvotes: 2

akuiper
akuiper

Reputation: 215077

You need to call the plt function inside do; and if you want to generate a separate pdf file for each group of data, you'll have to modify the file name accordingly based on the group of data, otherwise the file gets overwritten by a plot from the last group of data:

plt = function(df) {
    pdf(sprintf('plt_%s.pdf', df$x[1]))
    plot(df$x,df$y)
    dev.off()
    return(data.frame())
}

df %>% group_by(x) %>% do(plt(.))

Besides, if you simply want to have a single box plot of y grouped by x, you can use one boxplot:

boxplot(y ~ x, data = df)

Upvotes: 2

Related Questions