Como Acceder Bases de Datos con R

Publicado el domingo, 24 de enero de 2016

Para que un proyecto sea manejable, es importante tener una gestión no solo del código R, pero también de los datos. A lo largo de cualquier proyecto de análisis van a ocurrir correcciones, modificaciones y actualizaciones. Es posible manejar datos en archivos, pero con un poco de complejidad en los datos o en los cambios, rápidamente se vuelve inmanejable.

ODBC

Afortunadamente tenemos décadas de desarrollo de bases de datos, y estos permiten abstraer toda la gestión de datos a sistemas especializados. Como hay muchas DBMS (Data Base Management Systems, o en español: sistema de gestión de datos), se desarrollo una definición para una conexión genérica llamada ODBC. Esto es una sigla para Open Database Connectivity, el cual actúa como una interfaz entre la base de datos y el lenguaje de computo que lo consume.

Es por eso que RODBC se puede usar para conectar con muchos tipos de base de datos. PostgreSQL MySQL, Microsft SQL Server, IBM DB2, SQLite para nombrar los mas comunes.

Una típica conexión con RODBC podría tener la siguiente forma:

library(RODBC)
canal_bd <- odbcDriverConnect('driver={SQL Server};
                                  server=mi_maquina;
                                  database=mi_base_de_datos;
                                  trusted_connection=true')
resultado <- sqlQuery(canal_bd, 'SELECT * FROM mi_bd')  
odbcClose(canal_bd)

En palabras: abrimos un canal hacía la base de datos que llamamos canal_db. Esto ahora es un objeto que contiene toda la información para hacer una conexión usando ODBC, incluyendo el tipo de conexión (cual base de datos), la dirección de la maquina donde esta la base de datos (puede ser localhost cuando es el mismo computador donde estamos trabajando), y el nombre de la base de datos.

A nivel de tablas trabajamos al hacer búsquedas, como y entre varias formas que permite RODBC, podemos definir la búsqueda definiendo el canal (en nuestro caso canal_bd) y el código en SQL.

DBI

En una propuesta del 2000, David James propuso una nueva forma para conectar R con bases de datos. La propuesta la llamo DBI (Database Interface), que debía dar una respuesta nativa a R para funcionalidad similar a otros conectores, como el ODBC (de Microsoft), JDBC (de Oracle), el DBI de Perl y el DB-API de Python. El la decada posterior se ha dado mucho trabajo en esta aproximación y hay una lista extensa de conectores disponibles.

Estos incluyen RMySQL (para MySQL y MariaDB), RPostgreSQL, RSQlite y RSQLServer (para Microsoft SQL Server). Function de una forma mucho mas fácil en R que RODBC, aunque aquí también hay que especificar cual controlador (driver) se va a usar.

Por ejemplo, para hacer una conexión con SQLite se formularia la siguiente instrucción:

library(DBI)
conexion <- dbConnect(RSQLite::SQLite(), dbname = "mi_bd")
resultado <- dbSendQuery(con, "SELECT * FROM mi_bd")

Esto requiere que el controlador esté instalado por aparte (install.packages("RSQLite")). Son pocos los casos donde es preferible usar RODBC sobre el paquete basado en R-DBI.

dplyr

La gran desventaja de esta aproximación es que necesitas saber SQL para formular las búsquedas. Si recién estas aprendiendo R significa que necesitas un manual adicional de otro nuevo lenguaje. Y aún cuando eres un veterano en tanto R como SQL, el código SQL puede terminar siendo complejo.

Para solucionar esto, Hadley Wickham de RStudio escribió dplyr. Usando la facilidad de coneccion del sistema DBI (lo que llama el servicio de fondo, o back-end service) dplyr tiene acceso a las bases de datos mas comunes incluidos (que son SQLite, PostgreSQL, MySQL/MariaDB). Ademas hay una creciente lista de servicios de fondo para conectar no solo a DBMS tradicionales, pero también sistemas creados para gestionar "Big Data" como Hadoop (Spark, Hive, Impala) y BigQuery.

Conexiones se hacen de una forma muy directa, pero allí no esta la diferencia con RODBC. Lo importante es que ya no se necesitan ingresar búsquedas en SQL, si no que se puede usar una sintaxis mucho mas consistente con el resto del lenguaje R, y mucho mas consistente con la actividad de preparar datos para análisis.

Un ejemplo (del manual de dplyr para crear una base de datos en SQLite:

library(RSQLite)
library(dplyr)
mi_bd <- src_sqlite("mi_bd.sqlite3", create = T)
library(nycflights13) # datos ejemplo basados en vuelos saliendo de Nueva York en 2013
vuelos_sqlite <- copy_to(mi_bd, 
                         flights, 
                         temporary = FALSE, 
                         indexes = list(c("year", "month", "day"), 
                                          "carrier", "tailnum"))

Lo que nos da la posibilidad de conectar con la misma, que acabamos de crear:

vuelos_db <- src_sqlite('mi_bd.sqlite3', create = FALSE)
vuelos <- tbl(vuelos_db, "flights")

El objeto vuelos ahora es una referencia a una base de datos y las tablas que contiene. La magia de dplyr no esta tanto en la conexión a la base de datos, si no a la forma de acceso a los datos mismos. Primero explora lo que tienes:

> vuelos_db
  src:  sqlite 3.8.6 [mi_bd.sqlite3]
  tbls: flights, sqlite_stat1

Indica que vuelos_db es una base de datos en sqlite, con dos tablas: flights y sqlite_stat1 (el último es algo interno de sqlite). Los datos de la tabla flights lo hemos colocado en un objeto tbl con la segunda expresión. Y esta ahora nos permite trabajar con los datos usando dplyr. Ejemplos en la introducción a dplyr incluyen los verbos mas comunes en las expresiones dplyr: filter (filtrar, o seleccionar condicionalmente), arrange (ordenar), select (seleccionar variables / columnas) y summarize (resumir agregando filas o columnas) entre otros. Una combinación de verbos hace posible crear búsquedas que serían complejas y difíciles de leer en SQL de forma rápida y legible.


Si te gustó esta introducción o si tienes preguntas, mándame un mensaje a través de twitter @fransvandunne. Muchas veces no tengo la respuesta, pero teniendo la pregunta buscamos quien nos pueda ayudar.