La función querxc() en el paquete warbleR permite buscar y descargar registros de señales acústicas de aves (e.g. cantos de aves) en la base de datos en linea Xeno-Canto. Estos registros tienen gran cantidad de metadatos, incluyendo el género, especie, subespecie, fecha, hora, y coordenadas geográficas entre otras. Estos datos los vamos a usar para ver la variación en los patrones estacionales de actividad de las especies del género Turdus (al que pertenece el yigüirro Turdus grayi). Turdus es un grupo de distribución cosmopolita que se caracteriza por ser vocalmente muy activo, y por tanto esta ampliamente representado en Xeno-Canto.

Primero debemos instalar y cargar el paquete warbleR:

install.packages("warbleR")

library(warbleR)

 

Alternativamente, si la instalación tuvo algún problema, pueden cargar la función directamente desde el código en github así:

source("https://raw.githubusercontent.com/maRce10/warbleR/master/R/querxc.R")

 

Con querxc() podemos hacer búsquedas de familias, géneros o especies (tambien busquedas por sitios, grabadores, países, etc, pero estas son mas complejas). En nuestro caso vamos a bajar los metadatos para las grabaciones del género Turdus de la siguiente forma:

turdus <- querxc("Turdus", download = FALSE)

 

Podemos ver los nombres de las columnas para darnos una idea de lo que contienen los metadatos:

##  [1] "Recording_ID"      "Genus"             "Specific_epithet" 
##  [4] "Subspecies"        "English_name"      "Recordist"        
##  [7] "Country"           "Locality"          "Latitude"         
## [10] "Longitude"         "Vocalization_type" "Audio_file"       
## [13] "License"           "Url"               "Quality"          
## [16] "Time"              "Date"              "Altitude"         
## [19] "file.name"         "Spectrogram_small" "Spectrogram_med"  
## [22] "Spectrogram_large" "Spectrogram_full"  "Length"           
## [25] "Uploaded"          "Other_species"     "Remarks"          
## [28] "Bird_seen"         "Playback_used"     "Other_species1"   
## [31] "Other_species2"    "Other_species3"    "Other_species4"   
## [34] "Other_species5"    "Other_species6"    "Other_species7"   
## [37] "Other_species8"    "Other_species9"    "Other_species10"  
## [40] "Other_species11"   "Other_species12"   "Other_species13"  
## [43] "Other_species14"   "Other_species15"   "Other_species16"

 

Por supuesto también podemos usar head() para ver las primeras filas:

head(turdus[, 1:12])
##   Recording_ID  Genus Specific_epithet Subspecies         English_name
## 1       504016 Turdus     litsitsirupa            Groundscraper Thrush
## 2       509167 Turdus     litsitsirupa            Groundscraper Thrush
## 3       403680 Turdus     litsitsirupa            Groundscraper Thrush
## 4       347146 Turdus     litsitsirupa            Groundscraper Thrush
## 5       300630 Turdus     litsitsirupa   simensis Groundscraper Thrush
## 6       300628 Turdus     litsitsirupa   simensis Groundscraper Thrush
##       Recordist  Country                             Locality   Latitude
## 1       Aladdin Ethiopia                  North Shewa, Amhara   9.819800
## 2 Peter Boesman   Zambia Mkushi farm region, Central province -13.655075
## 3 Mary Simmonds Ethiopia         Agoro Lodge, Adigrat, Tigray  14.248900
## 4 Peter Boesman  Namibia                    Omaruru area west -21.447504
## 5 Peter Boesman Ethiopia                    Debre Birhan area   9.670645
## 6 Peter Boesman Ethiopia                   Debre Libanos area   9.711656
##   Longitude                                      Vocalization_type
## 1  39.73410 call, flight call, life stage uncertain, sex uncertain
## 2  29.35882                                                   song
## 3  39.48130                                                   call
## 4  15.88762                                          song and call
## 5  39.53370                                                   call
## 6  38.85794                                                   song
##                             Audio_file
## 1 //www.xeno-canto.org/504016/download
## 2 //www.xeno-canto.org/509167/download
## 3 //www.xeno-canto.org/403680/download
## 4 //www.xeno-canto.org/347146/download
## 5 //www.xeno-canto.org/300630/download
## 6 //www.xeno-canto.org/300628/download

 

Ejercicio 1


Con la función grep() podemos generar vectores con los indices (la posición en el vector) que nos indican si un texto (i.e. palabra) esta presente en cada uno de los elementos de un vector no-numérico. Por ejemplo este código nos dice si “ab” esta en cada elemento del vector v1:

v1  <- c("acd", "abc", "accb", "abb", "aab", "bc")

grep("ab", v1)
## [1] 2 4 5

 


1.1 Utilice esta función para eliminar los registros que no tengan la palabra “song” del juego de datos turdus.


1.2 ¿Cómo puede hacer que la función no tome en cuenta si las letras están en mayúscula o minúscula (osea que tome “Song”, “song” y “SONG” como lo mismo)? (pista: Fíjese en la descripcíón de los argumentos en la documentación de la función).


1.3 Elimine nuevamente los registros del juego de datos ignorando mayúsculas/minúsculas.


Podemos darnos una idea de la distribución geográfica de los datos con un histograma de la longitud:

# hacer histograma 
hist(turdus$Longitude, main = NULL, col = terrain.colors(20, alpha = 0.5)[2])

#poner linea roja entre viejo y nuevo mundo
abline(v = -25, col = "red", lty = 3, lwd = 2)

 

En ese gráfico podemos ver como se separan las grabaciones del viejo y nuevo mundo. Podemos suponer que menos de -25 de Longitud es el nuevo mundo. Esto se puede confirmar viendo los países que quedan por debajo de ese umbral:

unique(turdus$Country[turdus$Longitude < - 25])
##  [1] "Brazil"             "Venezuela"          NA                  
##  [4] "Argentina"          "Colombia"           "Guyana"            
##  [7] "Bolivia"            "Ecuador"            "Peru"              
## [10] "Portugal"           "Canada"             "New Zealand"       
## [13] "Chile"              "Costa Rica"         "Honduras"          
## [16] "Mexico"             "Guatemala"          "El Salvador"       
## [19] "Uruguay"            "Paraguay"           "United Kingdom"    
## [22] "French Guiana"      "Suriname"           "Panama"            
## [25] "Nicaragua"          "Belize"             "United States"     
## [28] "Trinidad & Tobago"  "St Lucia"           "Dominican Republic"
## [31] "Jamaica"            "Cuba"               "Bahamas"           
## [34] "Puerto Rico"        "France"             "Dominica"

 

El Reino Unido sale por la colonia que tiene en las Malvinas:

turdus$Locality[turdus$Country == "United Kingdom" & turdus$Longitude < -25 & !is.na(turdus$Longitude)]
## [1] "The Rookery, Saunder Island, Falkland Islands"

 

 

Ejercicio 2


2.1 Divida el juego de datos turdus en dos juegos de datos para el viejo y nuevo mundo. Use los nombres nue.turdus y vie.turdus. Note que algunos registros no poseen coordenadas:

any(is.na(turdus$Longitude))
## [1] TRUE


2.2 Debe eliminar los registros con NAs antes de crear los juegos de datos nuevos. También elimine los datos que tiene NAs en la columna “Date” (esto será importante mas adelante):


2.3 Utilice la función table() para ver el número de observaciones por especie:


Podemos extraer los nombres de las especies de el resultado de table() usando la función names().

names(table(nue.turdus$Specific_epithet))
##  [1] "albicollis"     "amaurochalinus" "assimilis"      "aurantius"     
##  [5] "chiguanco"      "daguae"         "falcklandii"    "flavipes"      
##  [9] "fulviventris"   "fumigatus"      "fuscater"       "grayi"         
## [13] "haplochrous"    "hauxwelli"      "ignobilis"      "iliacus"       
## [17] "infuscatus"     "lawrencii"      "leucomelas"     "leucops"       
## [21] "lherminieri"    "maculirostris"  "maranonicus"    "merula"        
## [25] "migratorius"    "nigrescens"     "nigriceps"      "nudigenis"     
## [29] "obsoletus"      "olivater"       "philomelos"     "plebejus"      
## [33] "plumbeus"       "reevei"         "rufitorques"    "rufiventris"   
## [37] "rufopalliatus"  "sanchezorum"    "serranus"       "subalaris"     
## [41] "swalesi"

 

2.4 Combinando las funcione names() y table(), extraiga el nombre de las especies que tienen mas de 100 observaciones las especies que tengan menos de 100 observaciones de las bases de datos.


Con el operador %in% podemos generar un vector lógico que nos indique si un vector no-numérico contiene alguno de los elementos que se encuentran en un segundo vector. Por ejemplo:

l1 <- letters[1:5]
l1
## [1] "a" "b" "c" "d" "e"
l2 <- letters[4:10]
l2
## [1] "d" "e" "f" "g" "h" "i" "j"
l1 %in% l2
## [1] FALSE FALSE FALSE  TRUE  TRUE


  1. Usando el operador %in% y los vectores con los nombres de las especies creados en a), elimine las especies (columna Specific_epithet) que tienen menos de 100 observaciones en ambas bases de datos nue.turdus y vie.turdus. (Pista: las nuevas bases de datos deben tener 1223 filas y 5905 filas respectivamente)

En R podemos tratar las fechas como un clase especial de objeto “Date”. Esto nos permite, entre otras cosas, obtener valores para los meses y años:

nue.turdus$Date <- as.Date(nue.turdus$Date)

class(nue.turdus$Date)
## [1] "Date"
nue.turdus$Month <- format(nue.turdus$Date, "%m")

nue.turdus$Month <- as.numeric(nue.turdus$Month)
hist(nue.turdus$Month, xlim = c(1, 12), col = "skyblue")

 

Con esto podemos empezar a explorar la variación en la estacionalidad del comportamiento vocal (en otras palabras: cuando cantan en el año) a través del género. Por ejemplo podemos hacer un histograma de los cantos por mes para la especie Turdus grayi:

# filtrar grabaciones de T grayi
t.grayi <- nue.turdus[nue.turdus$Specific_epithet == "grayi", ]

# hacer histograma
hist(t.grayi$Month, xlim = c(1, 12), breaks = 12, col = "skyblue", 
     main = paste("Turdus",t.grayi$Specific_epithet[1]), xlab = "Mes")

 

Ejercicio 3


3.1 Construya una función que tome la base de datos nue.turdus y produzca un histograma similar al anterior para cada una de las especies. * EL gráfico debe ser multi-panel con 3 columnas * El usuario puede debe poder definir el numero de filas en el gráfico * El argumento que define las columnas debe tener un valor por defecto de 2 * Cada histograma debe tener el epíteto específico en el título

Pistas: * la función debe tener un bucle adentro (for o lapply()) * la función debe generar un sub-juego de datos para cada especie antes de hacer el histograma


3.2 Use la función sobre las bases de datos nue.turdus y vie.turdus.


3.3 Modifique la función para que el usuario pueda definir el color usado en los histrogramas y córrala dos veces con colores diferentes para el juego de datos nue.turdus.


3.4 Haga que el número de filas sea definido con base en número de especies en la base de datos. Pueden quedar paneles vacíos pero no especies sin gráfico. Córrala para los juegos de datos nue.turdus y vie.turdus.



Información de la sesión

## R version 4.0.1 (2020-06-06)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=es_CR.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=es_CR.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=es_CR.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=es_CR.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## loaded via a namespace (and not attached):
##  [1] compiler_4.0.1  magrittr_1.5    tools_4.0.1     htmltools_0.5.0
##  [5] yaml_2.2.1      stringi_1.4.6   rmarkdown_2.3   knitr_1.29     
##  [9] stringr_1.4.0   xfun_0.15       digest_0.6.25   rlang_0.4.6    
## [13] evaluate_0.14