library(rinat)
library(dplyr)
library(lubridate)
library(sf)
library(mapview)
library(leafpop)
library(DT)Mis visitas a Monterrey
Hoy quiero hacer un resumen de mis visitas a Monterrey, México a lo largo de los años.
Paquetes
En esta contribución a mi blog voy a usar R con la siguiente selección de paquetes:
Con esta función del paquete here defino las rutas de acceso a los archivos locales:
here::i_am("regions/Monterrey.qmd")Vamos a crear un directorio para los datos descargados.
if (!dir.exists(here::here("data")))
dir.create(here::here("data"))
inat_obs_data <- here::here("data", "inat-obs-2026.rds")Con esto puedo descargar todas las observaciones de iNaturalist de mi usuario. Guardo los datos descargados en un archivo del directorio data de este repositorio:
if (file.exists(inat_obs_data)) {
user_obs <- readRDS(inat_obs_data)
} else {
user_obs <- get_inat_obs_user("NeoMapas",maxresults = 5000) |>
mutate(dts=date(datetime), year=year(dts), month=month(dts))
saveRDS(user_obs, inat_obs_data)
}Uso la función st_to_sf del paquete sf para hacer los datos espacialmente explícitos:
user_obs_xy <- st_as_sf(user_obs,
coords = c("longitude","latitude"),
crs = 4326)En este caso, me enfoco en los datos de Monterrey, así que voy a leer una capa con los límites del estado.
NL <- read_sf("https://raw.githubusercontent.com/PhantomInsights/mexico-geojson/refs/heads/main/2023/states/Nuevo%20Le%C3%B3n.json")Y realizo una intersección con la función st_intersection del paquete sf:
monterrey_obs <- st_intersection(user_obs_xy,NL)Con las funciones de dplyr podemos agrupar los datos y calcular el número de observaciones y taxa por grupo:
monterrey_obs |>
st_drop_geometry() |>
group_by(year, month, NOMGEO) |>
summarise(obs=n(),taxa=n_distinct(species_guess), .groups="drop") |>
knitr::kable()| year | month | NOMGEO | obs | taxa |
|---|---|---|---|---|
| 2010 | 11 | Monterrey | 7 | 7 |
| 2022 | 1 | Santiago | 12 | 12 |
| 2024 | 1 | Santiago | 34 | 29 |
| 2024 | 2 | Santiago | 8 | 6 |
| 2024 | 10 | Santiago | 138 | 75 |
| 2026 | 4 | García | 18 | 3 |
| 2026 | 4 | Monterrey | 1 | 1 |
| 2026 | 4 | Santiago | 38 | 8 |
Lista de observaciones
A continuación creamos una tabla con la lista de observaciones de todas las visitas:
st_drop_geometry(monterrey_obs) |>
st_drop_geometry() |>
select(iconic_taxon_name,scientific_name, common_name, quality_grade, url) |>
mutate(`url` =
sprintf('<a href="%s" target="_blank">iNat link</a>', url)) |>
datatable(style='bootstrap4', escape = FALSE) |>
formatStyle(c('iconic_taxon_name','common_name', 'quality_grade', 'url'),
color = 'maroon', backgroundColor = 'mistyrose') |>
formatStyle('scientific_name',
color = 'maroon', backgroundColor = 'mistyrose', fontStyle = 'italic')Uso la función datatable del paquete DT, con estilo bootstrap4 que se corresponde con el estilo de este sitio web.
Mapa de localidades
Aquí podemos crear un mapa con las observaciones agrupadas por año y mes, e incluyendo una imágen de cada observación:
monterrey_obs |> mutate(grp=paste(year,month.abb[month])) |>
mapview(
map.types = c("OpenStreetMap.DE", "Esri.WorldImagery"),
zcol = "grp", burst = TRUE,
layer.name = c("Visitas a Monterrey"),
hide = TRUE)¿Qué les parece?
Información de la sesión
sessionInfo()R version 4.5.2 (2025-10-31)
Platform: aarch64-apple-darwin20
Running under: macOS Tahoe 26.4.1
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
locale:
[1] en_AU.UTF-8/en_AU.UTF-8/en_AU.UTF-8/C/en_AU.UTF-8/en_AU.UTF-8
time zone: Australia/Sydney
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] DT_0.34.0 leafpop_0.1.0 mapview_2.11.4 sf_1.1-0
[5] lubridate_1.9.5 dplyr_1.2.1 rinat_0.1.10
loaded via a namespace (and not attached):
[1] gtable_0.3.6 xfun_0.57 ggplot2_4.0.3
[4] raster_3.6-32 htmlwidgets_1.6.4 lattice_0.22-9
[7] leaflet.providers_3.0.0 vctrs_0.7.3 tools_4.5.2
[10] crosstalk_1.2.2 generics_0.1.4 stats4_4.5.2
[13] curl_7.1.0 tibble_3.3.1 proxy_0.4-29
[16] pkgconfig_2.0.3 KernSmooth_2.23-26 satellite_1.0.6
[19] RColorBrewer_1.1-3 S7_0.2.2 leaflet_2.2.3
[22] uuid_1.2-2 lifecycle_1.0.5 compiler_4.5.2
[25] farver_2.1.2 textshaping_1.0.5 terra_1.9-11
[28] codetools_0.2-20 htmltools_0.5.9 maps_3.4.3
[31] class_7.3-23 yaml_2.3.12 jquerylib_0.1.4
[34] pillar_1.11.1 classInt_0.4-11 wk_0.9.5
[37] brew_1.0-10 tidyselect_1.2.1 digest_0.6.39
[40] rprojroot_2.1.1 fastmap_1.2.0 grid_4.5.2
[43] here_1.0.2 cli_3.6.6 magrittr_2.0.5
[46] base64enc_0.1-6 dichromat_2.0-0.1 leafem_0.2.5
[49] e1071_1.7-17 withr_3.0.2 scales_1.4.0
[52] sp_2.2-1 timechange_0.4.0 rmarkdown_2.31
[55] httr_1.4.8 otel_0.2.0 png_0.1-9
[58] evaluate_1.0.5 knitr_1.51 s2_1.1.9
[61] rlang_1.2.0 Rcpp_1.1.1-1.1 glue_1.8.1
[64] DBI_1.3.0 svglite_2.2.2 jsonlite_2.0.0
[67] R6_2.6.1 plyr_1.8.9 systemfonts_1.3.2
[70] units_1.0-1