class: center, middle, inverse, title-slide .title[ # SMD-Dismo ] .author[ ### Javier MontaƱo Chiriboga ] .date[ ### 2023-05-18 ] --- background-image: url(https://www.azquotes.com/picture-quotes/quote-all-models-are-wrong-but-some-are-useful-george-e-p-box-53-42-27.jpg) --- class: center, middle # Modelos de Distribusion de Especies (SDM) ## con MaXent --- background-image: url(https://vignette.wikia.nocookie.net/jkenterprises/images/4/48/Golem%2Bof%2BPrague.jpg/revision/latest?cb=20170115084655) --- background-image: url(https://i.pinimg.com/originals/88/ac/bf/88acbfec6866a3ac0765dfd296e1323c.jpg) --- ## Fuentes de Datos (Dataset) -- - Collectas -- - Datos de Biodiversidad(ocurrencias) -- - Herbarios -- - etc.. -- --- ##Descarga desde **GBIF** -- En esta ocasion vamos a obtener los datos desde los registros almacenados en el GBIF -- . Una forma es descargar los datos directamente desde la pagina del GBIF, mendiante un identificardor de objeto digital (DOI) -- . Una alternativa es descargar directamente de R desde el paquete *rgbif*  --- ###Instalar **rgbif** -- Para instalar el paquete se usa la funcion *install.packages* e.g `install.packages("rgbif")` -- Para usar el paquete se debe previamente instalar, luego de la instalacion se carga el paquete con la funcion *library* ```r library(rgbif) #para instalar el paquete install.package("rgbif") ``` ---  --- -Es importante tener cuenta en el gbif para usar sin limites rgbif  --- -Para descargar es necesario encontrar el ID de la especie en la base de datos del GBIF, los ID se encuentran en la funcion `name_backbone_checklist()` ```r spp <- c("Herpothallon rubrocinctum") gb <- data.frame(Especie = spp) keys <- gb %>% pull("Especie") %>% name_backbone_checklist() %>% filter(!matchType == "NONE") %>% pull(usageKey) #crea un archivo con los codigos del gbif ``` --- ###Descargar datos de ocurrencias Para descargar sin limite alguno se usa la funcion `occ_download()`, una alternativa a esta funcion es la `occ_search()` donde no es necesario colocar tu cuenta, pero tiene un limite de registros. ```r keys1 <- occ_download( pred_in("taxonKey", keys), pred("country", "CO"), #registros de Colombia pred("hasCoordinate", TRUE), pred("occurrenceStatus","PRESENT"), format = "SIMPLE_CSV", user = cuenta, pwd = contras, email = correo ) #para descargar los registros keys2 <- grep("^", keys1, value = T) keys2 ``` ``` ## [1] "0257166-230224095556074" ``` --- ### Datos Espaciales Mientras se descargan los datos vamos a manejar los datos espaciales. --- Lo primero que vamos a hacer en conseguir el mapa de Colombia. ```r colombia1 <- getData('GADM' , country = "COL", level = 1) #shape de Colombia plot(colombia1) ``` <img src="diapo_files/figure-html/mapa-1.png" style="display: block; margin: auto;" /> --- datos ambientales que vamos a usar para el modelo <img src="diapo_files/figure-html/clima-1.png" style="display: block; margin: auto;" /> --- La informacion climatica se obtiene en formato raster, basicamente es una matrix, donde cada elemento o pixel tiene un dato y para graficarlo a cada dato se le asigna un color.  --- Los raster pueden estar en juntos en diferentes capas o en solo una capa  ---  {width=50% height=50%} b --- luego procedemos a cortar los datos de raster para que tengan la misma extencion que nuestor mapa de Colombia. para eso primero usamos la funcion `crop()` del paquete que corta el raster en un cuadrado de extencion cercana al mapa que tenemos. -- Luego con la funcion `mask()` se corta el rater para que tenga una forma cercana a la de nuestro mapa <img src="diapo_files/figure-html/mask-1.png" style="display: block; margin: auto;" /> --- Para tener en cuenta todas las variables, estas se combinan en un raster mutiple. ```r cb <- list(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20) clima <- stack(cb) #se combinan todos los rasters plot(clima) ``` <!-- --> --- Ahora con el mapa debemos cargar los datos de las ocurrencias que descargamos del GBIF a R, para poder modelar la distribucion. ```r d <- occ_download_get("0252496-230224095556074") %>% occ_download_import() #archivo con los datos d1 <- d[, c(10, 22, 23, 36)] #solo dejar el nombre, las coordenadas y el tipo de observacion colnames(d1) <- c("especies", "lat", "lon", "basisOfRecord") knitr::kable(head(d1), format = 'html') ``` <table> <thead> <tr> <th style="text-align:left;"> especies </th> <th style="text-align:right;"> lat </th> <th style="text-align:right;"> lon </th> <th style="text-align:left;"> basisOfRecord </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> Herpothallon rubrocinctum </td> <td style="text-align:right;"> 4.615950 </td> <td style="text-align:right;"> -74.31527 </td> <td style="text-align:left;"> HUMAN_OBSERVATION </td> </tr> <tr> <td style="text-align:left;"> Herpothallon rubrocinctum </td> <td style="text-align:right;"> 4.065356 </td> <td style="text-align:right;"> -73.59437 </td> <td style="text-align:left;"> HUMAN_OBSERVATION </td> </tr> <tr> <td style="text-align:left;"> Herpothallon rubrocinctum </td> <td style="text-align:right;"> 6.207769 </td> <td style="text-align:right;"> -75.55069 </td> <td style="text-align:left;"> HUMAN_OBSERVATION </td> </tr> <tr> <td style="text-align:left;"> Herpothallon rubrocinctum </td> <td style="text-align:right;"> 4.780458 </td> <td style="text-align:right;"> -71.89709 </td> <td style="text-align:left;"> HUMAN_OBSERVATION </td> </tr> <tr> <td style="text-align:left;"> Herpothallon rubrocinctum </td> <td style="text-align:right;"> 4.780630 </td> <td style="text-align:right;"> -71.89702 </td> <td style="text-align:left;"> HUMAN_OBSERVATION </td> </tr> <tr> <td style="text-align:left;"> Herpothallon rubrocinctum </td> <td style="text-align:right;"> 4.842261 </td> <td style="text-align:right;"> -71.89049 </td> <td style="text-align:left;"> HUMAN_OBSERVATION </td> </tr> </tbody> </table> --- En este caso vamos a hacer un filtrado leve de los datos, se van a eliminar los duplicados. ```r d1 <- subset(d1,!is.na(lat) & !is.na(lon)) #filtrar datos sin coordenadas en x o en y d1 <- data.table(d1) #cambia de data.frame a data.table d1 <- d1[!especies == ""] #quitar los registros sin nobre cinetifico pru <- with(d1, data.table(especies, cor = paste(lat, lon))) #la idea es crear pru para filtar duplicaods(registros de las mismas coordenads) pru <- pru %>% group_by(especies) %>% duplicated(by = key(cor)) d2 <- d1[!pru] #filtro de duplicados dp <- subset(d2, basisOfRecord == "PRESERVED_SPECIMEN") #filtro de especimes de herbario with(dp, sort(table(especies))) #numero de registros por especie ``` ``` ## Herpothallon rubrocinctum ## 24 ``` ```r spp <- with(d1, unique(especies)) ``` --- Para proseguir se debe elegir el sistema de cordenadas en este caso vamos a elegir la WGS 84. ```r ocu1 <- dp datos1 <- ocu1[, -c(1, 4)] ocu1 <- ocu1[,-1] coordinates(datos1) <- ~lon + lat #espaciales para graficar src <- CRS("+init=epsg:4326") crs(datos1) <- src mapa <- spTransform(colombia1, crs(datos1)) sobrelapan <- over(datos1, mapa) plot(clima[[1]]) plot(datos1, add = T) ``` <!-- --> --- Ademas de las cordenadas, la proyeccion que se use para visualizar las ocurrencias cobran relevancia al visualizar los resultados ```r col <- gisco_get_countries(country = "Colombia") col1 <- col %>% st_transform(crs = "+proj=robin") col2 <- col %>% st_transform(crs = "+proj=lagrng") col3 <- col %>% st_transform(crs = "+proj=merc") pr <- ggplot(col1) + geom_sf(fill = "#078930", col = "white") + theme_minimal() pl <- ggplot(col2) + geom_sf(fill = "#078930", col = "white") + theme_minimal() pm <- ggplot(col3) + geom_sf(fill = "#078930", col = "white") + theme_minimal() ``` --- ###Robinson ```r pr ``` <!-- --> --- ###Lagrange ```r pl ``` <!-- --> --- ###Mercator ```r pm ``` <!-- --> --- Con los datos de ocurrencias y las varibles a analizar podemos emepzar con el SMD.  --- Para esto primero creamos un bufer de 10km en esta ocasion sobre los registros obtenidos ```r buffer <- buffer(datos1, width = 100000) #bufer de 10km areas <- crop(clima, extent(buffer)) #un rectangulo del area de los puntos areas <- mask(areas, buffer) #el area exacta que coge todos los registros plot(areas[[1]]) ``` <!-- --> --- Teneindo los registros y las variables elegidas, en el bufer, para crear "ruido" en el modelo vamos a crear una suerte de registros falsos es los alrededores de los registros del GBIF. ```r u <- runif(1) if (u < .6){bg <- sampleRandom(x = areas, size = 10000, na.rm = T, sp = T)} else {bg <- randomPoints(areas, 10000, p = datos1)} #hacen lo mismo pero diferente plot(bg) ``` <!-- --> --- antes de correr el modelo vamos a separar los datos del GBIF en dos grupos, el primer grupo de datos sera usado en nuestro modelo para el proceso de "*entrenamiento*", el otro grupo de datos que no va a ser tenido en cuenta en el modelo sera para "*testear*" el modelo mas adelante --- En este caso vamos a separar nuestros datos en tres partes iguales y aleatoriamente se escogera una parte que sera la usada para "testear" y las otras dos en la parte del "entrenamiento" <!-- --> --- Un ultimo paso antes de correr el modelos, es extraer las condiciones ambientales de cada una de las variables evaluadas en los lugares de los registros. Luego se hace una matrix de prescencia-ausencia de cada una de las variables. ```r p <- raster::extract(clima, train) ptest <- raster::extract(clima, test) a <- raster::extract(clima, bg) pa <- c(rep(1, nrow(p)), rep(0, nrow(a))) #presente en el test y ausente en el entorno pder <- as.data.frame(rbind(p, a)) knitr::kable(head(pder), format = 'html') ``` <table> <thead> <tr> <th style="text-align:right;"> wc2.1_30s_bio_1 </th> <th style="text-align:right;"> wc2.1_30s_bio_2 </th> <th style="text-align:right;"> wc2.1_30s_bio_3 </th> <th style="text-align:right;"> wc2.1_30s_bio_4 </th> <th style="text-align:right;"> wc2.1_30s_bio_5 </th> <th style="text-align:right;"> wc2.1_30s_bio_6 </th> <th style="text-align:right;"> wc2.1_30s_bio_7 </th> <th style="text-align:right;"> wc2.1_30s_bio_8 </th> <th style="text-align:right;"> wc2.1_30s_bio_9 </th> <th style="text-align:right;"> wc2.1_30s_bio_10 </th> <th style="text-align:right;"> wc2.1_30s_bio_11 </th> <th style="text-align:right;"> wc2.1_30s_bio_12 </th> <th style="text-align:right;"> wc2.1_30s_bio_13 </th> <th style="text-align:right;"> wc2.1_30s_bio_14 </th> <th style="text-align:right;"> wc2.1_30s_bio_15 </th> <th style="text-align:right;"> wc2.1_30s_bio_16 </th> <th style="text-align:right;"> wc2.1_30s_bio_17 </th> <th style="text-align:right;"> wc2.1_30s_bio_18 </th> <th style="text-align:right;"> wc2.1_30s_bio_19 </th> <th style="text-align:right;"> COL_elv_msk </th> </tr> </thead> <tbody> <tr> <td style="text-align:right;"> 16.13333 </td> <td style="text-align:right;"> 8.783333 </td> <td style="text-align:right;"> 86.11111 </td> <td style="text-align:right;"> 28.70962 </td> <td style="text-align:right;"> 21.0 </td> <td style="text-align:right;"> 10.8 </td> <td style="text-align:right;"> 10.2 </td> <td style="text-align:right;"> 15.75000 </td> <td style="text-align:right;"> 16.20000 </td> <td style="text-align:right;"> 16.46667 </td> <td style="text-align:right;"> 15.75000 </td> <td style="text-align:right;"> 1749 </td> <td style="text-align:right;"> 240 </td> <td style="text-align:right;"> 74 </td> <td style="text-align:right;"> 35.08498 </td> <td style="text-align:right;"> 577 </td> <td style="text-align:right;"> 276 </td> <td style="text-align:right;"> 532 </td> <td style="text-align:right;"> 577 </td> <td style="text-align:right;"> 2192 </td> </tr> <tr> <td style="text-align:right;"> 16.71250 </td> <td style="text-align:right;"> 8.775000 </td> <td style="text-align:right;"> 86.88118 </td> <td style="text-align:right;"> 32.69175 </td> <td style="text-align:right;"> 21.5 </td> <td style="text-align:right;"> 11.4 </td> <td style="text-align:right;"> 10.1 </td> <td style="text-align:right;"> 16.28333 </td> <td style="text-align:right;"> 16.86667 </td> <td style="text-align:right;"> 17.06667 </td> <td style="text-align:right;"> 16.26667 </td> <td style="text-align:right;"> 1773 </td> <td style="text-align:right;"> 216 </td> <td style="text-align:right;"> 69 </td> <td style="text-align:right;"> 33.01048 </td> <td style="text-align:right;"> 579 </td> <td style="text-align:right;"> 282 </td> <td style="text-align:right;"> 552 </td> <td style="text-align:right;"> 463 </td> <td style="text-align:right;"> 2102 </td> </tr> <tr> <td style="text-align:right;"> 20.92917 </td> <td style="text-align:right;"> 9.208333 </td> <td style="text-align:right;"> 89.40129 </td> <td style="text-align:right;"> 31.87037 </td> <td style="text-align:right;"> 26.1 </td> <td style="text-align:right;"> 15.8 </td> <td style="text-align:right;"> 10.3 </td> <td style="text-align:right;"> 20.70000 </td> <td style="text-align:right;"> 20.73333 </td> <td style="text-align:right;"> 21.30000 </td> <td style="text-align:right;"> 20.50000 </td> <td style="text-align:right;"> 2145 </td> <td style="text-align:right;"> 301 </td> <td style="text-align:right;"> 102 </td> <td style="text-align:right;"> 43.52382 </td> <td style="text-align:right;"> 805 </td> <td style="text-align:right;"> 335 </td> <td style="text-align:right;"> 668 </td> <td style="text-align:right;"> 632 </td> <td style="text-align:right;"> 1374 </td> </tr> <tr> <td style="text-align:right;"> 13.96667 </td> <td style="text-align:right;"> 9.866667 </td> <td style="text-align:right;"> 83.61581 </td> <td style="text-align:right;"> 28.78868 </td> <td style="text-align:right;"> 19.6 </td> <td style="text-align:right;"> 7.8 </td> <td style="text-align:right;"> 11.8 </td> <td style="text-align:right;"> 13.80000 </td> <td style="text-align:right;"> 13.91667 </td> <td style="text-align:right;"> 14.38333 </td> <td style="text-align:right;"> 13.66667 </td> <td style="text-align:right;"> 1253 </td> <td style="text-align:right;"> 172 </td> <td style="text-align:right;"> 44 </td> <td style="text-align:right;"> 35.66748 </td> <td style="text-align:right;"> 439 </td> <td style="text-align:right;"> 209 </td> <td style="text-align:right;"> 330 </td> <td style="text-align:right;"> 361 </td> <td style="text-align:right;"> 2526 </td> </tr> <tr> <td style="text-align:right;"> 18.10417 </td> <td style="text-align:right;"> 11.025000 </td> <td style="text-align:right;"> 86.81102 </td> <td style="text-align:right;"> 19.36001 </td> <td style="text-align:right;"> 24.6 </td> <td style="text-align:right;"> 11.9 </td> <td style="text-align:right;"> 12.7 </td> <td style="text-align:right;"> 17.85000 </td> <td style="text-align:right;"> 18.18333 </td> <td style="text-align:right;"> 18.30000 </td> <td style="text-align:right;"> 17.85000 </td> <td style="text-align:right;"> 2080 </td> <td style="text-align:right;"> 286 </td> <td style="text-align:right;"> 54 </td> <td style="text-align:right;"> 44.03385 </td> <td style="text-align:right;"> 819 </td> <td style="text-align:right;"> 239 </td> <td style="text-align:right;"> 552 </td> <td style="text-align:right;"> 819 </td> <td style="text-align:right;"> 1795 </td> </tr> <tr> <td style="text-align:right;"> 12.99583 </td> <td style="text-align:right;"> 8.041667 </td> <td style="text-align:right;"> 75.15576 </td> <td style="text-align:right;"> 73.65332 </td> <td style="text-align:right;"> 17.9 </td> <td style="text-align:right;"> 7.2 </td> <td style="text-align:right;"> 10.7 </td> <td style="text-align:right;"> 13.08333 </td> <td style="text-align:right;"> 12.15000 </td> <td style="text-align:right;"> 13.83333 </td> <td style="text-align:right;"> 12.01667 </td> <td style="text-align:right;"> 1714 </td> <td style="text-align:right;"> 313 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:right;"> 68.75770 </td> <td style="text-align:right;"> 760 </td> <td style="text-align:right;"> 81 </td> <td style="text-align:right;"> 442 </td> <td style="text-align:right;"> 95 </td> <td style="text-align:right;"> 2653 </td> </tr> </tbody> </table> --- ya tenemos todo lo necesario para correr el modelo de distribucion de especies **SMD**, atraves del paquete de dismo con maxima entropia. ```r mod <- dismo::maxent(x = pder, p = pa, factors = "biome", nbg = 10000, args = c("-J", "-P")) #modelo de distribucion de especies response(mod) #Ponderacion de la variacion de cada variables ``` <!-- --> ```r ped1 <- predict(mod, clima) #Extrapolacion del modelo en todo Colombia ``` --- <!-- --> --- ```r mod <- dismo::maxent(x = pder, p = pa, factors = "biome", nbg = 10000, args = c("-J", "-P")) #modelo de distribucion de especies response(mod) #Ponderacion de la variacion de cada variables ``` <!-- --> ```r ped1 <- predict(mod, clima) #Extrapolacion del modelo en todo Colombia ``` --- Ahora con el modelo hacemos la evaluacion o el "*testeo*" con los datos que separamos previamente ```r p1 <- predict(mod, data.frame(ptest)) a1 <- predict(mod, data.frame(a)) combinado <- c(p1, a1) label <- c(rep(1, length(p1)), rep(0, length(a1))) predic <- prediction(combinado, label) perfor <- performance(predic, "tpr","fpr") auc <- performance(predic, "auc") #auc del modelo bdf2 <- data.frame("TPR" = perfor@y.values, "FPR" = perfor@x.values, "Cutoff" = perfor@alpha.values) colnames(bdf2) <- c("TPR", "TFR", "Cutoff") bdf2 <- data.table(bdf2) AUC <- function(data = list(ptest, a), i) { p1 <- predict(mod, data.frame(ptest[i,])) a1 <- predict(mod, data.frame(a)) combinado <- c(p1, a1) label <- c(rep(1, length(p1)), rep(0, length(a1))) predic <- prediction(combinado, label) auc <- performance(predic, "auc") result <- list() result[[1]] <- auc@y.values[[1]] result[[2]] <- sd(perfor@y.values[[1]]) return(result[[1]]) } bo <- boot(ptest, AUC, 500) #Bootrap del modelo ``` --- <img src="diapo_files/figure-html/boot-grafica-1.png" style="display: block; margin: auto;" /> --- background-image: url(https://images.fineartamerica.com/images/artworkimages/mediumlarge/3/1-labor-omnia-vincit-improbus-vidddie-publyshd.jpg) --- background-image: url(http://i2.cdn.turner.com/cnnnext/dam/assets/150126102625-01-auschwitz-liberation-0126-super-169.jpg)