The “Global Warming Hiatus” analysed

afb001 Some of the warming or cooling we see has a  known cause. If we would be able “to subtract” those know externally caused effects, we would get a clearer idea of the extent of the global warming caused CO2, etc. That is the analysis done by Grant Foster and Stefan Rahmstorf in a 2011 paper called “Global temperature evolution 1979–2010”. I had the same idea and the execution in R is actually not too difficult

I have combined (and averaged) the three surface temperature records (from NASA/GISS,NOAA/NCDC and HadCRU) and tafb002wo lower-troposphere (LT)temperature records based on satellite microwave sensors (from RSS and UAH). 

That is my main series of monthly averages (start 1979 to May 2014) that I use in this analysis.

Step by step I calculate a linear effect after subtracting a known effect. As expected in each step the model gets a bit more accurate. The RMSE, root mean squared error is the standard measure for the goodness of fiafb003t

The first effect to subtract is a seasonal influence (rotation of the  earth around the sun). We fit a simple fourier series (sum of sines and cosines). This is a small effect. 

Then we move on to the solar variability. There are recent direct measurements from satellites, but they are difficult to use. Instead I use the wellknown sunspot cycle as a “proxy”. The fit becomes better with a time lag of 2 months. This impact is a little bit bigger than the yearly seasonal impact, maximum is about 0.05 degree. Maybe I should fit a non-linear function  here. I have yet to try that.

Third, volcanos.afb004

Volcanic Aerosols filter the sunlight, and therefore decrease the surface temperatures. The database contains two big eruption since 1979, and the effects, though temporarily, can be up to -0.2. As a consequence, the estimated increase due to CO2 goes down, but the model accuracy increases. The impact is at it’s maximum 5 months after the eruption.afb005

Finally, the ENSO (El Nino Southern Oscillation). This is a pattern of oceanic streams in the Southern Pacific that causes the El Nino phenomenon – a reversal of the streams that bring very warm water to the coast of South America. With swings of abou 0.3 degrees it has a considerable impact on the climate, so it also goes into our model. There are other oceanic oscillations that we could include, but they are even less well measured and understood than the ENSO. 

Residuals afb006

Now,  let’s look at the remainders that are now left. That is the “unexplained variance”.  I used a robust estimator all the way, outliers are less important when using a robust estimator. The mean of all residuals is slightly below 0.0: the negative outliers are a little bit bigger. The RMSE is the stan
dard deviation from that mean: around 0.1.

Conclusion. 

Taking known external influences into account, the estimate for the decadal increase due to global warming increases from 0.145 to 0.165 per decade. The “natural” variation left has a standard deviation of about 0.1 degree.  If we restrict the analysis to the period 1998-present, the increase is 0.07, halved but definitely not 0. 


Code (for analysis and figure 4).

source("readTS.R")
source("pretty.plot.R")
library("robust")

trial.name="Five averaged Time series"
read.rss(); read.gss(); read.uah(); read.ncd(); read.hc4()
trial= window((rss.ts+uah.ts+gss.ts+ncd.ts+hc4.ts)/5, start=1979)

read.mei()
read.ssp()
read.vol()
pvol=5; pssp=2; pmei=4
vol.lag<-lag(vol.ts, -pvol)
ssp.lag<-lag(ssp.ts, -pssp)
mei.lag<-lag(mei.ts, -pmei)

start.y<-1979
end.y<- end(trial)-c(0,1)
trial<-window(trial, start=start.y, end = end.y)
mei<-window(mei.lag, start=start.y, end = end.y)
ssp<-window(ssp.lag, start=start.y, end = end.y)
vol<-window(vol.lag, start=start.y, end = end.y)
year<-index(trial)
f1<-sin(2*pi*year)
f2<-cos(2*pi*year)
f3<-sin(4*pi*year)
f4<-cos(4*pi*year)

fanta<-lmRob(trial~year+f1+f2+f3+f4+ssp+vol+mei)

periodic.fit<-f1*fanta$coefficients['f1'] +
 f2*fanta$coefficients['f2'] +
 f3*fanta$coefficients['f3'] +
 f4*fanta$coefficients['f4']

ssp.fit <- ssp*fanta$coefficients['ssp']
vol.fit <- vol*fanta$coefficients['vol']
mei.fit <- mei*fanta$coefficients['mei']

yearfit<-fanta$fit - (ssp.fit+periodic.fit+vol.fit+mei.fit)
pretty.plot(ts.to.df(trial-periodic.fit)
 , kleur=2
 , main=sprintf("Trend after eliminating (known) external influences\n%s Time series; Robust lm", trial.name))
pretty.plot(data.frame(year, fanta$fit-periodic.fit), kleur=1, add=TRUE, lwd=2)
pretty.plot(data.frame(year, yearfit), kleur=3, lwd=2, add=TRUE)
pretty.legend("topleft", sprintf("Increase: %2.4f C per decade\nRMSE: %2.6f\nLag params: %d %d %d"
 , 10*fanta$coefficients['year']
 , RMSE<-sqrt(mean(fanta$res^2))
 , pvol, pssp, pmei))

Leave a Reply