Reputation: 1780
I'm trying to create a custom function to return a chart object. This function seems to be having an error with calculating min/max/etc in the ggplot object.
If I run the code for the ggplot not inside a custom function it works.
To reproduce this error after I need to clear the memory with (rm(list = ls())) and reload the function and data.
How can I change my function to work correctly?
Sample data:
Date<-seq(as.Date("2000/1/1"), by = "week", length.out = 53*4)
ThousandBarrelsADay<-sample(1:1000, 53*4, replace=F)
yAxisTitle<-"Thousand Barrels per Day"
titleChart<-"test"
Function call:
p<-LinePlotTestStatsLine(Date, ThousandBarrelsADay, titleChart, yAxisTitle)
Error:
p
Error in eval(expr, envir, enclos) : object 'MinVal' not found
The code for the function:
LinePlotTestStatsLine<- function(xDateValues, yValues, titleChart, yAxisTitle) {
dfTemp=0
#the sub title outlining the data range
subtitleChart = paste("(Data set from ", min(xDateValues), " to ", max(xDateValues), ")", sep="")
#create a base dataframe
Week<- as.numeric(str_sub(ISOweek(xDateValues),start=-2))
dfTemp<-data.frame(xDateValues, Week, yValues)
dfTemp<- dfTemp[order(dfTemp$xDateValues),]
#Summary Stat by week
dfTemp_Out<-describeBy(dfTemp$yValues, dfTemp$Week, mat = TRUE)
colnames(dfTemp_Out)[2]<-"Week"
#get the last year's of data Use 53 weeks because some years have 53 weeks
tempLast53<- tail(dfTemp, 53-length(dfTemp$yValues))
LableDateMinMax<-tempLast53$xDateValues[13]
LableDateMedian<-tempLast53$xDateValues[20]
#Chrate a base table for charting
ChartData1<-join(dfTemp_Out, tempLast53, type="inner")
#make sure the chart table is sorted
ChartData1<- ChartData1[order(ChartData1$xDateValues),]
#find the max Date
MaxDate<- max(dfTemp$xDateValues)
maxYR<- max(year(dfTemp$xDateValues))
#min, Median, mean & max for hoizontal lines
MinVal<-min(dfTemp$yValues)
rMin<-max(which(dfTemp$yValues== MinVal, arr.ind = TRUE))
MinD<- dfTemp$xDateValues[rMin]
MaxVal<-max(dfTemp$yValues)
rMax<-max(which(dfTemp$yValues== MaxVal, arr.ind = TRUE))
MaxD<- dfTemp$xDateValues[rMax]
#Set the chart data
ChartData1_Plot <-ChartData1[,c("xDateValues","Week","yValues")]
ChartData1_Plot$Statistic<-paste("Past YR at ", MaxDate, sep="")
MedianVal<-median(dfTemp$yValues)
MeanVal<-mean(dfTemp$yValues)
stDev<- sd(dfTemp$yValues)
#ribbon to show one st. Dev.
Ribbon<-data.frame(ChartData1[,c("xDateValues")])
Ribbon$Lower<-MeanVal-stDev
Ribbon$Higher<-MeanVal+stDev
colnames(Ribbon)<-c("xDateValues", "Lower", "Higher")
Ribbon$mean<-ChartData1$mean
#Set the seasons for charting
#Spring March 20, 2013
dSpring <- as.Date(paste("03/20/",maxYR, sep=""), "%m/%d/%Y")
if (MaxDate<=dSpring) {
dSpring <- as.Date(paste("03/20/",maxYR-1, sep=""), "%m/%d/%Y")
}
#summer June 21, 2013
dSummer<-as.Date(paste("06/21/",maxYR, sep=""), "%m/%d/%Y")
if (MaxDate<=dSummer) {
dSummer<- as.Date(paste("06/21/",maxYR-1, sep=""), "%m/%d/%Y")
}
#Autumn September 22, 2013
dAutumn<-as.Date(paste("09/23/",maxYR, sep=""), "%m/%d/%Y")
if (MaxDate<=dAutumn) {
dAutumn<- as.Date(paste("09/23/",maxYR-1, sep=""), "%m/%d/%Y")
}
# winter December 21, 2013
dWinter<-as.Date(paste("12/21/",maxYR, sep=""), "%m/%d/%Y")
if (MaxDate<=dWinter) {
dWinter<- as.Date(paste("12/21/",maxYR-1, sep=""), "%m/%d/%Y")
}
ChartData_Plot <- ChartData1_Plot
p1<-ggplot(ChartData_Plot, aes(x=xDateValues,y=yValues))+
geom_line(aes(group=Statistic, colour=Statistic))+
scale_color_manual(values=c("black"))+
geom_ribbon(data=Ribbon, aes(group = 1, y=mean, x=xDateValues, ymin=Lower, ymax=Higher), alpha=0.1, fill="blue")+
geom_hline(aes(yintercept=MinVal), color="red", linetype="dashed")+
geom_hline(aes(yintercept=MaxVal), color="red", linetype="dashed")+
annotate(geom="text", x = LableDateMinMax, y = MinVal-MaxVal/90, label = paste("Min as at ", MinD, sep=""), colour = "red", size = 4)+
annotate(geom="text", x = LableDateMinMax, y = MaxVal+MaxVal/40, label = paste("Max as at ", MaxD, sep=""), colour = "red", size = 4)+
geom_hline(aes(yintercept=MedianVal), color="darkgreen", linetype="dashed")+
geom_hline(aes(yintercept=MeanVal), color="blue", linetype="dashed")+
annotate(geom="text", x = LableDateMinMax, y = MeanVal+MaxVal/40, label = paste("Mean", sep=""), colour = "blue", size = 4)+
annotate(geom="text", x = LableDateMedian, y = MedianVal+MaxVal/40, label = paste("Median", sep=""), colour = "darkgreen", size = 4)+
theme(legend.position="bottom")+
geom_vline(xintercept = as.numeric(dSpring),colour="darkgrey")+
geom_vline(xintercept = as.numeric(dSummer),colour="darkgrey")+
geom_vline(xintercept = as.numeric(dAutumn),colour="darkgrey")+
geom_vline(xintercept = as.numeric(dWinter),colour="darkgrey")+
annotate(geom="text", x = c(dWinter+45, dSpring+45, dSummer+45, dAutumn+45), y = MaxVal+MaxVal/10, label = c("Winter",
"Spring", "Summer", "Autumn"), colour = "darkgrey",
size = 4)+
ggtitle(bquote(atop(.(titleChart), atop(italic(.(subtitleChart)), ""))))+
labs(x = "")+
scale_x_date(breaks="4 weeks",labels = date_format("%b-%Y"))+
scale_y_continuous(labels = comma)+expand_limits(y = 0)+
theme(axis.text.x = element_text(size=10,angle=45,colour="black",vjust=1,hjust=1))+
labs(y = yAxisTitle)+
theme(legend.position="none")
Footnote<-"Note: Shaded area represents one standard deviation from the mean"
#p1<-arrangeGrob(p1, sub = textGrob(Footnote, x = 0, hjust = -0.1, vjust=0.1, gp = gpar(fontface = "italic", fontsize = 10)))
return(p1)
}
Upvotes: 2
Views: 952
Reputation: 1780
I have figured out the problem. I have not used environment before but it was a very simple fix.
To get the function to work:
.e <- environment() #at the start of the function
...
ggplot(ChartData_Plot, aes(x=xDateValues,y=yValues), environment = .e)
For a discussions on environments see:
http://www.r-bloggers.com/environments-in-r/
http://adv-r.had.co.nz/Environments.html
Upvotes: 3
Reputation: 2921
The function geom_hline
is looking for MinVal
inside the ChartData_Plot
data frame, where it does not exist. Add data = NULL
to the geom_hline
functions and it should be able to find the value.
Upvotes: 0