# Gumbel custom likelihood
# negative log likelihood
gumd0 <- function(pars, likdata) {
# this is needed, and should be fine
pars <- split(pars, likdata$idpars)
# likdata$X should be set up by evgam
mu <- likdata$X[[1]] %*% pars[[1]]
lsigma <- likdata$X[[2]] %*% pars[[2]]
y <- likdata$y
y <- (y - mu) * exp(-lsigma)
nllh <- sum(lsigma - y + exp(y))
return(nllh)
}
# first and second derivatives of neg. log lik. in order
# d_mu, d_lsigma, d_{mu, mu}, d_{mu, lsigma}, d_{lsigma, lsigma}
gumd12 <- function(pars, likdata) {
# this is needed, and should be fine
pars <- split(pars, likdata$idpars)
# likdata$X should be set up by evgam
mu <- likdata$X[[1]] %*% pars[[1]]
lsigma <- likdata$X[[2]] %*% pars[[2]]
y <- likdata$y
out <- matrix(0, length(y), 5)
ee1 <- exp(lsigma)
ee2 <- y - mu
ee3 <- ee2/ee1
ee4 <- exp(ee3)
ee5 <- (ee3 + 1) * ee4
ee6 <- 1 - ee4
# first derivatives
out[, 1] <- ee6/ee1
out[, 2] <- ee6 * ee2/ee1 + 1
# second derivatives
out[, 3] <- ee4/ee1^2
out[, 4] <- -((1 - ee5)/ee1)
out[, 5] <- (ee5 - 1) * ee2/ee1
return(out)
}
gum_fns <- list(d0 = gumd0, d120 = gumd12, d340 = NULL)
unlink <- list(NULL, function(x) exp(x))
attr(unlink[[2]], "deriv") <- unlink[[2]]
qgumbel <- function(p, pars1, pars2) pars1 - exp(pars2) * log(-log(p))
gum_fns$q <- qgumbel
gum_fns$unlink <- unlink
# \donttest{
data(COprcp)
COprcp <- cbind(COprcp, COprcp_meta[COprcp$meta_row,])
COprcp$year <- format(COprcp$date, "%Y")
COprcp_gev <- aggregate(prcp ~ year + meta_row, COprcp, max)
COprcp_gev <- cbind(COprcp_gev, COprcp_meta[COprcp_gev$meta_row,])
inits <- sqrt(6 * var(COprcp_gev$prcp) / pi^2)
inits <- c(mean(COprcp_gev$prcp) - inits[1] * 0.5772156649, log(inits[1]))
fmla_gum <- list(location = prcp ~ s(lon, lat) + s(elev), logscale = ~ s(lon, lat))
m <- evgam(fmla_gum, data = COprcp_gev, family = 'custom', custom.fns = gum_fns,
trace = 2, inits = inits)
predict(m, COprcp_gev[1:10,])
predict(m, COprcp_gev[1:10,], type = 'response')
predict(m, COprcp_gev[1:10,], prob = .99)
# }
Run the code above in your browser using DataLab