Hemos recibido de Conabio los datos de los ejemplares de las colecciones biológicas del Inecol. Se trata de los registros derivados de los proyectos de sistematización digital que esa institución ha apoyado. Nos compartieron la información como una base de datos relacional en el dialecto Postgresql. El modelo de datos se ilustra en la Figura 1. Puede apreciarse que el contenido medular de las colecciones se distribuye en tres tablas: ejemplar, nombre y geografía. Hay otras cinco tablas en el modelo de datos, que básicamente son catálogos necesarios para normalizar la captura de los datos y sistemas de referencia usados por Conabio para operar en forma estandarizada en el contexto internacional principalmente.
Organización de las tablas
El modelo de datos mostrado en la Figura 1 es sugerente de la naturaleza e intensión de usos de la abstracción propuesta al sistematizar los datos de colecciones biológicas en general. Un dato adicional nos lo da la cantidad de piezas de información recolectadas, lo que corresponde a las columnas en las tablas. Hagamos ahora un recuento de las columnas que tiene cada tabla en el modelo.
Código
q_cols_tabs <-paste("select table_name, count(column_name)","from information_schema.columns", "where table_schema = 'public'","group by table_name","order by table_name")q_num_cols <-dbSendQuery(con, q_cols_tabs)cols_tbls <-dbFetch(q_num_cols)dbClearResult(q_num_cols)cols_tbls %>%select(table_name, count) %>%flextable() %>%set_header_labels(table_name ="Tabla", count ="Núm. columnas") %>%width(width =c(5, 3), unit ="cm")
Tabla
Núm. columnas
catalogoejemplar
3
catalogonombre
3
conabioejemplar
4
conabiogeografia
55
conabionombre
113
ejemplar
45
geografia
31
nombre
26
Tabla 1. Tamaño de las tablas en número de colmnas que registran.
Información recibida
El número de registros que tienen las tablas que recibimos es el siguiente.
Código
q_reg_tabls <-paste("WITH tbl AS","(SELECT table_schema, table_name","FROM information_schema.tables","WHERE table_name not like 'pg_%' AND table_schema in ('public'))","SELECT table_schema, table_name,"," (xpath('/row/c/text()',", " query_to_xml(format('select count(*)"," as c from %I.%I',"," table_schema, table_name),", " FALSE, TRUE, ''))"," )[1]::text::int AS rows_n","FROM tbl ORDER BY rows_n DESC")q_tam_tabls <-dbSendQuery(con, q_reg_tabls)tam_tbls <-dbFetch(q_tam_tabls)dbClearResult(q_tam_tabls)tam_tbls %>%select(table_name, rows_n) %>%flextable() %>%set_header_labels(table_name ="Tabla", rows_n ="Núm. registros") %>%width(width =c(5, 3), unit ="cm")
Tabla
Núm. registros
catalogoejemplar
4,675,149
conabioejemplar
569,287
ejemplar
569,287
conabiogeografia
76,273
geografia
72,343
nombre
56,924
conabionombre
56,772
catalogonombre
28,231
Tabla 2. Registros existentes en cada una de las tablas recibidas.
Código
q_proy <-paste("SELECT proyecto, COUNT(ejemplar) AS ejemplares"," FROM ejemplar", "GROUP BY proyecto", "ORDER BY proyecto")q_proy <-dbSendQuery(con, q_proy)ejemp_proy <-dbFetch(q_proy)dbClearResult(q_proy)ejemp_proy %>%mutate(ejemplares =as.integer(ejemplares)) %>%flextable() %>%set_header_labels(table_name ="Proyecto", rows_n ="Núm. registros") %>%width(width =c(5, 3), unit ="cm") %>%colformat_int(j =2, big.mark =",")
proyecto
ejemplares
AA014
2,562
EE005
22,180
HA010
55,373
K005
5,069
ME014
321,707
Q017
162,396
Tabla 3. Número de registros relacionados con cada proyecto apoyado por Conabio.
Paseo por los datos
Para propósitos curatoriales, sin duda, la unidad básica es el ejemplar y hay precisamente una tabla al respecto. A continuación mostramos a manera de ejemplo una consulta sencilla para explorar las fuentes de las colecciones del Inecol registradas en esta tabla.
Colección de Federico Escobar Sarria (Entomológica)
3,412
Colección de Hongos
5,012
Colección del Servicio Entomológico Autónomo
2
Colección Entomológica
14,020
Colección Herpetológica
247
Colección Mastozoológica
45
Colección Miguel Ángel Morón (Coleoptera, Lamellicornia)
437
Colección Nacional de Anfibios y Reptiles
1
Colección Nacional de Insectos
86
Colección Nacional de Insectos, Estación de Biología Chamela
22
Colección Nacional Entomológica Forestal 'Biól. Raúl Muñiz Vélez'
1
Colección Particular de Aristeo Cuauhtémoc Deloya López
143
Colección Particular de Bruce D. Gill (Scarabaeidae, Coleoptera)
2
Colección Particular de Carmen Huerta
2
Colección Particular de Darío Navarrete Gutiérrez
4,413
Colección Particular de Delbert A. La Rue (Scarabaeidae, Coleoptera)
1
Colección Particular de Eduardo Pineda Arredondo
21
Colección Particular de Enrique Montes de Oca T.
3,141
Colección Particular de Federico Solórzano
117
Colección Particular de Fernando Z. Vaz de Mello (Coleoptera)
1,870
Colección Particular de Francisco J. Cabrero-Sañudo
3
Colección Particular de Giovanni Dellacasa (Coleoptera)
239
Colección Particular de Gonzalo Halffter
1,503
Colección Particular de L. E. Rivera
18
Colección Particular de Luis Leonardo Delgado
7
Colección Particular de Mario Zunino (Coleoptera)
1
Colección Particular de Mathieu, J.
10
Colección Particular de R. Sánchez G.
128
Colección Particular de Roberto Arce Pérez
1
Colección Particular de Sofía Anduaga
261
Colección Pedro Reyes Castillo (Coleoptera, Passalidae)
3,916
Collection d'insectes
11
Collection of Herpetology
2,092
Collezioni Zoologiche
280
Dudley Herbarium
145
Entomology Collection
106
Gray Herbarium
1,827
Henry and Anne Howden Personal Collection (Entomology)
291
Herbario
292,958
Herbario-Hortorio
28
Herbario 'Graciela Calderón y Jerzy Rzedowski'
217,770
Herbario 'Mtra. Graciela Calderón Díaz-Barriga y Dr. Jerzy Rzedowski Rotter'
1
Herbario Alfredo Barrera Marín
17
Herbario Arturo Gómez-Pompa
1
Herbario Etnobotánico
1
Herbario Jerzy Rzedowski y Graciela Calderón
646
Herbario María Agustina Batalla
6
Herbario Nacional de México, Plantas Vasculares
1,188
Herbario Nacional Forestal Biól. Luciano Vela Gálvez
1
Herbarium
841
Herbarium of the Arnold Arboretum
153
Herbier
103
Herpetology Collection
541
Insect Collection
616
Insecta Collection
1
Insectario
7
Insects, Arachnids and Myriapods Collection
10
Invertebrate Zoology Collection
3
Jardín Botánico Francisco Javier Clavijero
391
John G. Searle Herbarium
178
Kew Herbarium
405
National Entomological Collection
109
NO APLICA
2,441
NO DISPONIBLE
6,487
Paul K. Lago Personal Collection (Entomology)
1
Recent Invertebrate Collection
7
Richard A. Cunningham Personal Collection (Coleoptera)
1
Scott McCleve Personal Collection (Entomology)
2
United States National Herbarium
123
W. D. Edmonds Personal Collection (Coleoptera)
14
Xiloteca Dr. Faustino Miranda
376
Total
569,287
Tabla 4. Número de ejemplares por colección.
Tabla ejemplar
Explorando el contenido de la Tabla de ejemplares podemos ver que tiene 45 columnas, lo que junto con la estructura de relaciones puede expresar en forma muy rica la naturaleza geográfica, ecológica, morfológica y taxonómica de los ejemplares.
La base de datos está ampliamente documentada internamente. La consulta que sigue nos permite averiguar detalles del propósito o forma de uso de las distintas columnas. Por ejemplo, puede interesarnos comprender claramente como operan las que se usan como claves externas que controlan la vinculación con otras tablas.
Código
# En SQL postgres, los operadores || = concatena y :: = cast a tipo de dato# regclass es un tipo de dato "mágico" es una # especie de alias de oid: "object identifier".q_descr <-paste("SELECT column_name, col_description(","(table_schema||'.'||table_name)::regclass::oid, ","ordinal_position) as column_comment","FROM information_schema.columns","WHERE table_schema = 'public'","and table_name = 'ejemplar'")q_describe <-dbSendQuery(con, q_descr)cols_describe <-dbFetch(q_describe)dbClearResult(q_describe)cols_describe %>%datatable(colnames =c("Columna", "Descripción"), rownames =FALSE,options =list(initComplete =JS("function(settings, json) {",paste0("$(this.api().table().header()).css(","{'font-size': '14px', ", "'background-color': '#c2d1f0', ","'color': '#000'});"),"}"))) %>%formatStyle(columns =colnames(.$x$data), `font-size`='14px')
Tabla 5. Descripción del contenido en Tabla ‘ejemplar’.
Uso de la base de datos
Distribución geográfica de Tabebuia
Ahora queremos mostrar un ejemplo del potencial relacional del modelo de datos. Lo haremos interrogando a la base de datos sobre las especies del género Tabebuia. Hay que notar que hacer esto implica recurrir a la relación entre las tablas ejemplar y nombre, pues la primera sólo registra datos del origen (el colector por ejemplo) y de la situación de preservación del espécimen, pero no registra ningún dato taxonómico. Ni siquiera el binomio latino. Algo similar ocurre con la localización de los sitios de colecta. Para obtener sus datos debemos recurrir a la tabla geografia. El resultado de hacer todo esto se muestra a continuación.
Código
q_sp_geo <-paste("SELECT llaveejemplar as especimen, nombrevalidocatscat as sp,"," paisoriginal as pais, estadooriginal as estado,"," nombrecolector as colector, latitudgrados as lat_g,"," latitudminutos as lat_m, latitudsegundos as lat_s,"," longitudgrados as lon_g, longitudminutos as lon_m,"," longitudsegundos as lon_s","FROM conabionombre", " JOIN ejemplar on ejemplar.llavenombre=conabionombre.llavenombre"," JOIN geografia on ejemplar.llavesitio = geografia.llavesitio","WHERE conabionombre.grupo='Plantas' and"," conabionombre.nombrevalidocatscat like 'Tabebuia%'","ORDER BY sp")# Realiza la consulta a la base de datosq_sp_geo <-dbSendQuery(con, q_sp_geo)sp_geo <-dbFetch(q_sp_geo)dbClearResult(q_sp_geo)sp_geo %>%select(sp, colector, estado, pais, especimen) %>%datatable(colnames =c("Especie", "Colector", "Estado o provincia", "País", "ejemplar ID"), filter ="top", rownames =FALSE,options =list(initComplete =JS("function(settings, json) {",paste0("$(this.api().table().header()).css(","{'font-size': '14px', ", "'background-color': '#c2d1f0', ","'color': '#000'});"),"}"))) %>%formatStyle(columns =colnames(.$x$data), `font-size`='12px')
Tabla 6. Datos relacionados con las especies de Tabebuia.
Podemos hacer un mapa a partir de los datos disponibles, pues la tabla geografia también registra la latitud y la longitud de los sitios de colecta.
Figura 2. Mapa de distribución de los ejemplares de Tabebuia, registrados en la base de datos.
¿Cuántos invertebrados hay regsitrados?
En el proceso de valoración de lo que amablemente recibimos de Conabio, nos interesó saber cuántos registros de invertebrados habría en la base de datos compartida. Hicimos una consulta para obtener esta información y los resultados se muestran en el cuadro siguiente.
Código
q_invert <-paste("SELECT NO.grupo, NO.divisionphylumcat, NO.clasecat, NO.ordencat, EJ.proyecto, count(*)", " FROM ejemplar AS EJ", " JOIN conabiogeografia as GEO", " ON EJ.llaveregionsitiosig = GEO.llaveregionsitiosig", " JOIN conabionombre as NO"," ON EJ.llavenombre = NO.llavenombre", "WHERE NO.grupo = 'Invertebrados'","GROUP BY NO.grupo, NO.divisionphylumcat, NO.clasecat, NO.ordencat, EJ.proyecto")# Realiza la consulta a la base de datosq_invert <-dbSendQuery(con, q_invert)invertebrados <-dbFetch(q_invert)dbClearResult(q_invert)invertebrados %>%select(grupo, proyecto, divisionphylumcat, clasecat, ordencat, count) %>%datatable(colnames =c("Grupo", "Proyecto", "Phylum", "Clase", "Orden", "Núm. registros"), filter ="top", rownames =FALSE,options =list(initComplete =JS("function(settings, json) {",paste0("$(this.api().table().header()).css(","{'font-size': '14px', ", "'background-color': '#c2d1f0', ","'color': '#000'});"),"}"))) %>%formatStyle(columns =colnames(.$x$data), `font-size`='12px')
Tabla 7. Registros de inverterados en la base de datos.
El SNIB
La Figura 2 ilustra los ámbitos que convergen en la configuración de los datos sobre biodiversidad, desde la perspectiva del Sistema Nacional de Información sobre Biodiversidad de México (SNIB). Mucha más información sobre el modelo de datos que usa actualmente la Conabio puede encontrarse en el sitio Web del SNIB.
También puede interesar saber que el modelo de datos que utiliza el SNIB actualmente es más amplio que el que nos compartió Conabio con los datos de las colecciones del Inecol.