0

Sample data

set.seed(123)
df <- data.frame(loc.id = rep(c(1:3), each = 4*10), 
                        year = rep(rep(c(1980:1983), each = 10), times = 3),
                        day = rep(1:10, times = 3*4),
                        x = sample(123:200, 4*3*10, replace = T),
                        start = 123,
                        end = 200)

I want to save the plot of each loc.id for all years in a single page using facet_wrap and each loc.id in separate pages as a pdf. Following loop does this:

loc.vec <- 1:3

pdf("my.pdf")

for(l in  seq_along(loc.vec)){

  loc.id <- loc.vec[l]
  df.sub <- df[df$loc.id == loc.id,]

  pp <- ggplot(df.sub,aes(x = day, y = x)) + geom_line() +
          facet_wrap(~year) + 
          geom_vline(aes(xintercept = df.sub$start)) + 
          geom_vline(aes(xintercept = df.sub$end))
  print(pp)
}
dev.off()

Can I achieve without the loop?

Thanks

6
  • 2
    whats the problem with using a loop? Commented May 31, 2018 at 14:53
  • The no. of loc.id I have is way too many. So was wondering if there is any quicker solution to this. Don't mind using a loop Commented May 31, 2018 at 15:16
  • Why the downvote? Commented May 31, 2018 at 19:59
  • 1
    It wasn't my downvote, but I can hazard a guess why. Your question includes code that works fine. There's no way around needing some kind of loop here, and your original choice of for is as good as any from a functional viewpoint. You may get a range of answers suggesting to use map or apply or by or any of the many other ways of looping in R. But none of them changes the underying fact that you need to repeat an operation several times iterating over loc.id. In other words you need a loop and you already have one that works just fine. Commented May 31, 2018 at 20:13
  • Fair point. I guess I was more talking about from a speed perspective i.e. if I had 1 million loc.id, would this loop will still be faster compared to the solution below. Commented Jun 1, 2018 at 9:39

2 Answers 2

1

Here is a solution using purrr:

library(tidyverse)

f_plot <- function(id) {
  df %>%
    filter(loc.id == id) %>%
    ggplot(., aes(x = day, y = x)) + 
    geom_line() +
    facet_wrap(~year) + 
    geom_vline(aes(xintercept = start)) + 
    geom_vline(aes(xintercept = end))
}

pdf("my2.pdf")
map(loc.vec, f_plot)
dev.off()
Sign up to request clarification or add additional context in comments.

Comments

1

Consider by (being the object-oriented wrapper to tapply) to slice dataframe by the loc.vec factor and run subsets through plot:

process_plots <- function(df.sub) {    
  ggplot(df.sub, aes(x = day, y = x)) + 
    geom_line() + facet_wrap(~year) + 
    geom_vline(aes(xintercept = df.sub$start)) + 
    geom_vline(aes(xintercept = df.sub$end))      
}

pdf("my.pdf")    
by(df, df$loc.vec, process_plots)
dev.off()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.