Nota: documento construido con base en el video de Julio Trenceti Criação de pacotes em R.

Filosofía

Requisitos

Configuración

  • Instalar versión dev de devtools
    • Instalar devtools
    • Luego devtools::install_github("hadley/devtools")
  • Sistemas operativos
    • Windows: instalar Rtools
    • Mac: instalar XCode
    • GNU Linux: instalar r-base-dev
      • sudo apt-get install r-base-dev
  • Verificar que todo está correcto
    • devtools:has_devel()
print(devtools::has_devel())
## [1] TRUE

Etapas sugeridas para crear una biblioteca de R

Componentes del paquete

Description

  • Versión del paquete (devtools::numeric_version())
  • Dependencias
  • Autor o autores
  • Licencias
  • Definir Imports y Suggests con usethis::use_package("xxx", type = "xxxx")
    • Imports: bibliotecas necesarias o esenciales
    • Suggests: bibliotecas sugeridas

Código R

  • Todas los códigos de R deben estar almacenados en la carpeta R
  • Todo se organiza a partir de funciones
  • Cargar todos los cambios (devtools::load_all())
  • Nota: no usar funciones como library(), require()

Documentación

  • Fácil de construir
    • Agregar encabezados a las funciones de R
    • Usar devtools::document()
    • Comenzar con #'
  • Etiquetas con @tag (ej. @param)
  • Texto
    • Primera sentencia es el título
    • Segunda sentencia es una descripción
    • Las demás sentencias indican detalles múltiples
#' Valor p en múltiples t.test 
#' 
#' Esta función genera una población de números aleatorios con
#' distribución normal y con base en ella se realizan múltiples
#' muestreos; luego se emplea el t.test para obtener el número de veces que
#' el contraste de hipótesis genera conclusiones erradas.
#' 
#' Detalles...
#' 
#' @param n tamaño poblacional (por defecto igual a 1000)
#' @param gp tamaño muestral (por defecto igual a 20)
#' @param cp número de comparaciones (por defecto igual a 100)
#' @param nc nivel de confianza (por defecto igual a 0.95)
#' 
#' @return un vector con los valores p obtenidos para las comparaciones
#' establecidas.
#' 
#' @examples
#' valp(n = 100, gp = 5, cp = 10, nc = 0.90)
#' valp(n = 100, gp = 10, cp = 10, nc = 0.95)
#' valp(n = 100, gp = 15, cp = 10, nc = 0.99)
#' 
#' @export
valp <- function(n = 1000, gp = 20,  cp = 100, nc = 0.95){
  pob = rnorm(n = n)
  g1 = list()
  vp = c()
  for (i in 1:cp) {
    g1[[i]] = sample(pob, size = gp)
    vp[i] = t.test(x = g1[[i]], alternative = "two.sided", conf.level = nc,
                   mu = 0)$p.value
  }
  return(vp)
}

Viñetas

  • Útil para dar una explicación general de una biblioteca.
  • Fácil de construir con RMarkdown.
  • Generalmente se usa para bibliotecas más complejas.
  • Usar usethis::use_vignette("nombre") para crear viñeta (con plantilla RMarkdown)
  • Para usar el paquete debe ser instalado mientras se desarrolla, de lo contrario no ejecuta correctamente (por ejemploa al crear las viñetas).

Pruebas (testthat)

  • Biblioteca testthat de Hadley.
  • devtools::use:testthat()
  • Definir lo que se quiere probar (función o parámetros) y lo que se espera de resultado.
  • Ejecutar las pruebas devtools::test sobre un nuevo Script que se almacena dentro de la carpeta testthat.
library(Pruebas)
context("Longitud del vector resultante")
test_that("Prueba la longitud del vector", {
  expect_equal(length(valp()), 100)
})

Namespace

  • Puede ser necesario para subir el paquete al CRAN.
  • Imports y Exports
  • Use @export para hacer que la función quede disponible para el usuario a través de ::
  • Use @import para especificar que dicha función (la de su paquete) necesita de otra función que pertenece a otra biblioteca.
#' Valor p en múltiples t.test 
#' 
#' Esta función genera una población de números aleatorios con
#' distribución normal y con base en ella se realizan múltiples
#' muestreos; luego se emplea el t.test para obtener el número de veces que
#' el contraste de hipótesis genera conclusiones erradas.
#' 
#' Detalles...
#' 
#' @param n tamaño poblacional (por defecto igual a 1000)
#' @param gp tamaño muestral (por defecto igual a 20)
#' @param cp número de comparaciones (por defecto igual a 100)
#' @param nc nivel de confianza (por defecto igual a 0.95)
#' 
#' @return un vector con los valores p obtenidos para las comparaciones
#' establecidas.
#' 
#' @examples
#' valp(n = 100, gp = 5, cp = 10, nc = 0.90)
#' valp(n = 100, gp = 10, cp = 10, nc = 0.95)
#' valp(n = 100, gp = 15, cp = 10, nc = 0.99)
#' 
#' @export
valp <- function(n = 1000, gp = 20,  cp = 100, nc = 0.95){
  pob = rnorm(n = n)
  g1 = list()
  vp = c()
  for (i in 1:cp) {
    g1[[i]] = sample(pob, size = gp)
    vp[i] = t.test(x = g1[[i]], alternative = "two.sided", conf.level = nc,
                   mu = 0)$p.value
  }
  return(vp)
}
#' Gráfico de valores p en t.test
#' 
#' Gráfico de valores p obtenido con valp.
#' 
#' @param x vector de valores p con la función \code{\link{valp}}
#'
#' @examples
#' grafvp(valp()) # 100 comparaciones por defecto
#' grafvp(valp(cp = 10)) # modificando el número de comparaciones
#'
#' @importFrom stats rnorm t.test
#'
#' @export
#' @import ggplot2
grafvp <- function(x) {
  df = data.frame(index = c(1:length(x)), valorP = x)
  g = ggplot(data = df, aes(x = index, y = valorP)) +
    geom_point() +
    geom_hline(yintercept = 0.01, lwd = 0.5, color = "firebrick", lty = 2) +
    geom_hline(yintercept = 0.05, lwd = 0.5, color = "dodgerblue4", lty = 2) +
    geom_hline(yintercept = 0.10, lwd = 0.5, color = "green4", lty = 2) +
    labs(x = "", y = "Valor p",
         title = paste0("Valores p para ", length(x), " comparaciones",
                        sep = ""),
         caption = "Línea roja: 0.01\nLínea azul: 0.05\nLínea verde: 0.10") +
    theme_linedraw()
  return(g)
}

Datos externos

  • Cuatro maneras de incluir datos en un paquete
    • Binarios (.Rdata) en la carpeta data/. Usar devtools::use_data()
    • Datos utilizados internamente por las funciones en R/sysdata.rda
    • Datos en texto (csv, txt, excel) en la carpeta inst/extdata
    • Datos que no son utilizados por el paquete en data-raw. Usar devtools::use_data_raw()
  • Documentar los datos es semejante a documentar las funciones adicionando @format y @source
  • No es necesario unsar @export

Código compilado (C, C++)

  • Usar el paquete Rcpp
  • Programar en C o C++
  • Usando R o RStudio y abriendo un nuevo archio, es posible visualizar un prototipo.
  • Usar CTRL + Shift + B en lugar de devtools::load_all()

Comprobar paquete con devtools::check()

  • Con devtools::check() se obtienen:
    • Errores
    • Advertencias
    • Anotaciones

Finalmente, sin errores, el paquete podrá ser almacenado en Github.

Probando el paquete “Pruebas”

devtools::install_github("Edimer/Pruebas", force = TRUE)
## Running /usr/lib/R/bin/R CMD INSTALL \
##   /tmp/RtmpkaTb3W/devtools2f0d4a683f73/Edimer-Pruebas-839cd59 \
##   '--library=/home/edimer/R/x86_64-pc-linux-gnu-library/3.4' \
##   --install-tests 
## * installing *source* package ‘Pruebas’ ...
## ** R
## ** tests
## ** preparing package for lazy loading
## ** help
## *** installing help indices
## ** building package indices
## ** installing vignettes
## ** testing if installed package can be loaded
## * DONE (Pruebas)
library(Pruebas)
valores <- valp(n = 1000000, gp = 1000, cp = 100, nc = 0.95)
set.seed(1000)
library(ggplot2)
grafvp(valores)