Category: Sin categoría

Consulta SQL de cercanía

En algunas plataformas o implementaciones se requiere procesar información de lugares con sus ubicaciones, almacenando Latitud y Longitud, por ejemplo tiendas, establecimientos, etc. Pero para su funcionamiento se requiere realizar consultas de cercanía, es decir, de acuerdo a un punto central encontrar otros puntos que están cerca alrededor de un radio determinado en kilómetros. Este tipo de consultas requiere conocimiento de la trigonometría pues requieren intervención del seno y coseno y conversión a radianes de la latitud y longitud para obtener correctamente la distancia en kilómetros. En esta ocasión presento una solución que es una consulta SQL para obtener dicha información. La consulta que se ocupa es la siguiente:
SELECT *,  ( 6371 * acos ( cos ( radians(LATITUDE_CENTER) ) * cos( radians(latitude) ) * cos( radians(longitude) – radians(LONGITUDE_CENTER) ) + sin ( radians(LATITUDE_CENTER) ) * sin( radians(latitude) ) ) ) AS distance FROM TABLE HAVING distance < DISTANCE ORDER BY distance LIMIT 0 , 20
 donde
LATITUDE_CENTER: latitud del punto central
LONGITUDE_CENTER: longitud del punto central
latitude: atributo de la table de tipo DOUBLE que almacena la latitude
longitude: atributo de la table de tipo DOUBLE que almacena la longitud
TABLE: tabla sobre la cual se hará la consulta
DISTANCE: distancia en kilómetros a buscar
Veamos un ejemplo. Tenemos el siguiente contexto donde una persona quiere consultar todos los cajeros automáticos que están en un radio de 2 kilómetros. Tenemos la siguiente tabla en un script SQL que se adjunta al final del post. La estructura de la tabla es la siguiente:

Figura 1. Esquema de la base de la tabla ATM

Figura 2. Datos almacenados en la tabla ATM

Teniendo la anterior table, ejecutamos la pasada consulta con un punto central Latitud: 19.535701 y Longitud: -96.903266, en la tabla atm, la consulta que se generaría es el siguiente:

 

SELECT *, ( 6371 * acos ( cos ( radians(19.535701) ) * cos( radians(latitude) ) * cos( radians(longitude) – radians(-96.903266) ) + sin ( radians(19.535701) ) * sin( radians(latitude) ) ) ) AS distance FROM atm HAVING distance < 2 ORDER BY distance LIMIT 0 , 20

El resultado obtenido es una lista de los cajeros automáticos que estén dentro del radio establecido con un atributo más cuyo nombre es distance y devuelve los kilómetros que hay de distancia entre el punto central y dicho punto.  Dichos resultados se ven como los siguientes:

Figura 3. Resultado de la consulta

Como pueden ver, todos los registros están dentro del rango que establecimos (2 Km), por lo que pueden jugar con los valores para observar los diferentes comportamientos.

Espero les haya ayudado esta publicación

Archivo de la Base de Datos: Descargar

Git básico

Git es software que se utiliza para mantenimiento y la gestión de versiones en sistemas complejos donde están involucrados varios integrantes en el proyecto o la cantidad de archivos es considerable, buscando así confiabilidad en el proceso de desarrollo y eficiencia, pero por estas mismas razones, a veces puede ser un poco confuso entenderlo. Es por esta razón que en este post el objetivo es mostrarles algunos comandos básicos de Git para sobrevivir en el ámbito laboral.

git init

Crea un repositorio vacío o bien reinicializa uno ya existente. Esto permite que puedas comenzar a trabajar con cualquier repositorio que no reconoce los comandos de git.

git clone <dirección>

Te permite crear una copia de la rama del master del proyecto almacenado remotamente a tu máquina (local). La dirección normalmente se encuentra en la página del proyecto y comúnmente termina en .git

git clone -b <rama> <dirección>

Te permite descargar una copia del proyecto pero solamente de la rama que ingreses. La dirección normalmente se encuentra en el repositorio del proyecto y comúnmente termina en .git

git add -A

Agrega  todo los archivos con los que trabajaste (modificados, nuevos y eliminados) para el siguiente commit. El comando git add se considera el primero de todos para realizar el proceso de commit hacia el repositorio remoto. Es decir, no ignora ningún tipo de cambio.

git add .

Realiza la misma acción que el comando pasado.

git add -u

Realiza una actualización de todos los archivos ya existentes solamente. Si agregaste o eliminaste, éstos no se visualizarán.

git commit -m “Comentario

Realiza el proceso de encapsulado de los archivos agregados con los comandos anteriores para considerar enviarlo en el próximo “commit”. -m es un parámetro que indica permitir añadir un mensaje cerrado entre comillas.

git push origin <rama>

Realiza la actualización del código preparado por los previos comandos en la rama que indiques. Es importante que los cambios que hayas hecho estén en la misma rama que subas.

git status

Te permite visualizar todos los archivos modificados (agregados, eliminados y actualizados)

git branch

Te permite visualizar todas las ramas disponibles en el repositorio remoto (el proyecto en la nube) y que fueron activadas localmente.

git pull origin <rama>

Realiza la descarga de todos los archivos ubicados remotamente (en la nube) de una rama en específico (puede ser la misma rama u alguna otra). Toma en cuenta que para ejecutar este comando sin problemas primero debes realizar un commit a tus propios cambios con los comandos que arriba compartí.

git merge <rama>

Realiza una fusión de archivos entre la rama en la que tu estás posicionado local y la rama que desees que se unan remotamente.

git remote add origin <dirección>

Este comando te permitirá agregar una ubicación remota al proyecto actual que tienes localmente. Esto es importante por que de lo contrario, si no existiera una relación entre tu código local con el código remoto, es imposible realizar commit a tu proyecto, ya que no sabrá a donde dirigir la actualización

git checkout -b <rama>

Te permite cambiar de una rama a otra por primera vez agregando su nombre. En caso de que ya esté la rama almacenada localmente, solo basta ejecutar la misma instrucción sin el parámetro -b.

git tag x.x.x

Te permite agregar como tag una versión del software del último commit en remoto. Los valores de versiones representan un cambio mayor en el primera valor, un cambio menor en el segundo, y la cantidad de bugs corregidos en el tercer valor.

git push origin — tags

Va acompañado con el anterior, y su función es agregar dicho tag al commit remoto.

git reset — hard

Te elimina todos los cambios hecho hasta ahora, regresando al último commit hecho remotamente.

Espero que estos comandos simples te permiten sobrevivir laboralmente, ya que son básicos, y si quisieras aprender más te recomiendo leer la documentación de Git publicado por Atlassian (https://es.atlassian.com/git/tutorials/learn-git-with-bitbucket-cloud/).

Someter paquetes al CRAN

El CRAN (Comprehensive R Archive Network) es un red que almacena contenido idéntico tales como las distribuciones de la consola de R, extensiones, paquetes, documentación, entre otras cosas más, siendo cada nodo una copia del nodo principal. Por esta misma razón, CRAN es quien se encarga del sometimiento, aceptación y publicación de los paquetes del lenguaje.

El proceso para someter un nuevo paquete puede ser complejo y confuso. Un dato interesante es que existen 8622 paquetes en el repositorio de R, que si lo comparamos con la cantidad de usuarios que al menos están interesados en este lenguaje que se estiman son 141,507 (dato obtenido de stackoverflow desde la sección de tags), representaría aproximadamente el 6%. Este porcentaje es relativamente pequeño y algunas veces fuentes de información sobre el sometimiento de paquetes para CRAN puede ser muy limitada. En esta publicación se explicará los pasos básico para preparar tu paquete y someterlo al CRAN. Para explicar todo el detalle se toma como referencia los sitios oficiales que describen este proceso tales como Writing R Extensions, Creating R Packages: A Tutorial  y CRAN Repository Policy, pero sólo abordaremos los pasos básicos.

1. Estructura del paquete

Antes de comenzar cualquier detalle, debes tomar en cuenta la estructura del directorio que se utilizará para contener todos los archivos y carpetas del paquete. Primero se debe crear una carpeta con el nombre del paquete que se desea (en esta ocasión lo llamaremos MiPaquete) y dentro de ella almacenará un archivo DESCRIPTION, otro con el nombre de NAMESPACE, una carpeta llamada “man” y otra llamada “R”. En total son 2 archivos sin extensión y dos carpetas, por lo que la estructura se puede visualizar en el diagrama de la figura 1.

Figura 1. Diagrama de la estructura de un paquete

2. FORMACIÓN DEL ARCHIVO DESCRIPTION

Como se puede visualizar, se creó un archivo con el nombre de DESCRIPTION (es importante respetar mayúsculas y minúsculas) sin extensión. Este archivo almacena información básica acerca del paquete siguiendo el formato “Debian Control File”, que consiste en crear campos con un nombre ASCII, inmediatamente seguido por dos puntos (:) y el valor del campo separado por un espacio entre los dos puntos y el valor. Para ver más detalladamente, esta descripción de muestra en la figura 2.

Figura 2. Formato del archivo DESCRIPTION

Dentro de los campos obligatorios a definir se encuentran:

Package: nombre del paquete. Sólo debe contener caracteres (ASCII) tipo letras, números y punto. Tener al menos dos caracteres e iniciar con una letra y no terminar con un punto.

Version: versión del paquete. Este valor es una secuencia de al menos 2 (usualmente 3) valores enteros no negativos separados por puntos o guión (-). De acuerdo a la semántica para generar una versión, el primer número representa el valor de la versión mayor y significa cambios incompatibles del sistema; el segundo número representa la versión menor y representa funcionalidades agregadas compatibles con la versión actual del sistema, y el tercer valor es el parche y significa los parches o correcciones agregados de errores a la actual versión. Normalmente en la versión mayor su significado es: 0 = versión alpha; 1 = versión beta; 2 = candidato a liberación; y 3 liberación final o estable.

License: licencia para el paquete y es importante asignar un valor, ya que sin el incluso sería incorrectamente en asuntos legales. Recordemos que R está bajo la licencia Generic Public Licence, por lo que su uso y librerías es libre. Las diferentes versiones posible a ocupar las puedes aquí y elegir la que mejor te convenga.

Description: descripción breve de lo que hace el paquete. En esta sección se puede utilizar varias sentencias, pero solamente un párrafo. Esta descripción debe ser completamente entendible para cualquier usuario de R. No se debe iniciar la descripción con la frase “This package” o algún similar.

Title: descripción corta del paquete y tiene como longitud máxima 65 caracteres. Puedes utilizar title case (letras en mayúsculas en  las palabras importantes) y no repetir el nombre del paquete.

Author: describe quién escribió el paquete. Este es un campo en texto plano con valores permitidos ASCII en forma Nombre Apellidos. Si existe más de un autor entonces serán separados por comas (,). En caso para los autores con dos apellidos (materno y paterno) es válido utilizar el guió (-) para unificarlo en un sólo apellido.

Maintainer: nombre de la persona que está a cargo del mantenimiento del paquete. En este campo sólo se permite un sólo nombre siguiendo el formato del autor y seguido de la dirección de correo electrónico encerrado en corchetes angulares (< >). Por ejemplo: Jesús López <jesus@email.com>.

Fuera de estos campos, los demás son opcionales, aunque muchos paquetes hacen uso de los campos ‘Imports’, ‘Exports’ y ‘Depends’, ya que sea muy normal que hagamos uso de otros paquetes para que el nuestro pueda funcionar.

3. FORMACIÓN DEL ARCHIVO NAMESPACE

Es parte fundamental el archivo NAMESPACE para un paquete, ya que R tiene un sistema de gestión de namespace para el código de sus paquetes, ya que este sistema le permite a los programadores de los paquetes especificar cuáles variables deberían ser exportados para hacerlos disponible a los usuarios del paquete, así como qué variables deben ser importados de otros paquetes. El archivo NAMESPACE (posicionado en la raíz de la carpeta del paquete) cuenta con sus comandos import() para importar los paquetes haciendo el llamado de la instrucción library o require para hacer uso de los demás paquetes. Por otro lado, también se cuenta con la instrucción export() para especificar qué variables serán exportados. Por ejemplo, si en tu paquete quieres hacer uso del paquete IMPACT que se encarga de realizar un análisis multivariante del Impacto de los Items para un cuestionario, sólo basta con colocar en el archivo NAMESPACE la instrucción import(IMPACT); pero también es necesario hacerlo en el archivo DESCRIPTION en el campo de Imports: IMPACT. Si quieres poner en uso alguna de las funciones a los usuarios de tu paquete (por ejemplo, creas una función llamada calculoPromedio), entonces basta con colocar en el archivo NAMESPACE la instrucción export(calculoPromedio).

Ahora bien, si sólo deseas importar alguna variable o función de otro paquete a tu propio paquete existe una instrucción llamada importFrom(paquete,variable), donde el paquete es el nombre del paquete que deseas utilizar y variable el nombre de al variable o función que deseas importar de ese paquete.

Para gestionar de mejor forma y más fácil la definición de este archivo, se recomienda utilizar roxygen2 en cada función del paquete que se explicará en la siguiente sección.

4. CARPETA R

Dentro de la carpeta R se almacena todo el código que hace funcional al paquete. Comúnmente se crea un archivo por función con la finalidad de contener nuestro código modular y así seguir las buenas prácticas de codificación. Una vez estando el paquete en el repositorio de CRAN, las funciones son cargadas automáticamente y podrán hacerse uso llamándolas como todos lo sabemos hacer: llamando el nombre de la función y sus parámetros.

Una cosa importante a considerar es la documentación del paquete, esto es un aspecto importante a considerar en el sometimiento de paquetes y los revisores toman en cuenta. Como muchos sabemos, cada función tiene descrito su funcionalidad, parámetros, etc. Para que se pueda generar la documentación de manera automática vamos a hacer uso de Roxygen para generar archivos .Rd (R documents). Para esto, es importante añadir en el archivo DESCRIPTION el siguiente campo

RoxygenNote: 5.0.1

que es la versión más reciente de esta herramienta (2 de julio del 2016). Con esto, agregamos la funcionalidad de generar la documentación automáticamente y dentro del archivo de cada función se agrega en la parte superior del archivo (función) las siguientes etiquetas:

#’ @title Nombre de la función

#’ @author Nombre del autor

#’ @description Descripción de la función

#’ @details Detalles de la función

#’ @return Valores que regresa la función

#’ @references Referencias usadas para implementar la función

#’ @import Librerías que e utilizarán para la ejecución de esta función

#’ @importFrom <nombre de la librería sin corchetes angulares> <nombre de la función sin corchetes angulares>

#’ @export nombre de la librería a exportar

Siguiendo la declaración de estas etiquetas en cada función, durante la generación del paquete y validación, la documentación de cada uno será realizada automáticamente, se generará la carpeta man y se almacenará ahí. Si quieres aprender un poco más sobre roxygen2 puedes dar clic aquí o al final de este artículo que dejaré los recursos necesarios.

5. COMPILACIÓN Y REVISIÓN

Finalmente, después de configurar los antes descrito y haber codificado tus funciones, el paso final es ejecutar la compilación y su revisión. Antes de hacer esto es importante considerar que las carpetas y subcarpetas de tu paquete deben estar completamente limpias, esto quiere decir que no debe haber ningún archivo extra del que se ha especificado aquí, esto incluye los archivos temporales. Para saber si contienes archivos temporales debes habilitar su visualización en Windows o en algún sistema UNIX. Si hablamos de un sistema Mac OS X que sus temporales son los más difíciles de eliminar, desde la Terminal (Aplicaciones – Utilidades – Terminal) debes posicionarte sobre tu carpeta del paquete y ejecutar el siguiente comando:

find . -name “.*” -exec rm -rf {} \;

el cual intentará buscar todos los archivos temporales y ocultos y los eliminará de la misma carpeta posicionada y de sus subdirectorios. Una vez hecho esto, retrocede un directorio desde la Terminal y estarás posicionado sobre la carpeta que almacena tu carpeta del paquete. Para empezar con la compilación de tu paquete se procede a ejecutar el siguiente comando:

R CMD build <Paquete>

donde Paquete es el nombre de la carpeta de tu paquete, que en nuestro caso se llama MiPaquete, entonces en Terminal debería verse como:

R CMD build MiPaquete

y con esto realizará el proceso necesario. Una vez terminado el proceso de compilación, en el mismo directorio donde estás posicionado te generará un archivo comprimido con el nombre de tu paquete y extensión .tar.gz, el cual es el que CRAN te solicita que subas para que lo puedan evaluar y subir al repositorio. El siguiente paso es el de revisión con el siguiente comando:

R CMD check <Paquete>

donde Paquete es de la misma forma el nombre del paquete, por lo que se debería visualizar en Terminal como:

R CMD check MiPaquete

y lo que hará es revisar que el archivo este perfectamente estructurado para que pueda ser evaluado por el CRAN. En su ejecución en la Terminal se verán los resultados de cada evaluación que hace. Para que se pueda subir el comprimido al repositorio del CRAN y ser evaluado el resultado de esta evaluación debe ser “OK” en todos sus pasos. Si alguno llega a presentar warning, NOTE o failed, se deberá corregir ya que entonces sería el primer criterio de los evaluadores y será rechazado. Si todo el proceso de revisión fue satisfactorio, entonces ese archivo .tar.gz puede ser cargado en la página de presentación del paquete al CRAN (ir al sitio) y llenar los valores correspondientes. Sólo sigue las instrucciones hasta que te llegue un correo de confirmación de recepción de tu paquete.

El tiempo de evaluación no sobrepasa las 24 horas, comúnmente puede varias siendo desde 30 min para recibir una respuesta hasta 8 horas, dependiendo del revisor ya que todos (al menos los que he tenido la oportunidad de ver el proceso) son Europeos.

Existen muchas razones por las que pueden rechazar el paquete el equipo del CRAN, desde la modificación de ambientes globales hasta por una falta de ortografía, por lo que el proceso primerizo puede ser algunas veces frustrante y desesperante, sin embargo sólo recomiendo seguir estrictamente las políticas del CRAN para enviar paquetes. Una recomendación que dejo es que garanticen su funcionalidad en los diferentes sistemas operativos que fue diseñado su paquete, sobre todo si contiene archivos que dependan del sistema, ya que eso también es un factor de rechazo.

Si tienes alguna duda o requieren asesoría referente al tema, puedes dejar un comentario en la publicación o bien escribirme a mi correo hola@fcojlanda.me.

RECURSOS

Writing R Extensions

CRAN Repository Policy

Creating R Packages: A Tutorial – Friedrich Leisch

Generating Rd files

Paquete IMPACT

Submit package to CRAN