Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot is not working properly inside a function despite working outside it - R

I am trying to create a function that takes in 2 parameters & outputs the appropriate ggplot for them. The code works perfectly manually, but somehow I cannot make it work inside a function wrapper.

The error returned is

Error in eval(expr, envir, enclos) : object 'TimeVector' not found

I try to correct for that by coercing the objects not found, which are added to ggplot, as strings. This in turn creates different trouble in form of

Error: Discrete value supplied to continuous scale

Removing the scale_x_continuous(breaks=0:24) fixes that second error, but outputs an empty graph, suggesting that ggplot is not fed with any data at all.

The data is a large data frame of observations of traffic density grouped by time. It looks like this:

ID                   Road Status                Time Statusint Day  Months Year Weekday

1 Me7war To Sheikh Zayid Orange 2012-10-01 00:03:00         3   1 October   12  Monday
1 Me7war To Sheikh Zayid  Green 2012-10-01 05:00:00         2   1 October   12  Monday
1 Me7war To Sheikh Zayid Yellow 2012-10-01 05:24:00         5   1 October   12  Monday

I am trying to plot the "Statusint" variable, short for status integer ranging from 1 (good traffic) to 5 (Terrible traffic) against the "Time" variable. "Time" is formatted as Posix, so I create a numeric vector called "TimeVector" for the sole purpose of plotting against in ggplot.

The function is as follows:

Plotroad <- function( roadID , Day ) {

  *** Working Code ***

  else { 

  ### THE PROBLEM CODE: Everything below works manually, but returns an error in the function

    Roadsubset <- October[October$ID == as.numeric(roadID), ] 
    Timesubset <- subset(Roadsubset, format(Roadsubset$Time,'%d') == "Day" )
    TimeVector <- as.numeric(gsub(":" , "." , strftime(Timesubset$Time, format="%H:%M")))

    ggplot(Timesubset, aes( x = "TimeVector", y = "Timesubset$Statusint")) + geom_point() +  
        stat_smooth() + scale_x_continuous(breaks=0:24) 


    ### The working code: 
    Roadsubset <- October[October$ID == as.numeric(roadID), ] 
    Timesubset <- subset(Roadsubset, subset = Roadsubset$Day == as.integer(Date) )
    TimeVector <- as.numeric(gsub(":" , "." , strftime(Timesubset$Time, format="%H:%M")))
    Timesubset$timevector <- TimeVector

    print(ggplot( data = Timesubset, aes_string( x = "timevector" , y = "Statusint" )) + geom_point() + stat_smooth()  + scale_x_continuous(breaks=0:24) + labs(list(title = as.character(Timesubset$Road[1]) , x = "Time of Day", y = "Status")))  

  }
}

I have seen some advice suggesting using print, as ggplot is invoked not in the command line. This, however does not fix the aforementioned errors.

This is my first post to stack overflow, so please point out how I can better format questions for the future, if in need. Thanks.

like image 935
M. Momtaz Hegazy Avatar asked Dec 30 '13 18:12

M. Momtaz Hegazy


1 Answers

Aside from using variable names, there is an issue with scope. GGPlot carries out non-standard evaluation in the global environment, so anything defined in your function is not directly accessible, except for the "data" argument since that one is passed explicitly and not through non-standard evaluation. So one work around to this problem is to add your variable to the data argument. I've created an example that I think mimics your problem, but since I don't have your data it's not identical:

gg_fun <- function() {
  data <- data.frame(a=1:10, b=1:10)
  clr <- rep(c("a", "b"), 5)
  ggplot(data, aes(x=a, y=b, color=clr)) + geom_point()
}
gg_fun()
# Error in eval(expr, envir, enclos) : object 'clr' not found
gg_fun <- function() {
  data <- data.frame(a=1:10, b=1:10)
  clr <- rep(c("a", "b"), 5)
  data$clr <- clr
  ggplot(data, aes(x=a, y=b, color=clr)) + geom_point()
}
gg_fun() # works

In your case, you need to add TimeVector to Timesubset (trivial), and then use the unquoted aes syntax:

ggplot(Timesubset, aes(x=TimeVector, y=Statusint)) ...
like image 140
BrodieG Avatar answered Oct 21 '22 08:10

BrodieG