Reputation: 2861
I am trying to create a GGPLOT2 smoothed line graph that looks more like this
Source: http://www.esrl.noaa.gov/psd/enso/mei/
and less like this:
Source: https://dl.dropboxusercontent.com/u/16400709/StackOverflow/Rplot02.png
My data are available on dropbox.
Having looked at previous posts I used the code below:
#MEI Line Graph
d4 <- read.csv("https://dl.dropboxusercontent.com/u/16400709/StackOverflow/Data_MEI.csv")
head(d4,n=20)
MEI<-ggplot(d4,aes(x=d4$Date, y=d4$MEI,group=1))+geom_line()
MEI+stat_smooth(method ="auto",level=0.95)
What I think I need is to reduce the amount of smoothing taking place, but I have yet to figure out how to achieve this.
d4s<-SMA(d4$MEI,n=8)
plot.ts(d4s)
SMA() works well but I cant get it to work with ggplot Any hints would be appreciated!
Upvotes: 3
Views: 5591
Reputation: 5056
Be aware that the MEI index is for a 2-month period, so it's already got some smoothing built in. Assuming that you are using the MEI data that NOAA ESRL publishes, you should be able to create the same plot.
First of all you need to get the system set up, as you'll be working with timezeones:
# set things up ----
working.dir = file.path('/code/R/StackOverflow/')
setwd(working.dir)
Sys.setenv(TZ='GMT')
now, download your data and read it in
d.in <- read.csv("MEI.txt")
The next step is to get the dates formatted properly.
d.in$Date <- as.POSIXct(d.in$Date,
format = "%d/%m/%Y",
tz = "GMT")
and because we need to figure out where things cross the x-axis, we'll have to work in decimal dates. Use the Epoch value:
d <- data.frame(x = as.numeric(format(d.in$Date,
'%s')),
y = d.in$MEI)
Now we can figure out the zero-crossings. We'll use Beroe's example for that.
rx <- do.call("rbind",
sapply(1:(nrow(d)-1), function(i){
f <- lm(x~y, d[i:(i+1),])
if (f$qr$rank < 2) return(NULL)
r <- predict(f, newdata=data.frame(y=0))
if(d[i,]$x < r & r < d[i+1,]$x)
return(data.frame(x=r,y=0))
else return(NULL)
}))
and tack that on the end of the initial data:
d2 <- rbind(d,rx)
now convert back to dates:
d2$date <- as.POSIXct(d2$x,
origin = "1960-01-01",
format = "%s",
tz = "GMT")
now we can do the plot:
require(ggplot2)
ggplot(d2,aes(x = date,
y = y)) +
geom_area(data=subset(d2, y<=0), fill="blue") +
geom_area(data=subset(d2, y>=0), fill="red") +
scale_y_continuous(name = "MEI")
and that gives you this:
Now, do you really need to smooth this?
Upvotes: 10