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

Deja un comentario