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.
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)) ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With