Comme vous l’avez vu en cours nous allons utiliser le package geoR pour faire notre analyse spatiale. Nous allons reprendre l’analyse du jeu de donnees de concentration en Calcium vu en cours. Attention toutefois je ne commenterai pas les résultats car nous l’avons déjà fait en cours. Le but de ce document est simplement de vous aider dans l’utilisation de geoR (et autres)…

  1. Analyse descriptive

Après avoir importé les données et vérifié qu’il n’y avait pas de valeurs abérantes, nous faisons donc un symbol plot

library(geoR)
data(ca20)
## Mon code pour le symbol plot
par(ps = 14, mar = c(4, 5, 0.5, 0.5))
plot(ca20$borders, type = "l", xlab = "Longitude", ylab = "Latitude",
     asp = 1)
lines(ca20$reg1, lty = 2)
lines(ca20$reg2, lty = 2)
lines(ca20$reg3, lty = 2)
symbols(ca20$coord, circles = abs(ca20$data-mean(ca20$data)),
        bg = c("blue", "red")[1 + as.numeric(ca20$data > mean(ca20$data))],
        inches = FALSE, add = TRUE)
text(ca20$coord, labels = round(ca20$data, 1), cex = 0.5)
par(mfrow = c(1, 4), ps = 20, mar = c(4, 5, 0.75, 0.5))

plot(ca20$coord[,1], ca20$data, xlab = "Longitude", ylab = "Ca")
lines(lowess(ca20$coord[,1], ca20$data), col = "orange")
plot(ca20$coord[,2], ca20$data, xlab = "Latitude", ylab = "Ca")
lines(lowess(ca20$coord[,2], ca20$data), col = "orange")
plot(ca20$covariate[,"altitude"], ca20$data, xlab = "Altitude", ylab = "Ca")
lines(lowess(ca20$covariate[,"altitude"], ca20$data), col = "orange")
plot(ca20$covariate[,"area"], ca20$data, xlab = "Sous-region", ylab = "Ca")

Cela dit puisque le jeu de données Ca20 est au format geodata, il existe une méthode pour cela (mais en pratique ce ne sera pas le cas à moins de convertir vous même vos données au format geodata)

plot(ca20)

Passons au variogramme empirique.

vario.emp <- variog(coords = ca20$coords, data = ca20$data)
variog: computing omnidirectional variogram
plot(vario.emp)

## On aurait pu faire directement plot(variog(ca20)) car ca20 est de classe geodata

Pour avoir un variogramme empirique directionnel

plot(variog4(coords = ca20$coords, data = ca20$data))
variog: computing variogram for direction = 0 degrees (0 radians)
        tolerance angle = 22.5 degrees (0.393 radians)
variog: computing variogram for direction = 45 degrees (0.785 radians)
        tolerance angle = 22.5 degrees (0.393 radians)
variog: computing variogram for direction = 90 degrees (1.571 radians)
        tolerance angle = 22.5 degrees (0.393 radians)
variog: computing variogram for direction = 135 degrees (2.356 radians)
        tolerance angle = 22.5 degrees (0.393 radians)
variog: computing omnidirectional variogram

  1. Modélisation paramétrique

Deux approches sont alors possibles : soit l’on ajuste un variograme paramétrique via les moindres carrés (généralisés ou pas) soit en ajustant directement un processus gaussien.

fit.vario <- variofit(vario.emp, cov.model = "stable", fix.nugget = TRUE)##ici on fait confiance au package pour qu'il trouve de bonnes valeurs initiales, sinon on fait comme dit en cours ;-)
variofit: covariance model used is powered.exponential 
variofit: weights used: npairs 
variofit: minimisation function used: optim 
initial values not provided - running the default search
variofit: searching for best initial value ... selected values:
              sigmasq  phi     tausq kappa
initial.value "153.65" "175.1" "0"   "0.5"
status        "est"    "est"   "fix" "fix"
loss value: 3360490.37531911 
plot(vario.emp, ylim = c(0, 200))
lines(fit.vario, col = "seagreen3")

Bon d’accord mais c’est un peu nul ce que l’on a fait non car il y a un effet de la sous-région ! On en tient compte alors

vario.emp2 <- variog(ca20, trend = ~ area)
variog: computing omnidirectional variogram
plot(vario.emp2)
fit.vario2 <- variofit(vario.emp2, fix.nugget = TRUE)
variofit: covariance model used is matern 
variofit: weights used: npairs 
variofit: minimisation function used: optim 
initial values not provided - running the default search
variofit: searching for best initial value ... selected values:
              sigmasq  phi     tausq kappa
initial.value "106.36" "175.1" "0"   "0.5"
status        "est"    "est"   "fix" "fix"
loss value: 1762223.86576382 
lines(fit.vario2, col = "seagreen3")

Maintenant si je veux passer par l’ajustement d’un processus gaussien

fit.gp <- likfit(ca20, trend = ~ area, fix.nugget = TRUE, ini.cov.pars = c(100, 100), cov.model = "stable", fix.kappa = FALSE)
---------------------------------------------------------------
likfit: likelihood maximisation using the function optim.
likfit: Use control() to pass additional
         arguments for the maximisation function.
        For further details see documentation for optim.
likfit: It is highly advisable to run this function several
        times with different initial values for the parameters.
likfit: WARNING: This step can be time demanding!
---------------------------------------------------------------
likfit: end of numerical maximisation.

Comparons à la fonction que nous avons fait en cours et disponible ici

url <- "http://imag.umontpellier.fr/~ribatet/docs/Geostatistique/fitgp.R"
source(url)
fit.gp.mine <- myfitgp(data = ca20$data, coords = ca20$coords,
                       trend = ~ area, covariables = ca20$covariate, iterlim = 1000)

Je vous laisse voir que nous trouvons les mêmes résultats. Conclusion on est trop fort non ?

  1. Krigeage

Le plus simple consiste à passer un variogramme ajusté ou un processus gaussien ajusté directement à la fonction faisant le krigeage.

gr <- pred_grid(ca20$borders, by = 2.5)## points ou l'on veut predire
gr0 <- polygrid(gr, borders = ca20$borders, bound = TRUE)## on se restreint a la region d'etude et on n'ira pas en dehors
ind.reg <- numeric(nrow(gr0))
ind.reg[.geoR_inout(gr0, ca20$reg1)] <- 1
ind.reg[.geoR_inout(gr0, ca20$reg2)] <- 2
ind.reg[.geoR_inout(gr0, ca20$reg3)] <- 3
ind.reg <- as.factor(ind.reg)##ici j'ai affecte le numero de la sous region a chaque point de prediction
KC <- krige.control(obj.model = fit.gp, trend.d = ~ area, trend.l = ~ ind.reg)
ca20pred <- krige.conv(ca20, loc = gr, krige = KC)
krige.conv: results will be returned only for prediction locations inside the borders
krige.conv: model with mean defined by covariates provided by the user
krige.conv: Kriging performed using global neighbourhood 
## Ouf on peut faire le graphique
par(mfrow = c(1, 2), mar = c(4, 5, 0.5, 0.5), ps = 14)
##plot(variog(ca20), xlab = expression(h), ylab = expression(gamma(h)))
##f <- function(h) (16.77 + 135.17) - (16.77 * as.numeric(h == 0) + 135.17) * exp(-h / 159.49)
##curve(f, from = 0, to = 1500, col = "orange", add = TRUE)
image(ca20pred, loc = gr, y.leg = c(4790, 4840), x.leg = c(4930, 5350),
      col = heat.colors(64), breaks = seq(15, 80, length = 65),
      zlim = c(15, 80))
lines(ca20$reg1, lty = 2)
lines(ca20$reg2, lty = 2)
lines(ca20$reg3, lty = 2)
text(ca20$coord, labels = ca20$data, cex = 0.75)
image(ca20pred, loc = gr, y.leg = c(4790, 4840), x.leg = c(4930, 5350),
      val = sqrt(ca20pred$krige.var), col = heat.colors(64), breaks = seq(0, 13, length = 65),
      zlim = c(0, 13))
lines(ca20$reg1, lty = 2)
lines(ca20$reg2, lty = 2)
lines(ca20$reg3, lty = 2)
points(ca20$coord, pch = 15)

LS0tCnRpdGxlOiAiRmFpcmUgZGUgbGEgZ8Opb3N0YXRpc3RpcXVlIGF2ZWMgUiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKQ29tbWUgdm91cyBsJ2F2ZXogdnUgZW4gY291cnMgbm91cyBhbGxvbnMgdXRpbGlzZXIgbGUgcGFja2FnZSBnZW9SIHBvdXIgZmFpcmUgbm90cmUgYW5hbHlzZSBzcGF0aWFsZS4gTm91cyBhbGxvbnMgcmVwcmVuZHJlIGwnYW5hbHlzZSBkdSBqZXUgZGUgZG9ubmVlcyBkZSBjb25jZW50cmF0aW9uIGVuIENhbGNpdW0gdnUgZW4gY291cnMuIEF0dGVudGlvbiB0b3V0ZWZvaXMgamUgbmUgY29tbWVudGVyYWkgcGFzIGxlcyByw6lzdWx0YXRzIGNhciBub3VzIGwnYXZvbnMgZMOpasOgIGZhaXQgZW4gY291cnMuIExlIGJ1dCBkZSBjZSBkb2N1bWVudCBlc3Qgc2ltcGxlbWVudCBkZSB2b3VzIGFpZGVyIGRhbnMgbCd1dGlsaXNhdGlvbiBkZSBnZW9SIChldCBhdXRyZXMpLi4uCgoxLiBBbmFseXNlIGRlc2NyaXB0aXZlCgpBcHLDqHMgYXZvaXIgaW1wb3J0w6kgbGVzIGRvbm7DqWVzIGV0IHbDqXJpZmnDqSBxdSdpbCBuJ3kgYXZhaXQgcGFzIGRlIHZhbGV1cnMgYWLDqXJhbnRlcywgbm91cyBmYWlzb25zIGRvbmMgdW4gKnN5bWJvbCBwbG90KgpgYGB7cn0KbGlicmFyeShnZW9SKQpkYXRhKGNhMjApCgojIyBNb24gY29kZSBwb3VyIGxlIHN5bWJvbCBwbG90CnBhcihwcyA9IDE0LCBtYXIgPSBjKDQsIDUsIDAuNSwgMC41KSkKcGxvdChjYTIwJGJvcmRlcnMsIHR5cGUgPSAibCIsIHhsYWIgPSAiTG9uZ2l0dWRlIiwgeWxhYiA9ICJMYXRpdHVkZSIsCiAgICAgYXNwID0gMSkKbGluZXMoY2EyMCRyZWcxLCBsdHkgPSAyKQpsaW5lcyhjYTIwJHJlZzIsIGx0eSA9IDIpCmxpbmVzKGNhMjAkcmVnMywgbHR5ID0gMikKc3ltYm9scyhjYTIwJGNvb3JkLCBjaXJjbGVzID0gYWJzKGNhMjAkZGF0YS1tZWFuKGNhMjAkZGF0YSkpLAogICAgICAgIGJnID0gYygiYmx1ZSIsICJyZWQiKVsxICsgYXMubnVtZXJpYyhjYTIwJGRhdGEgPiBtZWFuKGNhMjAkZGF0YSkpXSwKICAgICAgICBpbmNoZXMgPSBGQUxTRSwgYWRkID0gVFJVRSkKdGV4dChjYTIwJGNvb3JkLCBsYWJlbHMgPSByb3VuZChjYTIwJGRhdGEsIDEpLCBjZXggPSAwLjUpCgpwYXIobWZyb3cgPSBjKDEsIDQpLCBwcyA9IDIwLCBtYXIgPSBjKDQsIDUsIDAuNzUsIDAuNSkpCnBsb3QoY2EyMCRjb29yZFssMV0sIGNhMjAkZGF0YSwgeGxhYiA9ICJMb25naXR1ZGUiLCB5bGFiID0gIkNhIikKbGluZXMobG93ZXNzKGNhMjAkY29vcmRbLDFdLCBjYTIwJGRhdGEpLCBjb2wgPSAib3JhbmdlIikKcGxvdChjYTIwJGNvb3JkWywyXSwgY2EyMCRkYXRhLCB4bGFiID0gIkxhdGl0dWRlIiwgeWxhYiA9ICJDYSIpCmxpbmVzKGxvd2VzcyhjYTIwJGNvb3JkWywyXSwgY2EyMCRkYXRhKSwgY29sID0gIm9yYW5nZSIpCnBsb3QoY2EyMCRjb3ZhcmlhdGVbLCJhbHRpdHVkZSJdLCBjYTIwJGRhdGEsIHhsYWIgPSAiQWx0aXR1ZGUiLCB5bGFiID0gIkNhIikKbGluZXMobG93ZXNzKGNhMjAkY292YXJpYXRlWywiYWx0aXR1ZGUiXSwgY2EyMCRkYXRhKSwgY29sID0gIm9yYW5nZSIpCnBsb3QoY2EyMCRjb3ZhcmlhdGVbLCJhcmVhIl0sIGNhMjAkZGF0YSwgeGxhYiA9ICJTb3VzLXJlZ2lvbiIsIHlsYWIgPSAiQ2EiKQpgYGAKCkNlbGEgZGl0IHB1aXNxdWUgbGUgamV1IGRlIGRvbm7DqWVzIENhMjAgZXN0IGF1IGZvcm1hdCBnZW9kYXRhLCBpbCBleGlzdGUgdW5lIG3DqXRob2RlIHBvdXIgY2VsYSAobWFpcyBlbiBwcmF0aXF1ZSBjZSBuZSBzZXJhIHBhcyBsZSBjYXMgw6AgbW9pbnMgZGUgY29udmVydGlyIHZvdXMgbcOqbWUgdm9zIGRvbm7DqWVzIGF1IGZvcm1hdCBnZW9kYXRhKQpgYGB7cn0KcGxvdChjYTIwKQpgYGAKClBhc3NvbnMgYXUgdmFyaW9ncmFtbWUgZW1waXJpcXVlLgpgYGB7cn0KdmFyaW8uZW1wIDwtIHZhcmlvZyhjb29yZHMgPSBjYTIwJGNvb3JkcywgZGF0YSA9IGNhMjAkZGF0YSkKcGxvdCh2YXJpby5lbXApCiMjIE9uIGF1cmFpdCBwdSBmYWlyZSBkaXJlY3RlbWVudCBwbG90KHZhcmlvZyhjYTIwKSkgY2FyIGNhMjAgZXN0IGRlIGNsYXNzZSBnZW9kYXRhCmBgYAoKUG91ciBhdm9pciB1biB2YXJpb2dyYW1tZSBlbXBpcmlxdWUgZGlyZWN0aW9ubmVsCmBgYHtyfQpwbG90KHZhcmlvZzQoY29vcmRzID0gY2EyMCRjb29yZHMsIGRhdGEgPSBjYTIwJGRhdGEpKQpgYGAKCjIuIE1vZMOpbGlzYXRpb24gcGFyYW3DqXRyaXF1ZQoKRGV1eCBhcHByb2NoZXMgc29udCBhbG9ycyBwb3NzaWJsZXMgOiBzb2l0IGwnb24gYWp1c3RlIHVuIHZhcmlvZ3JhbWUgcGFyYW3DqXRyaXF1ZSB2aWEgbGVzIG1vaW5kcmVzIGNhcnLDqXMgKGfDqW7DqXJhbGlzw6lzIG91IHBhcykgc29pdCBlbiBhanVzdGFudCBkaXJlY3RlbWVudCB1biBwcm9jZXNzdXMgZ2F1c3NpZW4uCgpgYGB7cn0KZml0LnZhcmlvIDwtIHZhcmlvZml0KHZhcmlvLmVtcCwgY292Lm1vZGVsID0gInN0YWJsZSIsIGZpeC5udWdnZXQgPSBUUlVFKSMjaWNpIG9uIGZhaXQgY29uZmlhbmNlIGF1IHBhY2thZ2UgcG91ciBxdSdpbCB0cm91dmUgZGUgYm9ubmVzIHZhbGV1cnMgaW5pdGlhbGVzLCBzaW5vbiBvbiBmYWl0IGNvbW1lIGRpdCBlbiBjb3VycyA7LSkKCnBsb3QodmFyaW8uZW1wLCB5bGltID0gYygwLCAyMDApKQpsaW5lcyhmaXQudmFyaW8sIGNvbCA9ICJzZWFncmVlbjMiKQpgYGAKCkJvbiBkJ2FjY29yZCBtYWlzIGMnZXN0IHVuIHBldSBudWwgY2UgcXVlIGwnb24gYSBmYWl0IG5vbiBjYXIgaWwgeSBhIHVuIGVmZmV0IGRlIGxhIHNvdXMtcsOpZ2lvbiAhIE9uIGVuIHRpZW50IGNvbXB0ZSBhbG9ycwpgYGB7cn0KdmFyaW8uZW1wMiA8LSB2YXJpb2coY2EyMCwgdHJlbmQgPSB+IGFyZWEpCnBsb3QodmFyaW8uZW1wMikKCmZpdC52YXJpbzIgPC0gdmFyaW9maXQodmFyaW8uZW1wMiwgZml4Lm51Z2dldCA9IFRSVUUpCmxpbmVzKGZpdC52YXJpbzIsIGNvbCA9ICJzZWFncmVlbjMiKQpgYGAKCk1haW50ZW5hbnQgc2kgamUgdmV1eCBwYXNzZXIgcGFyIGwnYWp1c3RlbWVudCBkJ3VuIHByb2Nlc3N1cyBnYXVzc2llbgpgYGB7cn0KZml0LmdwIDwtIGxpa2ZpdChjYTIwLCB0cmVuZCA9IH4gYXJlYSwgZml4Lm51Z2dldCA9IFRSVUUsIGluaS5jb3YucGFycyA9IGMoMTAwLCAxMDApLCBjb3YubW9kZWwgPSAic3RhYmxlIiwgZml4LmthcHBhID0gRkFMU0UpCmBgYAoKCkNvbXBhcm9ucyDDoCBsYSBmb25jdGlvbiBxdWUgbm91cyBhdm9ucyBmYWl0IGVuIGNvdXJzIGV0IGRpc3BvbmlibGUgaWNpIFx1cmx7aHR0cDovL2ltYWcudW1vbnRwZWxsaWVyLmZyL35yaWJhdGV0L2RvY3MvR2Vvc3RhdGlzdGlxdWUvZml0Z3AuUn0KCmBgYHtyfQp1cmwgPC0gImh0dHA6Ly9pbWFnLnVtb250cGVsbGllci5mci9+cmliYXRldC9kb2NzL0dlb3N0YXRpc3RpcXVlL2ZpdGdwLlIiCnNvdXJjZSh1cmwpCgpmaXQuZ3AubWluZSA8LSBteWZpdGdwKGRhdGEgPSBjYTIwJGRhdGEsIGNvb3JkcyA9IGNhMjAkY29vcmRzLAogICAgICAgICAgICAgICAgICAgICAgIHRyZW5kID0gfiBhcmVhLCBjb3ZhcmlhYmxlcyA9IGNhMjAkY292YXJpYXRlLCBpdGVybGltID0gMTAwMCkKYGBgCkplIHZvdXMgbGFpc3NlIHZvaXIgcXVlIG5vdXMgdHJvdXZvbnMgbGVzIG3Dqm1lcyByw6lzdWx0YXRzLiBDb25jbHVzaW9uIG9uIGVzdCB0cm9wIGZvcnQgbm9uID8KCjMuIEtyaWdlYWdlCgpMZSBwbHVzIHNpbXBsZSBjb25zaXN0ZSDDoCBwYXNzZXIgdW4gdmFyaW9ncmFtbWUgYWp1c3TDqSBvdSB1biBwcm9jZXNzdXMgZ2F1c3NpZW4gYWp1c3TDqSBkaXJlY3RlbWVudCDDoCBsYSBmb25jdGlvbiBmYWlzYW50IGxlIGtyaWdlYWdlLgpgYGB7cn0KZ3IgPC0gcHJlZF9ncmlkKGNhMjAkYm9yZGVycywgYnkgPSAyLjUpIyMgcG9pbnRzIG91IGwnb24gdmV1dCBwcmVkaXJlCmdyMCA8LSBwb2x5Z3JpZChnciwgYm9yZGVycyA9IGNhMjAkYm9yZGVycywgYm91bmQgPSBUUlVFKSMjIG9uIHNlIHJlc3RyZWludCBhIGxhIHJlZ2lvbiBkJ2V0dWRlIGV0IG9uIG4naXJhIHBhcyBlbiBkZWhvcnMKaW5kLnJlZyA8LSBudW1lcmljKG5yb3coZ3IwKSkKaW5kLnJlZ1suZ2VvUl9pbm91dChncjAsIGNhMjAkcmVnMSldIDwtIDEKaW5kLnJlZ1suZ2VvUl9pbm91dChncjAsIGNhMjAkcmVnMildIDwtIDIKaW5kLnJlZ1suZ2VvUl9pbm91dChncjAsIGNhMjAkcmVnMyldIDwtIDMKaW5kLnJlZyA8LSBhcy5mYWN0b3IoaW5kLnJlZykjI2ljaSBqJ2FpIGFmZmVjdGUgbGUgbnVtZXJvIGRlIGxhIHNvdXMgcmVnaW9uIGEgY2hhcXVlIHBvaW50IGRlIHByZWRpY3Rpb24KCktDIDwtIGtyaWdlLmNvbnRyb2wob2JqLm1vZGVsID0gZml0LmdwLCB0cmVuZC5kID0gfiBhcmVhLCB0cmVuZC5sID0gfiBpbmQucmVnKQpjYTIwcHJlZCA8LSBrcmlnZS5jb252KGNhMjAsIGxvYyA9IGdyLCBrcmlnZSA9IEtDKQoKIyMgT3VmIG9uIHBldXQgZmFpcmUgbGUgZ3JhcGhpcXVlCnBhcihtZnJvdyA9IGMoMSwgMiksIG1hciA9IGMoNCwgNSwgMC41LCAwLjUpLCBwcyA9IDE0KQoKIyNwbG90KHZhcmlvZyhjYTIwKSwgeGxhYiA9IGV4cHJlc3Npb24oaCksIHlsYWIgPSBleHByZXNzaW9uKGdhbW1hKGgpKSkKIyNmIDwtIGZ1bmN0aW9uKGgpICgxNi43NyArIDEzNS4xNykgLSAoMTYuNzcgKiBhcy5udW1lcmljKGggPT0gMCkgKyAxMzUuMTcpICogZXhwKC1oIC8gMTU5LjQ5KQojI2N1cnZlKGYsIGZyb20gPSAwLCB0byA9IDE1MDAsIGNvbCA9ICJvcmFuZ2UiLCBhZGQgPSBUUlVFKQoKaW1hZ2UoY2EyMHByZWQsIGxvYyA9IGdyLCB5LmxlZyA9IGMoNDc5MCwgNDg0MCksIHgubGVnID0gYyg0OTMwLCA1MzUwKSwKICAgICAgY29sID0gaGVhdC5jb2xvcnMoNjQpLCBicmVha3MgPSBzZXEoMTUsIDgwLCBsZW5ndGggPSA2NSksCiAgICAgIHpsaW0gPSBjKDE1LCA4MCkpCmxpbmVzKGNhMjAkcmVnMSwgbHR5ID0gMikKbGluZXMoY2EyMCRyZWcyLCBsdHkgPSAyKQpsaW5lcyhjYTIwJHJlZzMsIGx0eSA9IDIpCnRleHQoY2EyMCRjb29yZCwgbGFiZWxzID0gY2EyMCRkYXRhLCBjZXggPSAwLjc1KQoKaW1hZ2UoY2EyMHByZWQsIGxvYyA9IGdyLCB5LmxlZyA9IGMoNDc5MCwgNDg0MCksIHgubGVnID0gYyg0OTMwLCA1MzUwKSwKICAgICAgdmFsID0gc3FydChjYTIwcHJlZCRrcmlnZS52YXIpLCBjb2wgPSBoZWF0LmNvbG9ycyg2NCksIGJyZWFrcyA9IHNlcSgwLCAxMywgbGVuZ3RoID0gNjUpLAogICAgICB6bGltID0gYygwLCAxMykpCmxpbmVzKGNhMjAkcmVnMSwgbHR5ID0gMikKbGluZXMoY2EyMCRyZWcyLCBsdHkgPSAyKQpsaW5lcyhjYTIwJHJlZzMsIGx0eSA9IDIpCnBvaW50cyhjYTIwJGNvb3JkLCBwY2ggPSAxNSkKYGBgCgoK