library('spocc')
df <- occ(query = "Tursiops truncatus", from = "gbif",
date = c("2019-01-01", "2024-12-31"),
gbifopts = list(country = "MX"),
has_coords = TRUE, limit = 10000)
d <- occ2df(df)
Especie: “Tursiops truncatus”
El delfín nariz de botellaes una especie cosmopolita con poblaciones costeras y oceánicas en México (Pacífico y Golfo). Son depredadores robustos que viven en manadas con estructuras sociales complejas, destacando por su uso de la ecolocalización para cazar peces y calamares.
Modelo de regresión lineal: Debido a que la variable a predecir (presencia/ausencia) es binaria (0 o 1), el modelo más adecuado no es la regresión lineal simple,
Este enfoque permite a los investigadores estimar la probabilidad de que el delfín esté presente en un área específica basándose en diversas variables ambientales o antropogénicas (conocidas como variables predictoras).
MAPA: Los datos de GBIF (2019-2024) confirman la distribución bicoastal del Tursiops truncatus en México. Los registros se concentran a lo largo de las costas, destacando su presencia en el Golfo de California (Pacífico) y en el Golfo de México (especialmente en áreas como Veracruz y Tamaulipas).
library(sf)
## Linking to GEOS 3.13.1, GDAL 3.11.0, PROJ 9.6.0; sf_use_s2() is TRUE
library(mapview)
d <- st_as_sf(d, coords = c("longitude", "latitude"))
st_crs(d) <- 4326
mapview(d)
TEMPORADAS:
Los modelos de regresión utilizados en las costas de México deben considerar las estaciones climáticas (Nortes, Lluvias y Secas), ya que estas influyen en la distribución de los delfines y la disponibilidad de alimento.
En el Golfo de México, la temporada de Nortes (vientos fuertes y oleaje alto, de noviembre a febrero) y las Lluvias (julio a octubre) son cruciales.
Lluvias y Productividad: La temporada de lluvias
aumenta la descarga de agua dulce y nutrientes de los
ríos.
Nortes y Residencia: Aunque los Nortes provocan
condiciones meteorológicas adversas que pueden afectar los muestreos o
causar varamientos, en algunas poblaciones costeras de Veracruz se
observa que la abundancia y el ámbito hogareño de los
delfines se mantienen estables durante estas
temporadas. Esto sugiere que las poblaciones residentes han desarrollado
estrategias para explotar recursos consistentemente a pesar de las
variaciones estacionales.
library(readxl)
library(dplyr)
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(lubridate)
##
## Adjuntando el paquete: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
library(sf)
datos_Tursiops <- read_excel("C:/Users/angef/Downloads/datos_Tursiops.xlsx")
datos_Tursiops_modelo <- datos_Tursiops %>%
mutate(
Presencia_Ausencia = 1, # Creación de la variable de respuesta
date = as.Date(date) # Conversión de la columna de fecha
)
datos_Tursiops_modelo <- datos_Tursiops_modelo %>%
mutate(
mes = month(date),
Estacion = case_when(
mes %in% c(3, 4, 5) ~ "Primavera",
mes %in% c(6, 7, 8) ~ "Verano",
mes %in% c(9, 10, 11) ~ "Otoño",
TRUE ~ "Invierno" # Meses 12, 1, 2
),
Estacion = as.factor(Estacion)
)
modelo_delfines <- glm(
Presencia_Ausencia ~ Latitud + Longitud + Estacion,
data = datos_Tursiops_modelo,
family = binomial(link = "logit")
)
## Warning: glm.fit: algorithm did not converge
probabilidades_predichas <- predict(modelo_delfines, type = "response")
summary(modelo_delfines)
##
## Call:
## glm(formula = Presencia_Ausencia ~ Latitud + Longitud + Estacion,
## family = binomial(link = "logit"), data = datos_Tursiops_modelo)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 2.657e+01 1.627e+05 0 1
## Latitud 7.990e-08 3.841e+03 0 1
## Longitud 2.510e-08 1.720e+03 0 1
## EstacionOtoño -4.038e-06 4.152e+04 0 1
## EstacionPrimavera -3.714e-06 3.266e+04 0 1
## EstacionVerano -4.058e-06 4.316e+04 0 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 0.0000e+00 on 766 degrees of freedom
## Residual deviance: 4.4498e-09 on 761 degrees of freedom
## AIC: 12
##
## Number of Fisher Scoring iterations: 25
De lo anterior se puede deducir:
Estimate (Estimación) El valor numérico que indica el cambio en el logaritmo de las probabilidades (Log-Odds) de que el delfín esté presente por cada aumento de una unidad en el predictor, manteniendo los demás fijos.
Estimate: El valor. Un número positivo aumentaría la probabilidad de presencia; un negativo la disminuiría.Los valores son cercanos a cero (ej. \(7.99 \times 10^{-8}\)), lo que sugiere que Latitud, Longitud y Estación tienen un efecto casi nulo en la presencia del delfín.
head(datos_Tursiops_modelo)
## # A tibble: 6 × 8
## name prov date Longitud Latitud Presencia_Ausencia mes Estacion
## <chr> <chr> <date> <dbl> <dbl> <dbl> <dbl> <fct>
## 1 Tursiops … gbif 2024-01-01 -114. 31.3 1 1 Invierno
## 2 Tursiops … gbif 2024-01-17 -111. 26.1 1 1 Invierno
## 3 Tursiops … gbif 2024-01-25 -87.7 18.7 1 1 Invierno
## 4 Tursiops … gbif 2024-01-13 -117. 31.8 1 1 Invierno
## 5 Tursiops … gbif 2024-01-26 -111. 18.7 1 1 Invierno
## 6 Tursiops … gbif 2024-01-14 -110. 22.8 1 1 Invierno
Ahora el análisis de modelo de regresión lineal.
datos_conteo <- datos_Tursiops %>%
mutate(
date = as.Date(date),
mes = month(date),
Estacion = case_when(
mes %in% c(3, 4, 5) ~ "Primavera",
mes %in% c(6, 7, 8) ~ "Verano",
mes %in% c(9, 10, 11) ~ "Otoño",
TRUE ~ "Invierno"
)
)
library(ggplot2)
frecuencia_por_estacion <- datos_conteo %>%
group_by(Estacion) %>%
summarise(
Conteo_Avistamientos = n(),
.groups = 'drop'
) %>%
mutate(
Estacion = factor(Estacion, levels = c("Invierno", "Primavera", "Verano", "Otoño"))
)
print("Tabla de frecuencias creada. Generando gráfico...")
## [1] "Tabla de frecuencias creada. Generando gráfico..."
grafico_frecuencia <- ggplot(
frecuencia_por_estacion,
aes(x = Estacion, y = Conteo_Avistamientos, fill = Estacion)
) +
geom_bar(stat = "identity", color = "black") +
geom_text(aes(label = Conteo_Avistamientos), vjust = -0.5, size = 5) +
labs(
title = "Frecuencia de Delfines por Temporada",
x = "Estación del Año",
y = "Frecuencia"
) +
theme_minimal() +
theme(legend.position = "none")
# Muestra el gráfico
print(grafico_frecuencia)
El gráfico muestra la Frecuencia Absoluta de Avistamientos del delfín (Tursiops truncatus) por estación, revelando que la Primavera (323) y el Invierno (220) concentran la mayoría de los registros, mientras que el Verano (103) y el Otoño (116) tienen la menor frecuencia.
La Regresión Logística ajustada (\(\text{Presencia} \sim \text{Estación} + \text{Coordenadas}\)) utiliza los datos detrás de esta gráfica para cuantificar la probabilidad de presencia en función de la época del año.
datos_presencia <- datos_Tursiops %>%
mutate(
Presencia_Ausencia = 1,
date = as.Date(date)
) %>%
select(Longitud, Latitud, date, Presencia_Ausencia)
# 2.2 Generación de Ausencias Pseudo-Aleatorias (Puntos 0)
min_lon <- min(datos_presencia$Longitud)
max_lon <- max(datos_presencia$Longitud)
min_lat <- min(datos_presencia$Latitud)
max_lat <- max(datos_presencia$Latitud)
num_ausencias <- nrow(datos_presencia) * 2
ausencias <- data.frame(
Longitud = runif(num_ausencias, min_lon, max_lon),
Latitud = runif(num_ausencias, min_lat, max_lat)
) %>%
mutate(
date = sample(datos_presencia$date, num_ausencias, replace = TRUE),
Presencia_Ausencia = 0
) %>%
select(Longitud, Latitud, date, Presencia_Ausencia)
# 2.3 Unir datos y crear la variable Estación
datos_modelo_valido <- bind_rows(datos_presencia, ausencias) %>%
mutate(
mes = month(date),
Estacion = case_when(
mes %in% c(3, 4, 5) ~ "Primavera",
mes %in% c(6, 7, 8) ~ "Verano",
mes %in% c(9, 10, 11) ~ "Otoño",
TRUE ~ "Invierno"),
Estacion = as.factor(Estacion)
)
# 2.4 ¡CREACIÓN DEL MODELO! (Este paso ahora garantiza la existencia del objeto)
print("Creando y guardando el objeto 'modelo_delfines_valido'...")
## [1] "Creando y guardando el objeto 'modelo_delfines_valido'..."
modelo_delfines_valido <- glm(
Presencia_Ausencia ~ Latitud + Longitud + Estacion,
data = datos_modelo_valido,
family = binomial(link = "logit")
)
# --- 3. PREDICCIÓN Y GRÁFICO ---
# 3.1 Crear la Tabla de Predicción (el escenario)
promedio_latitud <- mean(datos_Tursiops$Latitud)
promedio_longitud <- mean(datos_Tursiops$Longitud)
escenario_prediccion <- data.frame(
Longitud = rep(promedio_longitud, 4),
Latitud = rep(promedio_latitud, 4),
Estacion = factor(c("Invierno", "Primavera", "Verano", "Otoño"),
levels = c("Invierno", "Primavera", "Verano", "Otoño"))
)
# 3.2 GENERAR LAS PREDICCIONES (Ahora el modelo existe y esta línea funcionará)
probabilidades_predichas <- predict(
modelo_delfines_valido,
newdata = escenario_prediccion,
type = "response"
)
# 3.3 Crear la tabla de resultados para el gráfico
tabla_predicciones <- escenario_prediccion %>%
mutate(
Probabilidad_Presencia = round(probabilidades_predichas, 4)
)
# 3.4 GENERACIÓN DEL GRÁFICO
print("Generando gráfico de Probabilidad de Presencia Predicha...")
## [1] "Generando gráfico de Probabilidad de Presencia Predicha..."
grafico_modelo <- ggplot(
tabla_predicciones,
aes(x = Estacion, y = Probabilidad_Presencia, fill = Estacion)
) +
geom_bar(stat = "identity", color = "black") +
geom_text(aes(label = Probabilidad_Presencia), vjust = -0.5, size = 5) +
labs(
title = "Probabilidad de Presencia por Estación",
subtitle = paste0("Modelo Logístico en el punto: Lon=", round(promedio_longitud, 2), ", Lat=", round(promedio_latitud, 2)),
x = "Estación del Año",
y = "Probabilidad Predicha (0.0 a 1.0)"
) +
theme_minimal() +
theme(
legend.position = "none",
plot.title = element_text(hjust = 0.5, face = "bold")
)
# Muestra el gráfico
print(grafico_modelo)
El gráfico ilustra que la Presencia de Delfines (Tursiops truncatus) en las costas de México depende fuertemente de la estación, alcanzando su pico en Primavera (323 avistamientos) y su mínimo en Verano (103). El modelo de Regresión Logística tiene como objetivo cuantificar y validar estadísticamente esta variación observada.
Causa de la Variación Estacional Las diferencias de avistamiento son impulsadas por la ecología y la disponibilidad de recursos:
Picos (Primavera): La alta frecuencia probablemente se debe a un aumento en la productividad marina (nutrientes y alimento) que concentra a las presas principales del delfín en las áreas costeras.
Valles (Verano/Otoño): La baja frecuencia puede deberse a la dispersión de los delfines para evitar temperaturas extremas o a un desplazamiento de las presas a aguas más profundas o frescas. ________
min_lon <- min(datos_Tursiops$Longitud)
max_lon <- max(datos_Tursiops$Longitud)
min_lat <- min(datos_Tursiops$Latitud)
max_lat <- max(datos_Tursiops$Latitud)
# 2.2 Crear una secuencia de puntos espaciados (malla)
malla_prediccion <- expand.grid(
Longitud = seq(min_lon, max_lon, length.out = 50), # 50 puntos en horizontal
Latitud = seq(min_lat, max_lat, length.out = 50) # 50 puntos en vertical
) %>%
# Asignamos la temporada Verano a toda la malla para predecir
mutate(
Estacion = factor("Verano", levels = levels(datos_modelo_valido$Estacion))
)
# --- 3. PREDICCIÓN Y GENERACIÓN DE LA TABLA DEL MAPA ---
# Generar predicciones de probabilidad de presencia (0 a 1)
malla_prediccion$Probabilidad <- predict(
modelo_delfines_valido,
newdata = malla_prediccion,
type = "response"
)
# --- 4. GENERACIÓN DEL MAPA DE DISTRIBUCIÓN PREDICHA ---
print("Generando el Mapa de Distribución Predicha (Verano)...")
## [1] "Generando el Mapa de Distribución Predicha (Verano)..."
mapa_prediccion <- ggplot(malla_prediccion, aes(x = Longitud, y = Latitud)) +
# Usa geom_tile para colorear cada punto de la malla según la Probabilidad
geom_tile(aes(fill = Probabilidad)) +
# Añade los puntos de tus avistamientos originales
geom_point(data = datos_Tursiops, aes(x = Longitud, y = Latitud),
color = "black", shape = 21, size = 1, alpha = 0.5) +
# Escala de colores (Zona Roja = Alta Probabilidad, Zona Azul = Baja Probabilidad)
scale_fill_gradient(low = "lightblue", high = "red", name = "Probabilidad\n(0 a 1)") +
labs(
title = "Mapa de Idoneidad de Hábitat (Predicción: Verano)",
subtitle = "Zonas Rojas indican alta probabilidad de presencia de Tursiops.",
x = "Longitud",
y = "Latitud"
) +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5, face = "bold"))
# Muestra el mapa
print(mapa_prediccion)
Este mapa muestra la probabilidad de presencia del delfín nariz de botella en las costas de México durante el Verano.
Zonas Rojas (Idoneidad Alta): Indican áreas donde el modelo predice una alta probabilidad de presencia (Probabilidad ≥0.5, o 50%). Estas áreas se concentran principalmente en la costa occidental del Pacífico Mexicano y la Península de Baja California (Latitudes 20 a 30, Longitudes −115 a −105).
Zonas Azules (Idoneidad Baja): Indican áreas donde la probabilidad de presencia es baja (Probabilidad ≤0.2). Estas se encuentran en el Golfo de México (aproximadamente en Longitudes −95 a −90).
summary(modelo_delfines_valido)
##
## Call:
## glm(formula = Presencia_Ausencia ~ Latitud + Longitud + Estacion,
## family = binomial(link = "logit"), data = datos_modelo_valido)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -7.387574 0.590773 -12.505 < 2e-16 ***
## Latitud -0.029550 0.009167 -3.224 0.00127 **
## Longitud -0.070271 0.005445 -12.906 < 2e-16 ***
## EstacionOtoño 0.284537 0.149338 1.905 0.05674 .
## EstacionPrimavera -0.072175 0.110561 -0.653 0.51388
## EstacionVerano 0.185498 0.154013 1.204 0.22842
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 2929.2 on 2300 degrees of freedom
## Residual deviance: 2735.8 on 2295 degrees of freedom
## AIC: 2747.8
##
## Number of Fisher Scoring iterations: 3
Solo la Longitud (Coefficients: \(-0.061596\)) resultó ser una variable altamente significativa (\(p < 2e-16\)) en la predicción de la presencia de los delfines. El coeficiente negativo indica que, al moverse hacia el Este, el Log-Odds de presencia disminuye. Esto sugiere que las áreas costeras del Oeste de México (Pacífico/Baja California) son hábitats más probables.
datos_presencia <- datos_Tursiops %>%
mutate(Presencia_Ausencia = 1, date = as.Date(date)) %>%
select(Longitud, Latitud, date, Presencia_Ausencia)
min_lon <- min(datos_presencia$Longitud); max_lon <- max(datos_presencia$Longitud)
min_lat <- min(datos_presencia$Latitud); max_lat <- max(datos_presencia$Latitud)
num_ausencias <- nrow(datos_presencia) * 2
ausencias <- data.frame(
Longitud = runif(num_ausencias, min_lon, max_lon),
Latitud = runif(num_ausencias, min_lat, max_lat)
) %>%
mutate(date = sample(datos_presencia$date, num_ausencias, replace = TRUE), Presencia_Ausencia = 0) %>%
select(Longitud, Latitud, date, Presencia_Ausencia)
datos_modelo_valido <- bind_rows(datos_presencia, ausencias) %>%
mutate(
mes = month(date),
Estacion = case_when(mes %in% c(3, 4, 5) ~ "Primavera", mes %in% c(6, 7, 8) ~ "Verano",
mes %in% c(9, 10, 11) ~ "Otoño", TRUE ~ "Invierno"),
Estacion = as.factor(Estacion)
)
# 1.2 CREACIÓN DEL MODELO
modelo_delfines_valido <- glm(
Presencia_Ausencia ~ Latitud + Longitud + Estacion,
data = datos_modelo_valido,
family = binomial(link = "logit")
)
promedio_latitud <- mean(datos_Tursiops$Latitud)
promedio_longitud <- mean(datos_Tursiops$Longitud)
escenario_prediccion <- data.frame(
Longitud = rep(promedio_longitud, 4),
Latitud = rep(promedio_latitud, 4),
Estacion = factor(c("Invierno", "Primavera", "Verano", "Otoño"),
levels = levels(datos_modelo_valido$Estacion))
)
probabilidades_predichas <- predict(
modelo_delfines_valido,
newdata = escenario_prediccion,
type = "response"
)
tabla_predicciones <- escenario_prediccion %>%
mutate(
Probabilidad_Presencia = round(probabilidades_predichas, 4)
) %>%
select(Estacion, Longitud, Latitud, Probabilidad_Presencia)
# --- 3. VISUALIZACIÓN ---
print(tabla_predicciones)
## Estacion Longitud Latitud Probabilidad_Presencia
## 1 Invierno -106.992 22.75171 0.3480
## 2 Primavera -106.992 22.75171 0.3520
## 3 Verano -106.992 22.75171 0.4108
## 4 Otoño -106.992 22.75171 0.3840
Conclusiones ClaveOtoño es la Estación de Mayor Probabilidad: La probabilidad es más alta en Otoño (\(0.4049\) o \(40.49\%\)).Primavera es la Estación de Menor Probabilidad: La probabilidad es más baja en Primavera (\(0.3562\) o \(35.62\%\)).Baja Probabilidad General: Dado que todos los valores son menores a 0.50 (50%), el modelo predice que en este punto promedio, la Ausencia es más probable que la Presencia en cualquier época del año.
Modelo de regresión lineal clásico:
modelo_lineal_delfines <- lm(
Presencia_Ausencia ~ Latitud + Longitud + Estacion,
data = datos_modelo_valido
)
print("--- Resumen del Modelo de Regresión Lineal Clásico (MLC) ---")
## [1] "--- Resumen del Modelo de Regresión Lineal Clásico (MLC) ---"
summary(modelo_lineal_delfines)
##
## Call:
## lm(formula = Presencia_Ausencia ~ Latitud + Longitud + Estacion,
## data = datos_modelo_valido)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.5679 -0.3645 -0.2179 0.5758 0.8861
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.874115 0.115013 -7.600 4.28e-14 ***
## Latitud -0.003351 0.001891 -1.772 0.0765 .
## Longitud -0.012215 0.001047 -11.661 < 2e-16 ***
## EstacionOtoño 0.032230 0.030220 1.067 0.2863
## EstacionPrimavera 0.004800 0.022884 0.210 0.8339
## EstacionVerano 0.056678 0.032203 1.760 0.0785 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.4585 on 2295 degrees of freedom
## Multiple R-squared: 0.05661, Adjusted R-squared: 0.05456
## F-statistic: 27.55 on 5 and 2295 DF, p-value: < 2.2e-16
Solo la Longitud resultó ser un predictor altamente significativo (\(p < 2e-16\)). El coeficiente negativo (\(-0.0132\)) indica que, al moverse hacia el Este, la presencia predicha de delfines disminuye. Esto sugiere que las zonas más occidentales de México son más propensas al avistamiento. El modelo, en su conjunto, es significativo (\(p < 2.2e-16\)), gracias al fuerte efecto de la Longitud. Sin embargo, el \(R^2\) Múltiple es muy bajo (6.77%), indicando que el modelo solo explica una pequeña porción de la variación en la presencia/ausencia de los delfines. ___________
promedio_latitud <- mean(datos_modelo_valido$Latitud)
promedio_longitud <- mean(datos_modelo_valido$Longitud)
escenario_prediccion_lineal <- data.frame(
Longitud = rep(promedio_longitud, 4),
Latitud = rep(promedio_latitud, 4),
Estacion = factor(c("Invierno", "Primavera", "Verano", "Otoño"),
levels = levels(datos_modelo_valido$Estacion))
)
prob_predichas_lineal <- predict(
modelo_lineal_delfines,
newdata = escenario_prediccion_lineal
)
tabla_predicciones_lineal <- escenario_prediccion_lineal %>%
mutate(
# Nota: Los resultados pueden caer fuera del rango [0, 1]
Prediccion_Lineal = round(prob_predichas_lineal, 4)
) %>%
select(Estacion, Prediccion_Lineal)
print("--- Predicciones por Estación (Resultados No Limitados a 0-1) ---")
## [1] "--- Predicciones por Estación (Resultados No Limitados a 0-1) ---"
print(tabla_predicciones_lineal)
## Estacion Prediccion_Lineal
## 1 Invierno 0.3193
## 2 Primavera 0.3241
## 3 Verano 0.3760
## 4 Otoño 0.3515
El hecho de que los residuos no estén distribuidos simétricamente alrededor del cero (la mediana es \(-0.2108\)) es una bandera roja y una razón clave por la que la Regresión Logística es mejor para los datos binarios que el Modelo Lineal Clásico
Conclusiones:
El análisis de regresión, utilizando los datos de presencia y los puntos de ausencia simulados, revela que la Longitud (ubicación Este-Oeste) es el factor geográfico más importante para predecir la presencia del delfín, mientras que la influencia de las estaciones es marginal en el punto de estudio promedio
Resultado de Regresión Logística Válida: La Longitud es la única variable que resultó ser altamente significativa (\(p < 2e-16\)) en el modelo Logístico.Dirección del Efecto: El coeficiente negativo indica que la probabilidad de presencia disminuye a medida que la Longitud aumenta (moviéndose hacia el Este).Conclusión del Hábitat: Las poblaciones de Tursiops truncatus estudiadas tienen una mayor probabilidad de ser encontradas en las costas occidentales de México (Océano Pacífico y Baja California), lo cual es consistente con las concentraciones de avistamientos mostradas en tu Mapa de Idoneidad de Hábitat.