3

I'm having a hard time trying to create a function with a for loop that takes the columns in a data frame and creates different plots based on the column name.. I have read through multiple different related questions on SO, for example, 1: Creating function to use loops with ggplot2 [2]: Looping over variables in ggplot but nothing has worked for me so far.

Sample Data:

philly_df_new <- structure(list(DATE = structure(c(14610, 14611, 14612, 14613, 
14614, 14615, 14616, 14617, 14618, 14619, 14620, 14621, 14622, 
14623, 14624, 14625, 14626, 14627, 14628, 14629), class = "Date"), 
    HOURLYDewPointTempC = c(0, -8.9, -15, -12.2, -11.7, -10.6, 
    -8.3, -4.4, -12.2, -17.2, -12.8, -6.1, -10.6, -7.8, -5.6, 
    -2.2, 0.6, 3.9, 0.6, -3.3), HOURLYSeaLevelPressure = c(30, 
    29.79, 29.78, 29.76, 29.81, 29.78, 29.89, 29.87, 29.98, 30.25, 
    30.27, 30.13, 30.22, 30.23, 30.21, 30.23, 30.14, 29.49, 29.95, 
    29.92), DAILYDeptFromNormalAverageTemp = c(-1.7, 2.4, -6.4, 
    -10.3, -6.2, -5.1, -1, -1, -5.9, -10.8, -11.8, -9.7, -3.7, 
    -1.7, -1.6, 4.4, 4.4, 6.4, 8.4, 4.3)), .Names = c("DATE", 
"HOURLYDewPointTempC", "HOURLYSeaLevelPressure", "DAILYDeptFromNormalAverageTemp"
), row.names = c(NA, -20L), class = c("tbl_df", "tbl", "data.frame"
))

Different Codes I have tried:

Plot_Graph<-function(x,na.rm=T){
  nm=names(x)
  for (i in seq_along(nm)) {
    print(ggplot(x,aes_string(x="DATE",y=i) +
            geom_point()))
                                      }
  }

Plot_Graph(philly_df_new)
colNames <- names(philly_df_new)[2:4]
for(i in seq_along(colNames)){
  plt <- ggplot(philly_df_new, aes_string(x="DATE", y = i)) +
    geom_point(color="#B20000", size=3, alpha=0.5,na.rm = T) 
  print(plt)
}

When I run the first function I get this error message Error: Mapping should be created withaes()oraes_(). When I run the second function I get a plot with the same plot over and over with a horizontal line.I have tried more ways then this but for minimal purposes I'll show those two. I want to create a time series plot for each column like this: enter image description here

4
  • What exactly do you mean "nothing shows up"? Are there no plots in the Rstudio plot window at all? Rstudio will only show one plot at a time. Are you just seeing the last plot? Are you getting an error message of any kind? What version of ggplot2 are you using? Commented Aug 27, 2018 at 18:16
  • @MrFlick sorry didn't mean to be so vague .. I will edit question better. Thanks. Commented Aug 27, 2018 at 18:18
  • @MrFlick Hope my edit makes it clearer Commented Aug 27, 2018 at 18:21
  • 2
    You have a parenthesis in the wrong place inside Plot_Graph. It should be print(ggplot(x,aes_string(x="DATE",y=i))+geom_point()). Commented Aug 27, 2018 at 18:25

2 Answers 2

3

The following works.
You were looping along all columns including column "DATE", which is supposed to be the x axis and the loop variable was integer so in the plot's aesthetic y = i was an integer, not a column name.

Note that I call windows() to open a new graphic window. Remove this if not needed.

Plot_Graph <- function(DF, na.rm = TRUE){
  nm = names(DF)[-1]
  for (i in nm) {
    g <- ggplot(DF, aes(x = DATE, y = get(i))) +
            geom_point()
    windows()
    print(g)
  }
}

Plot_Graph(philly_df_new)
Sign up to request clarification or add additional context in comments.

6 Comments

How do you I add a Y label to this? I tried “ + ylab(get(i)) but it throws an error! Thanks in advance!
@None Try ylab(i), since i already is the column name .
@None Note that windows only works on, well, Windows. If you are using other OS's you can use X11() or quartz().
Actually, I’m on iOS and it worked very well - I was exporting those and didn’t really care about a pop up window - it was however also running well in the Rstudio plot console. Truces are in vogue lately ;)……..ah well may be it’s the XQ or Homebrew after all
Here is the code hoping it helps someone else: Plot_Graph <- function(DF, na.rm = TRUE){ nm = names(DF)[-1] for (i in nm) { g <- ggplot(DF, aes(x = Date.Time, y = get(i))) + geom_point(na.rm=TRUE, size=0.5) + theme(axis.text.x = element_text(angle = 45, hjust = 1)) + scale_x_datetime(breaks = "6 months", labels = date_format("%b %Y")) + xlab("Date") + ylab(i) print(g) ggsave(filename = sprintf('%s.png', i), plot = g) } } Plot_Graph(nf)
|
1

A solution using tidyeval approach similar to this answer which requires ggplot2 v3.0.0

  • First we build a function that takes x- & y- columns as inputs. Note the use of rlang::sym, rlang::quo_name & !!.

  • Then we can loop through every column using purrr::map.

library(rlang)
library(tidyverse)

philly_df_new <- structure(list(DATE = structure(c(14610, 14611, 14612, 14613, 
    14614, 14615, 14616, 14617, 14618, 14619, 14620, 14621, 14622, 
    14623, 14624, 14625, 14626, 14627, 14628, 14629), class = "Date"), 
        HOURLYDewPointTempC = c(0, -8.9, -15, -12.2, -11.7, -10.6, 
        -8.3, -4.4, -12.2, -17.2, -12.8, -6.1, -10.6, -7.8, -5.6, 
        -2.2, 0.6, 3.9, 0.6, -3.3), HOURLYSeaLevelPressure = c(30, 
        29.79, 29.78, 29.76, 29.81, 29.78, 29.89, 29.87, 29.98, 30.25, 
        30.27, 30.13, 30.22, 30.23, 30.21, 30.23, 30.14, 29.49, 29.95, 
        29.92), DAILYDeptFromNormalAverageTemp = c(-1.7, 2.4, -6.4, 
        -10.3, -6.2, -5.1, -1, -1, -5.9, -10.8, -11.8, -9.7, -3.7, 
        -1.7, -1.6, 4.4, 4.4, 6.4, 8.4, 4.3)), .Names = c("DATE", 
    "HOURLYDewPointTempC", "HOURLYSeaLevelPressure", "DAILYDeptFromNormalAverageTemp"
    ), row.names = c(NA, -20L), class = c("tbl_df", "tbl", "data.frame"
    ))

# define a function that accept strings as input
Plot_Graph <- function(df, x_var, y_var) {

  # convert strings to variable
  x_var <- rlang::sym(x_var)
  y_var <- rlang::sym(y_var)

  # unquote variable using !! 
  ggplot(df, aes(x = !! x_var, y = !! y_var)) + 
    geom_point() + 
    geom_line() +
    labs(x = rlang::quo_name(x_var), y = rlang::quo_name(y_var)) +
    scale_x_date(breaks = scales::pretty_breaks()) +
    theme_classic(base_size = 12)
}

Now loop through every column

plot_list <- colnames(philly_df_new)[-1] %>% 
  map( ~ Plot_Graph(philly_df_new, "DATE", .x))

plot_list
#> [[1]]

#> 
#> [[2]]

#> 
#> [[3]]

# Combine all plots
library(cowplot)

do.call(plot_grid, c(plot_list, 
                     align = "v",
                     axis = 'lr',
                     nrow = 3))

Created on 2018-08-27 by the reprex package (v0.2.0.9000).

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.