# Determining significant changes in slope in a GAM

by James White   Last Updated August 10, 2018 11:19 AM - source

I've read various online blogs and forums about obtaining this information, but I cannot seem to get the code to work. I have annual measurements and want to plot where significant changes in slope occur. I have read somewhere that scaling both the response and explanatory variable between 0-1 and examining where the gradient is >-1 or <1 denotes a significant period of changes, and first-order derivatives should be used for this. Can anyone verify this approach? And if so, suggest code how is best to achieve this? Ultimately, I would like to identify and plot (by highlighting in a different colour) periods of significant change, for two types of datasets like those outlined below. I have seen Gavin Simpson's helpful blog on this (https://www.r-bloggers.com/identifying-periods-of-change-in-time-series-with-gams/ ) but I cannot get it to work for my own data.

Example 1) Using a very basic dataset I can construct the following GAM and (I think) obtain first order derivatives. But I am not sure what to do from here.

``````##Create data and scale between 0 and 1
DF <- as.data.frame(seq(from = 1950, to = 2000, by = 1))
colnames(DF) <- "YEAR"
DF\$AVERAGE <- c(1:20,20,20,20,20,20,20:1,1,1,1,1,2,3)
range01 <- function(x){(x-min(x))/(max(x)-min(x))}
DF\$YEAR <- range01(DF\$YEAR)
DF\$AVERAGE <- range01(DF\$AVERAGE)

###Create GAM
library(mgcv)
GAM <- gam(AVERAGE ~ s(YEAR), data=DF)
plot(GAM)
newDF <- with(DF, data.frame(YEAR = unique(YEAR)))
X0 <- as.data.frame(predict(GAM, newDF, type = 'lpmatrix'))
``````

Example 2) I'd like to also identify and plot significant changes in slope for two GAM time series whereby values are nested within a factor (SITE here).

``````DF_NEW <- as.data.frame(seq(from = 1950, to = 2000, by = 1))
colnames(DF_NEW) <- "YEAR"
DF_NEW\$AVERAGE <- DF\$AVERAGE * -1

DF_NEW <- rbind(DF,DF_NEW)
DF_NEW\$SITE <- as.factor(rep(c("A","B"),each = 51))
DF_NEW\$YEAR <- range01(DF\$YEAR)
DF_NEW\$AVERAGE <- range01(DF\$AVERAGE)

GAM2 <- gam(AVERAGE ~ s(YEAR, by = SITE), data = DF_NEW)
``````

Thank you in advance for any help / suggestions.

Tags :