Capítulo26 Leaflet: Mapas interactivos

## [1] "2025-11-05"
library(tidyverse)

26.1 Bajar los datos de la web del USGS

Website: https://earthquake.usgs.gov/earthquakes/feed/v1.0/csv.php

library(data.table)
earthquakes <- fread("https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.csv")

head(earthquakes, n=10)
##                    time latitude longitude   depth   mag magType   nst   gap
##                  <POSc>    <num>     <num>   <num> <num>  <char> <int> <num>
##  1: 2025-11-05 19:44:09 39.56133 -123.0000  1.8300  1.71      md     5   129
##  2: 2025-11-05 19:43:32 32.10700 -101.9520  4.1356  1.20      ml    30    55
##  3: 2025-11-05 19:41:21 32.65383 -116.6567  9.0200  1.39      ml     5   206
##  4: 2025-11-05 19:27:22 32.92717 -115.5263  9.9200  1.75      ml    38    37
##  5: 2025-11-05 19:22:46 38.78650 -122.7668  2.0600  1.01      md    14    79
##  6: 2025-11-05 19:14:38 32.34500 -101.9290  4.4199  1.60      ml    45    40
##  7: 2025-11-05 18:51:42 61.93150 -149.1612 17.9000  1.60      ml    NA    NA
##  8: 2025-11-05 18:18:15 37.59517 -122.4640  9.6700  1.80      md    13    94
##  9: 2025-11-05 18:15:16 47.11317 -123.1173 -0.2300  1.47      ml    12    83
## 10: 2025-11-05 18:12:07 33.01933 -116.3633  3.4400  1.33      ml    52    35
##        dmin   rms    net           id             updated
##       <num> <num> <char>       <char>              <POSc>
##  1: 0.06567  0.01     nc   nc75259576 2025-11-05 19:47:23
##  2: 0.00000  0.30     tx tx2025vuwwyt 2025-11-05 20:00:45
##  3: 0.31080  0.18     ci   ci40481562 2025-11-05 19:44:53
##  4: 0.03864  0.28     ci   ci40481554 2025-11-05 19:30:59
##  5: 0.01516  0.03     nc   nc75259566 2025-11-05 19:47:21
##  6: 0.10000  0.40     tx tx2025vuvxzd 2025-11-05 19:19:03
##  7:      NA  0.32     ak ak025e7c32b2 2025-11-05 18:53:41
##  8: 0.03155  0.02     nc   nc75259551 2025-11-05 18:37:19
##  9: 0.06394  0.23     uw   uw62202752 2025-11-05 19:13:08
## 10: 0.06186  0.22     ci   ci40481546 2025-11-05 18:55:25
##                               place       type horizontalError depthError
##                              <char>     <char>           <num>      <num>
##  1: 17 km NNW of Lake Pillsbury, CA earthquake            1.78  6.5599999
##  2:       15 km W of Stanton, Texas earthquake            0.00  0.9917502
##  3:   10 km NNW of Tecate, B.C., MX earthquake            2.33 15.1300000
##  4:           6 km S of Brawley, CA earthquake            0.30  0.6400000
##  5:      1 km NW of The Geysers, CA earthquake            0.29  0.5400000
##  6:     27 km NNW of Stanton, Texas earthquake            0.00  0.7793624
##  7:     21 km N of Fishhook, Alaska earthquake              NA  0.3000000
##  8:         3 km SE of Pacifica, CA earthquake            0.47  0.7400000
##  9:  11 km S of Shelton, Washington  explosion            0.50 31.6100000
## 10:         23 km ESE of Julian, CA earthquake            0.19  0.6300000
##      magError magNst    status locationSource magSource
##         <num>  <int>    <char>         <char>    <char>
##  1: 0.5600000      4 automatic             nc        nc
##  2: 0.2000000     22 automatic             tx        tx
##  3: 0.1590000     18 automatic             ci        ci
##  4: 0.1870000     28 automatic             ci        ci
##  5: 0.1300000     13 automatic             nc        nc
##  6: 0.2000000     30 automatic             tx        tx
##  7:        NA     NA automatic             ak        ak
##  8: 0.1800000      9 automatic             nc        nc
##  9: 0.1091141      9  reviewed             uw        uw
## 10: 0.1530000     28  reviewed             ci        ci
unique(earthquakes$type)
## [1] "earthquake"   "explosion"    "quarry blast" "sonic boom"   "ice quake"
earthquakes %>% 
  filter(type=="sonic boom")
##                   time latitude longitude depth   mag magType   nst   gap  dmin
##                 <POSc>    <num>     <num> <num> <num>  <char> <int> <num> <num>
## 1: 2025-10-25 14:28:16 34.73767 -119.3992     0     0     mun    NA    NA    NA
## 2: 2025-10-19 19:32:00 34.36300 -119.0687     0     0     mun    NA    NA    NA
##      rms    net         id             updated
##    <num> <char>     <char>              <POSc>
## 1:    NA     ci ci41319720 2025-10-27 19:38:20
## 2:    NA     ci ci41111399 2025-10-20 19:11:15
##                                  place       type horizontalError depthError
##                                 <char>     <char>           <num>      <num>
## 1: 26 km WSW of Pine Mountain Club, CA sonic boom              NA         NA
## 2:          1 km NW of Santa Paula, CA sonic boom              NA         NA
##    magError magNst   status locationSource magSource
##       <num>  <int>   <char>         <char>    <char>
## 1:       NA      0 reviewed             ci        ci
## 2:       NA      0 reviewed             ci        ci
quarry_blasts=earthquakes %>% 
  filter(type=="quarry blast")

26.2 Si bajo los datos a mi computadora

Use esta alternativa si bajo los datos a su computadora

#library(readr)
#Earthquake_all_month <- read_csv("Datos/Earthquake_all_month.csv")

#EQ=Earthquake_all_month
#head(EQ, n=10)
names(earthquakes)
##  [1] "time"            "latitude"        "longitude"       "depth"          
##  [5] "mag"             "magType"         "nst"             "gap"            
##  [9] "dmin"            "rms"             "net"             "id"             
## [13] "updated"         "place"           "type"            "horizontalError"
## [17] "depthError"      "magError"        "magNst"          "status"         
## [21] "locationSource"  "magSource"
str(earthquakes)
## Classes 'data.table' and 'data.frame':   7570 obs. of  22 variables:
##  $ time           : POSIXct, format: "2025-11-05 19:44:09" "2025-11-05 19:43:32" ...
##  $ latitude       : num  39.6 32.1 32.7 32.9 38.8 ...
##  $ longitude      : num  -123 -102 -117 -116 -123 ...
##  $ depth          : num  1.83 4.14 9.02 9.92 2.06 ...
##  $ mag            : num  1.71 1.2 1.39 1.75 1.01 1.6 1.6 1.8 1.47 1.33 ...
##  $ magType        : chr  "md" "ml" "ml" "ml" ...
##  $ nst            : int  5 30 5 38 14 45 NA 13 12 52 ...
##  $ gap            : num  129 55 206 37 79 40 NA 94 83 35 ...
##  $ dmin           : num  0.0657 0 0.3108 0.0386 0.0152 ...
##  $ rms            : num  0.01 0.3 0.18 0.28 0.03 0.4 0.32 0.02 0.23 0.22 ...
##  $ net            : chr  "nc" "tx" "ci" "ci" ...
##  $ id             : chr  "nc75259576" "tx2025vuwwyt" "ci40481562" "ci40481554" ...
##  $ updated        : POSIXct, format: "2025-11-05 19:47:23" "2025-11-05 20:00:45" ...
##  $ place          : chr  "17 km NNW of Lake Pillsbury, CA" "15 km W of Stanton, Texas" "10 km NNW of Tecate, B.C., MX" "6 km S of Brawley, CA" ...
##  $ type           : chr  "earthquake" "earthquake" "earthquake" "earthquake" ...
##  $ horizontalError: num  1.78 0 2.33 0.3 0.29 0 NA 0.47 0.5 0.19 ...
##  $ depthError     : num  6.56 0.992 15.13 0.64 0.54 ...
##  $ magError       : num  0.56 0.2 0.159 0.187 0.13 ...
##  $ magNst         : int  4 22 18 28 13 30 NA 9 9 28 ...
##  $ status         : chr  "automatic" "automatic" "automatic" "automatic" ...
##  $ locationSource : chr  "nc" "tx" "ci" "ci" ...
##  $ magSource      : chr  "nc" "tx" "ci" "ci" ...
##  - attr(*, ".internal.selfref")=<externalptr>

26.3 Importación de Paquetes y Datos

library(tidyverse)
library(leaflet)
#library(rinat)
library(RColorBrewer)
library(flextable)

Seleccionar un subgrupo de los datos, solamente lo primeros 100 datos

nrow(earthquakes)
## [1] 7570
EQ_100 = earthquakes |> slice(1:100)
head(EQ_100)
##                   time latitude longitude  depth   mag magType   nst   gap
##                 <POSc>    <num>     <num>  <num> <num>  <char> <int> <num>
## 1: 2025-11-05 19:44:09 39.56133 -123.0000 1.8300  1.71      md     5   129
## 2: 2025-11-05 19:43:32 32.10700 -101.9520 4.1356  1.20      ml    30    55
## 3: 2025-11-05 19:41:21 32.65383 -116.6567 9.0200  1.39      ml     5   206
## 4: 2025-11-05 19:27:22 32.92717 -115.5263 9.9200  1.75      ml    38    37
## 5: 2025-11-05 19:22:46 38.78650 -122.7668 2.0600  1.01      md    14    79
## 6: 2025-11-05 19:14:38 32.34500 -101.9290 4.4199  1.60      ml    45    40
##       dmin   rms    net           id             updated
##      <num> <num> <char>       <char>              <POSc>
## 1: 0.06567  0.01     nc   nc75259576 2025-11-05 19:47:23
## 2: 0.00000  0.30     tx tx2025vuwwyt 2025-11-05 20:00:45
## 3: 0.31080  0.18     ci   ci40481562 2025-11-05 19:44:53
## 4: 0.03864  0.28     ci   ci40481554 2025-11-05 19:30:59
## 5: 0.01516  0.03     nc   nc75259566 2025-11-05 19:47:21
## 6: 0.10000  0.40     tx tx2025vuvxzd 2025-11-05 19:19:03
##                              place       type horizontalError depthError
##                             <char>     <char>           <num>      <num>
## 1: 17 km NNW of Lake Pillsbury, CA earthquake            1.78  6.5599999
## 2:       15 km W of Stanton, Texas earthquake            0.00  0.9917502
## 3:   10 km NNW of Tecate, B.C., MX earthquake            2.33 15.1300000
## 4:           6 km S of Brawley, CA earthquake            0.30  0.6400000
## 5:      1 km NW of The Geysers, CA earthquake            0.29  0.5400000
## 6:     27 km NNW of Stanton, Texas earthquake            0.00  0.7793624
##    magError magNst    status locationSource magSource
##       <num>  <int>    <char>         <char>    <char>
## 1:    0.560      4 automatic             nc        nc
## 2:    0.200     22 automatic             tx        tx
## 3:    0.159     18 automatic             ci        ci
## 4:    0.187     28 automatic             ci        ci
## 5:    0.130     13 automatic             nc        nc
## 6:    0.200     30 automatic             tx        tx

26.4 Mapa básico con Leaflet

names(earthquakes)
##  [1] "time"            "latitude"        "longitude"       "depth"          
##  [5] "mag"             "magType"         "nst"             "gap"            
##  [9] "dmin"            "rms"             "net"             "id"             
## [13] "updated"         "place"           "type"            "horizontalError"
## [17] "depthError"      "magError"        "magNst"          "status"         
## [21] "locationSource"  "magSource"
leaflet(EQ_100) %>% 
  addTiles() %>% 
  addCircleMarkers(lng = ~longitude, 
             lat = ~latitude, 
             popup = ~mag,
             color= ~(type))
#unique(earthquakes$type)

#color= ~(type),

26.5 Usando la paletas de color de viridis

Pasos

  1. Seleccionar los datos en el áreas de PR, latitud y longitud
  2. Crear una paleta de colores/ o usar viridis
  3. Crear un mapa con los datos de los terremotos
names(EQ_100)
##  [1] "time"            "latitude"        "longitude"       "depth"          
##  [5] "mag"             "magType"         "nst"             "gap"            
##  [9] "dmin"            "rms"             "net"             "id"             
## [13] "updated"         "place"           "type"            "horizontalError"
## [17] "depthError"      "magError"        "magNst"          "status"         
## [21] "locationSource"  "magSource"
unique(EQ_100$type)
## [1] "earthquake" "explosion"
pal = colorFactor(palette = "magma", domain = NULL)


leaflet(EQ_100) %>% 
  addTiles() %>% 
  addCircleMarkers(lng = ~longitude, 
             lat = ~latitude, 
             color= ~pal(mag),
             popup = ~paste("Magnitud", mag)
             )

26.6 Trabajando con datos de iNaturalist

26.6.1 AHora crea un mapa de los terremotos alrededor de Puerto Rico

Obtener los datos de observaciones de una especie en iNaturalist desde R:

Los datos a utilizar se obtendrán desde iNaturalist, una aplicación con base en la ciencia ciudadana que mantiene un registro de ocurrencias de especies.

La función get_inat_obs() permite acceder a los datos disponibles en iNaturalist, especificando los siguientes parámetros:

  • taxon_name: La especies de interés, siempre escrita entre comillas (“). Puede utilizar nombre común o científico.

  • quality: Siendo una aplicación basada en ciencia ciudadana, la calidad de algunos datos podría ser baja, debido a que les falta información - como nombre científico o ubicación - o que contienen información errónea - especies mal identificadas-. Colocando 'research' en este parámetro se especifica que se desea obtener sólo aquellas observaciones con alta calidad - que tengan información completa y cuya identificación haya sido confirmada por varias personas de la comunidad -.

  • geo: Al igual que el parámetro quality, este parámetro cuyo valor es lógico (TRUE o FALSE), es para especificar que se quiere obtener sólo los datos que están georeferenciados (cuando se coloca como TRUE).

  • maxresults: A través del API (Interfaz de Programación de Aplicaciones) de iNaturalist se puede acceder a un máximo de 10,000 observaciones en una sola búsqueda. Con este parámetro, cuyo valor debe ser numérico, se especifica cuantas observaciones se desea obtener, y no se debe exceder de 10,000 por búsqueda.

  • bounds: Un vector que contiene los límites geográficos de la búsqueda. Se puede insertar un cuadro delimitador ya especificado en un objeto, concatenar los valores del vector, o insertar un objeto de características simples (Simple Feature, sf). El argumento bounds es importante porque si obtenemos datos de iNaturalist, las únicas columnas que obtenemos con información acerca de la región o área donde se hicieron las observaciones son:

  • place_guess: Contiene el nombre de la región, pero su precisión y los nombres utilizados para cada región varía mucho.

  • latitue: Posición en el eje vertical del sistema de coordenadas.

  • longitude: Posición en el eje horizontal del sistema de coordenadas.
    Esto crea un problema a la hora del filtrar los datos por el nombre de una región, pues es difícil encontrar un solo valor que encompase a todas las variantes del nombre utilizado para esa región. iNaturalist se encuentra a nivel mundial, y usted puede acceder a todos esos datos. Sin embargo, hoy accederemos solamente a datos de Puerto Rico. Entonces, lo primero antes de acceder a lo datos de iNaturalist, es crear un objeto que contenga los límites geográficos de interés crea. Para esto se crea un objeto que contenga un cuadro delimitador (bounding box):

cajapr <- c(
  17.75, #Latitud Sur
   -67.4, #Longitud Oeste
  18.75, #Latitud Norte
  -65.15 #Longitud Este
  )

cajapr
## [1]  17.75 -67.40  18.75 -65.15
library(rinat)

Ahora podemos acceder a datos de Puerto Rico utilizando el objeto cajapr. Para este ejercicio utilizaremos datos de orquídeas pertenecientes al género Eulophia. En Puerto Rico se han reportado 3 especies de este género Eulophia alta, Eulophia maculata y Eulophia graminea. De estos, sólo E. alta es considerada nativa de la isla. Entonces, utilizando la función get_inat_obs podemos acceder a los datos de Eulophia en Puerto Rico

eulophia <- get_inat_obs(taxon_name = "Eulophia", 
                            quality = 'research', 
                            geo = T, 
                            maxresults = 1000,
                            #bounds = cajapr)
)

eulophia$scientific_name <- as.factor(eulophia$scientific_name)

flextable(head(eulophia)) # Para ver las primeras 6 lineas en una tabla bonita

scientific_name

datetime

description

place_guess

latitude

longitude

tag_list

common_name

url

image_url

user_login

id

species_guess

iconic_taxon_name

taxon_id

num_identification_agreements

num_identification_disagreements

observed_on_string

observed_on

time_observed_at

time_zone

positional_accuracy

public_positional_accuracy

geoprivacy

taxon_geoprivacy

coordinates_obscured

positioning_method

positioning_device

user_id

user_name

created_at

updated_at

quality_grade

license

sound_url

oauth_application_id

captive_cultivated

Eulophia graminea

2025-10-18 21:49:09 -0400

Pegasus Dr, Orlando, FL, US

28.60211

-81.19882

Chinese Crown Orchid

https://www.inaturalist.org/observations/325059424

https://inaturalist-open-data.s3.amazonaws.com/photos/588471937/medium.jpg

jlemos

325,059,424

Chinese Crown Orchid

Plantae

427,629

1

0

2025-10-18 21:49:09

2025-10-18

2025-10-19 01:49:09 UTC

Eastern Time (US & Canada)

20

20

false

9,877,282

2025-11-05 18:00:04 UTC

2025-11-05 18:22:01 UTC

research

CC-BY-NC

843

false

Eulophia hians hians

2025-11-05 09:02:32 +0200

Underberg, South Africa

-29.71478

29.57881

Blue Yawning Harlequin

https://www.inaturalist.org/observations/325037529

https://inaturalist-open-data.s3.amazonaws.com/photos/588429037/medium.jpg

felicia_girl

325,037,529

Blue Yawning Harlequin

Plantae

599,258

2

0

2025-11-05 09:02:32

2025-11-05

2025-11-05 07:02:32 UTC

Pretoria

40

40

open

false

9,597,197

Gabrielle Gray

2025-11-05 15:10:28 UTC

2025-11-05 17:00:36 UTC

research

CC-BY-NC

2

false

Eulophia maculata

2025-10-31 11:23:27 -0400

Dagny Johnson Key Largo Hammock Botanical State Park Trail, Key Largo, FL, US

25.17578

-80.36560

Monk Orchid

https://www.inaturalist.org/observations/325037305

https://inaturalist-open-data.s3.amazonaws.com/photos/588428449/medium.jpg

jhart

325,037,305

Monk Orchid

Plantae

1,453,469

1

0

2025-10-31 11:23:27

2025-10-31

2025-10-31 15:23:27 UTC

Eastern Time (US & Canada)

4

4

open

false

512,897

Julie Hart

2025-11-05 15:08:05 UTC

2025-11-05 15:30:17 UTC

research

CC-BY

843

false

Eulophia petersii

2025-11-03 17:32:38 +0200

Kruger Park, South Africa

-22.43709

31.14503

Garden Harlequin

https://www.inaturalist.org/observations/325019883

https://inaturalist-open-data.s3.amazonaws.com/photos/588395840/medium.jpg

drmckenzie

325,019,883

Garden Harlequin

Plantae

489,945

1

0

2025-11-03 17:32:38

2025-11-03

2025-11-03 15:32:38 UTC

Pretoria

open

false

gps

gps

2,434,483

Duncan McKenzie

2025-11-05 12:30:07 UTC

2025-11-05 15:17:27 UTC

research

CC-BY-NC

2

false

Eulophia tristis

2025-11-04 15:06:03 +0200

Bitou Local Municipality, South Africa

-34.07207

23.31828

Horned Cinderella Orchid

https://www.inaturalist.org/observations/324871998

https://static.inaturalist.org/photos/588101723/medium.jpg

kirsten243

324,871,998

Horned Cinderella Orchid

Plantae

1,453,533

2

0

2025-11-04 15:06:03

2025-11-04

2025-11-04 13:06:03 UTC

Pretoria

open

false

gps

gps

3,564,076

Kirsten Deacon

2025-11-04 14:18:00 UTC

2025-11-05 16:18:43 UTC

research

2

false

Eulophia pardalina

2017-12-12 11:17:00 +0300

Alaotra-Mangoro, MG-TM, MG

-18.94650

48.43270

https://www.inaturalist.org/observations/324855850

https://inaturalist-open-data.s3.amazonaws.com/photos/588055048/medium.jpg

ajpembo

324,855,850

Eulophia pardalina

Plantae

1,453,525

2

0

2017/12/12 11:17 AM

2017-12-12

2017-12-12 08:17:00 UTC

Nairobi

206

30,615

obscured

true

5,630,361

2025-11-04 11:42:40 UTC

2025-11-04 22:39:07 UTC

research

CC-BY-NC

false

bounds = cajapr Con el siguiente código podemos ver de forma rápida cuántas observaciones de cada especie hemos obtenido de iNaturalist:

summary(as.factor(eulophia$scientific_name))
##         Eulophia aculeata             Eulophia alta       Eulophia angolensis 
##                         1                        33                         4 
##       Eulophia beravensis          Eulophia bolusii      Eulophia bouliawongo 
##                         1                        18                         1 
##        Eulophia calcarata      Eulophia caricifolia           Eulophia cernua 
##                         1                         3                        84 
##          Eulophia citrina     Eulophia clitellifera       Eulophia cochlearis 
##                         1                         8                        17 
##          Eulophia cooperi         Eulophia cristata        Eulophia cucullata 
##                         1                         3                        41 
##        Eulophia decaryana           Eulophia ensata      Eulophia epidendraea 
##                         1                        17                         1 
##         Eulophia exaltata        Eulophia filifolia       Eulophia flabellata 
##                         1                         1                         1 
##         Eulophia gracilis         Eulophia graminea       Eulophia guineensis 
##                         1                       135                         8 
##         Eulophia herbacea      Eulophia hereroensis            Eulophia hians 
##                         3                         5                        52 
##      Eulophia hians hians Eulophia hians inaequalis       Eulophia horsfallii 
##                        21                        20                        15 
##       Eulophia humaniorum        Eulophia lamellata     Eulophia leontoglossa 
##                         1                         6                         2 
##   Eulophia livingstoneana      Eulophia longisepala         Eulophia maculata 
##                         1                         1                       312 
##        Eulophia malangana        Eulophia micrantha             Eulophia nuda 
##                         1                        26                         2 
##           Eulophia obtusa     Eulophia odontoglossa           Eulophia ovalis 
##                         1                         3                         1 
##  Eulophia ovalis bainesii        Eulophia pardalina       Eulophia parviflora 
##                         3                         1                        30 
##         Eulophia petersii            Eulophia picta      Eulophia plantaginea 
##                         9                         4                         3 
##          Eulophia pulchra           Eulophia ramosa     Eulophia roempleriana 
##                         3                         1                         1 
##        Eulophia siamensis     Eulophia spathulifera         Eulophia speciosa 
##                         1                         1                        46 
##    Eulophia streptopetala          Eulophia tenella          Eulophia tristis 
##                        30                         1                         5 
##      Eulophia welwitschii       Eulophia zollingeri 
##                         2                         3

Ahora que hemos obtenido los datos, podemos observar su distribución en el mapa de Puerto Rico utilizando leaflet.

26.7 Utilizando Leaflet

La función base del paquete leaflet es leaflet(), con esta se activa un artilugio (widget en inglés) sobre el cuál se construye el mapa. Esta función debe estar unida a otra función como addTiles() que añade el mapa.

leaflet() %>% 
  addTiles() 

Una vez tenemos el artilugio y el mapa, añadimos una capa que incluye los datos que se desean visualizar con marcadores sobre el mapa con la función addMarkers() dentro del cual se deben especificar los parámetros lng (longitud) y lat (latitud). Note que también se especifica el data.frame que contiene los datos bajo la función leaflet(). Cuando se trabaja en Leaflet, al especificar las variables a utilizar, es necesario colocar una virgulilla (~) antes de la variable. Esto le deja saber a R que lo que se especifica es una variable dentro del data.frame mencionado en la primera capa bajo la función leaflet().

names(eulophia)
##  [1] "scientific_name"                  "datetime"                        
##  [3] "description"                      "place_guess"                     
##  [5] "latitude"                         "longitude"                       
##  [7] "tag_list"                         "common_name"                     
##  [9] "url"                              "image_url"                       
## [11] "user_login"                       "id"                              
## [13] "species_guess"                    "iconic_taxon_name"               
## [15] "taxon_id"                         "num_identification_agreements"   
## [17] "num_identification_disagreements" "observed_on_string"              
## [19] "observed_on"                      "time_observed_at"                
## [21] "time_zone"                        "positional_accuracy"             
## [23] "public_positional_accuracy"       "geoprivacy"                      
## [25] "taxon_geoprivacy"                 "coordinates_obscured"            
## [27] "positioning_method"               "positioning_device"              
## [29] "user_id"                          "user_name"                       
## [31] "created_at"                       "updated_at"                      
## [33] "quality_grade"                    "license"                         
## [35] "sound_url"                        "oauth_application_id"            
## [37] "captive_cultivated"
leaflet(eulophia) %>% 
  addTiles() %>% 
  addMarkers(lng = ~longitude, 
             lat = ~latitude)

Una vez los marcadores están establecidos, es posible añadir etiquetas que contengan información acerca de las observaciones con el parámetro popup de la función addMarkers(). Por ejemplo, se pueden colocar etiquetas que contengan información del lugar de la observación especificando que la etiqueta contenga la información de la variable place_guess. Para ver la etiqueta debe hacer clic sobre el marcador de interés.

names(eulophia)
##  [1] "scientific_name"                  "datetime"                        
##  [3] "description"                      "place_guess"                     
##  [5] "latitude"                         "longitude"                       
##  [7] "tag_list"                         "common_name"                     
##  [9] "url"                              "image_url"                       
## [11] "user_login"                       "id"                              
## [13] "species_guess"                    "iconic_taxon_name"               
## [15] "taxon_id"                         "num_identification_agreements"   
## [17] "num_identification_disagreements" "observed_on_string"              
## [19] "observed_on"                      "time_observed_at"                
## [21] "time_zone"                        "positional_accuracy"             
## [23] "public_positional_accuracy"       "geoprivacy"                      
## [25] "taxon_geoprivacy"                 "coordinates_obscured"            
## [27] "positioning_method"               "positioning_device"              
## [29] "user_id"                          "user_name"                       
## [31] "created_at"                       "updated_at"                      
## [33] "quality_grade"                    "license"                         
## [35] "sound_url"                        "oauth_application_id"            
## [37] "captive_cultivated"
leaflet(eulophia) %>% 
  addTiles() %>% 
  addMarkers(lng = ~ longitude, 
             lat = ~ latitude, 
             popup = ~ place_guess) #  cambiar a la variable de interes

La función paste0 es una función base de R que concatena todos los elementos en una línea de caracteres. Los caracteres introducidos serán interpretados como UTF-8 o codificación de caracteres. Estos caracteres pueden ser mezclados con valores de una variable de caracteres en un data.frame. En el siguiente ejemplo se crea una etiqueta que contiene la ubicación y la especie observada. Se utiliza la función paste0() para combinar caracteres y las variables scientific_name y place_guess del data.frame.

leaflet(eulophia) %>% 
  addTiles() %>% 
  addMarkers(lng = ~ longitude, 
             lat = ~ latitude, 
             popup = paste0("<B>Especie: </B>", "<I>", eulophia$scientific_name, "</I>",
                            "<br/>",
                            "<B>Colectado donde: </B>", eulophia$place_guess)
               )

26.7.1 addAwesomeMarkers: Cambiando el diseño de los marcadores

La función addAwesomeMarkers() puede ser utilizada en lugar de addMarkers() y permite utilizar marcadores con diferentes diseños que se pueden obtener de fontawesome. Es posible cambiar los colores de los marcadores utilizando la codificación de colores RGB en formato (#RRGGBB). La siguiente guía de colores en R creada por Melissa Clarkson (2010) explica como utilizar colores en R: A guide to using color in R. Adicional, esta guía creada por Derek H. Ogle (2022) es muy útil.

En schemecolor podemos encontrar las codificaciones de los colores y muchos funcionan para leaflet. Para hacer estos cambios utilizamos la función awesomeIcons() bajo el parámetro icon dentro de addAwesomeMarkers().

Dentro de la función awesomeIcons() podemos especificar varios parámetros como:

  • icon: El icono que desea utilizar para su marcador. Debe poner el nombre que aparece en la página web de iconos que esté utilizando (i.e., fontawesome).

  • library: Cuando se especifica un icono, es necesario especificar la biblioteca de donde se saca el icono. Si es de fontawesome sería 'fa'.

  • markerColor: Para cambiar el color del marcador (parte que rodea el icono), utilizando la codificación de colores de schemecolor.

  • iconColor: Para cambiar el color del icono del marcadora, también con la codificación de schemecolor.

leaflet() %>% 
  addTiles() %>% 
  addAwesomeMarkers(lng = eulophia$longitude, 
                    lat = eulophia$latitude, 
             popup = paste0("<B>Especie: </B>", "<I>", eulophia$scientific_name, "</I>",
                            "<br/>",
                            "<B>Colectado por: </B>", eulophia$place_guess),
            icon = awesomeIcons(icon = "leaf", library = "fa", 
                                markerColor = "blue",
                                iconColor =  "#FFFFFF")
               ) 

Cuando se visualiza una gran cantidad de datos, esto puede resultar en el solapamiento de los marcadores, lo cual no es muy agradable a la vista. Es posible crear agregados que ayuden a visualizar mejor y faciliten el movimiento a través del mapa con el parámetro clusterOptions bajo la función addAwesomeMarkers(). El valor de este parámetro debe ser la función markerClusterOptions().

leaflet() %>% 
  addTiles() %>% 
  addAwesomeMarkers(lng = eulophia$longitude, lat = eulophia$latitude, 
             popup = paste0("<B>Especie: </B>", "<I>", eulophia$scientific_name, "</I>",
                            "<br/>",
                            "<B>Colectado por: </B>", eulophia$place_guess),
            icon = awesomeIcons(icon = "leaf", library = "fa", 
                                markerColor = "darkgreen",
                                iconColor =  "#FFFFFF"),
            clusterOptions = markerClusterOptions()
               ) 

Y para culminar, es posible cambiar el diseño del mapa utilizando la función addProviderTiles() en lugar de addTiles(). Puede echar un vistazo a los diferentes diseños disponibles para Leaflet la página de proveedores de Leaflet en GitHub. Actualmente Leaflet en R admite diseños de los siguientes proveedores: OpenStreetMap, MapQuestOpen, Stamen, Esri and OpenWeatherMap.

icon1 <- awesomeIcons(icon = "smile-o",
                      iconColor = "#FFFFFF",
                      library = "fa",
                      markerColor = "darkgreen")

leaflet() %>% 
  addProviderTiles("OpenStreetMap.Mapnik") %>% 
  addAwesomeMarkers(lng = eulophia$longitude, lat = eulophia$latitude, 
             popup = paste0("<B>Especie: </B>", "<I>", eulophia$scientific_name, "</I>",
                            "<br/>",
                            "<B>Colectado por: </B>", eulophia$place_guess),
            icon = icon1
               )

26.8 Trabajando Variables Categóricas con Leaflet:

Es posible distinguir entre especies utilizando diferentes colores, pero debe utilizar la función addCircleMarkers() en lugar de addAwesomeMarkers(). Para colorear grupos en Leaflet es necesario generar una paleta de colores para las variables de interés de acuerdo al tipo de variable (i.e., numérica, factorial). Para esto se utilizan las funciones colorFactor(), colorNumeric(), colorBin(), o colorQuantile(). colorFactor() y colorNumeric() generan paletas de colores para variables factoriales y numericas, respectivamente; mientras que colorBin() y colorQuantile() generan paletas de colores para valores numéricos resumidos en grupos.

En este caso se está trabajando con una variable factorial que divide las observaciones entre 3 especies de orquídeas. Primero se crea una paleta de colores para una variable factorial con la función colorFactor(). Bajo esta función se especifican los parámetros palette y levels. palettees para especificar la paleta de colores a utilizar y levelsespecifica los niveles de la variable factorial. La paleta de colores que se utiliza ("Dark2") proviene del paquete RColorBrewer. Esta paleta de colores para los niveles de la variable factorial scientific_name del data.frame eulophia se guardará en un objeto llamado pal.

mypal <- colorFactor(palette = 'Set3',
            levels = levels(eulophia$scientific_name))

eulophia$scientific_name=as.factor(eulophia$scientific_name)

mypal <- colorFactor(palette = 'Set3',
            levels = levels(eulophia$scientific_name))

Ahora que se ha especificado los colores para los valores factoriales, es posible utilizar el objeto pal para colorear los marcadores circulares del mapa de Leaflet de acuerdo a la especie observada especificando el parámetro color

leaflet(eulophia) %>% 
  addTiles() %>% 
  addCircleMarkers(lng = ~ longitude, lat = ~ latitude,
                   popup = paste0("<B>Especie: </B>", "<I>", eulophia$scientific_name, "</I>",
                            "<br/>",
                            "<B>Colectado por: </B>", eulophia$place_guess),
                   color = ~ mypal(scientific_name)) 

Para ayudar con la visualización de datos pertenecientes a diferentes grupos, en ocasiones es bueno presentar una leyenda que indique los colores que representan cada grupo. Es posible añadir una leyenda al mapa de Leaflet utilizando la función addLegend() y especificando los siguientes parámetros:

  • position: Para determinar la posición de la leyenda, en este caso se colocará en la parte superior derecha, "topright", del mapa, pero podría colocarla en la parte inferior derecha ("bottomright"), la parte inferior izquierda ("bottomleft"), o la parte superior izquierda ("topleft").

  • pal: La paleta de colores a utilizar generada a través de la función colorFactor() o sus equivalentes (i.e., colorNumeric())

  • values: Los valores o la variable u objeto que contiene los valores utilizados.

  • title: El título de la leyenda especificado como una línea de caracteres.

leaflet(eulophia) %>% 
  addTiles() %>% 
  addCircleMarkers(lng = ~ longitude, lat = ~ latitude,
                   popup = paste0("<B>Especie: </B>", "<I>", eulophia$scientific_name, "</I>",
                            "<br/>",
                            "<B>Colectado por: </B>", eulophia$place_guess),
                   color = ~ pal(scientific_name)) %>% 
  addLegend(position = "topright", 
            pal = pal, 
            values = ~ scientific_name,
            title = "Species"
            )
iconcolor <- function(scienctific_name)

leaflet() %>% 
  addProviderTiles("Esri.WorldImagery") %>% 
  addAwesomeMarkers(lng = eulophia$longitude, lat = eulophia$latitude, 
             popup = paste0("<B>Especie: </B>", "<I>", eulophia$scientific_name, "</I>",
                            "<br/>",
                            "<B>Colectado por: </B>", eulophia$place_guess),
            icon = icon1
               )

L.circleMarker([place.lon, place.lat], { color: getColor(place.constructdate), // you can call the getColor function fillColor: getColor(place.constructdate), fillOpacity: 0.5 })