5. Datos en el paquete

⏱ Enseñanza: 10 minutos · Ejercicios: 15 minutos

Preguntas

  • ¿Cómo agrego datos a un paquete?
  • ¿Cómo dejo registro de cómo preparé esos datos?
  • ¿Cómo se documentan los datos?

Objetivos

  • Guardar los datos crudos y el código que los prepara en data-raw/.
  • Agregar datos al paquete con usethis::use_data().
  • Documentar un conjunto de datos con roxygen2.
  • Usar los datos del paquete adentro de una función.

¿Por qué datos en un paquete?

Un paquete es una excelente forma de compartir datos chicos o medianos:

  • datos que usás en muchos proyectos (una tabla de códigos de provincias, de estaciones meteorológicas, de especies);
  • datos para enseñar (¿te acordás de palmerpenguins o de datos?);
  • datos que necesitan las funciones del paquete, como nuestros dichos;
  • datos para los test y ejemplos del paquete.

Nuestro vector de tres dichos no es suficiente. Vamos a usar una tabla de verdad, con el dicho, su significado, el país y un tema.

Datos crudos y código: data-raw/

Una buena práctica es guardar los datos crudos y el código que los prepara. De esta manera, cualquier persona (incluida vos en el futuro) puede ver de dónde salieron los datos y volver a generarlos. También muy util cuando debemos actualizar los datos con nuevos registros.

💻 En vivo

usethis::use_data_raw("dichos")
#> ✔ Creating data-raw/
#> ✔ Adding "^data-raw$" to .Rbuildignore
#> ✔ Writing data-raw/dichos.R

usethis creó la carpeta data-raw/, el script dichos.R y agregó la carpeta a .Rbuildignore: es parte de nuestro proyecto, pero no del paquete que se instala.

Bajamos el CSV a esa carpeta:

download.file(
  "https://yabellini.github.io/desarrollo_paquetes/datos/dichos.csv",
  "data-raw/dichos.csv"
)

(También podés descargarlo desde este enlace y moverlo a mano.)

Guardar los datos con use_data()

💻 En vivo, en data-raw/dichos.R

## Código para preparar el conjunto de datos `dichos`

library(tidyverse)

dichos <- read_csv("data-raw/dichos.csv", encoding = "UTF-8")

# Ordenamos por país para que sea más fácil de leer
dichos <- dichos |>
  arrange(pais, dicho)

usethis::use_data(dichos, overwrite = TRUE)

Corremos el script completo:

source("data-raw/dichos.R")
#> ✔ Setting LazyData to "true" in DESCRIPTION
#> ✔ Saving "dichos" to "data/dichos.rda"
#> ☐ Document your data (see <https://r-pkgs.org/data.html>).

use_data() guardó el objeto en data/dichos.rda y agregó LazyData: true en DESCRIPTION. Lazy quiere decir “perezoso”: los datos se cargan recién cuando alguien los usa.

devtools::load_all()
head(dichos)

Documentar los datos

Los datos también necesitan documentación. Pero no tienen código, así que ¿dónde va el bloque de roxygen2? En un archivo de R/, arriba del nombre del conjunto de datos entre comillas. Por convención lo llamamos R/data.R:

💻 En vivo

usethis::use_r("data")
#' Dichos y expresiones populares de América Latina
#'
#' Una colección de dichos, refranes y expresiones que se usan en distintos
#' países de América Latina, con su significado.
#'
#' @format Un data frame con 48 filas y 4 columnas:
#' \describe{
#'   \item{dicho}{El dicho o la expresión, como texto.}
#'   \item{significado}{Qué quiere decir, explicado en pocas palabras.}
#'   \item{pais}{País donde se usa. "Varios países" si se usa en muchos lugares.}
#'   \item{tema}{Tema del dicho: "dinero", "comida", "animales", etc.}
#' }
#' @source Recopilado para el taller de desarrollo de paquetes de LatinR 2026.
"dichos"
devtools::document()
?dichos
  • @format describe la estructura: qué tipo de objeto, cuántas filas y columnas, y qué tiene cada columna.
  • @source dice de dónde vienen los datos. ¡Es importante para dar crédito!
  • No hace falta @export: los datos de data/ siempre están disponibles.

Usar los datos en una función

Ahora dicho_al_azar() puede usar la tabla, y de paso le agregamos un argumento para elegir el país:

💻 En vivo, en R/dicho_al_azar.R

#' Elegir un dicho al azar
#'
#' Devuelve un dicho elegido al azar del conjunto de datos [dichos].
#' Podés elegir de qué país querés el dicho.
#'
#' @param pais Texto con el nombre de un país, por ejemplo `"Argentina"`.
#'   Si es `NULL` (el valor por defecto) se elige entre todos los países.
#'
#' @return Un texto (vector de caracteres) con el dicho.
#' @export
#'
#' @examples
#' dicho_al_azar()
#' dicho_al_azar(pais = "Argentina")
dicho_al_azar <- function(pais = NULL) {
  opciones <- dichos

  if (!is.null(pais)) {
    opciones <- dichos[dichos$pais == pais, ]
  }

  fila <- sample(nrow(opciones), size = 1)
  opciones$dicho[fila]
}
devtools::document()
dicho_al_azar(pais = "Chile")
#> [1] "Pasarlo chancho"

Las funciones del paquete pueden usar dichos directamente, porque los datos son parte del paquete.

Desafío 5.1: Datos adentro del paquete 10 minutos

  1. Corré usethis::use_data_raw("dichos").
  2. Descargá dichos.csv y guardalo en la carpeta data-raw/ de tu paquete.
  3. Completá data-raw/dichos.R para leer el CSV y guardarlo con usethis::use_data(). Corré el script.
  4. Corré devtools::load_all() y mirá los datos: head(dichos), table(dichos$pais).
usethis::use_data_raw("dichos")
download.file(
  "https://yabellini.github.io/desarrollo_paquetes/datos/dichos.csv",
  "data-raw/dichos.csv"
)

En data-raw/dichos.R:

dichos <- read.csv("data-raw/dichos.csv", encoding = "UTF-8")
usethis::use_data(dichos, overwrite = TRUE)
source("data-raw/dichos.R")
devtools::load_all()
head(dichos)
table(dichos$pais)

Desafío 5.2: Completá los espacios 7 minutos

Esta nueva versión de dicho_al_azar() usa los datos y tiene un argumento pais. Completá los ____, guardá, cargá y probá con dicho_al_azar(pais = "Chile").

#' Elegir un dicho al azar
#'
#' Devuelve un dicho elegido al azar del conjunto de datos [dichos].
#'
#' @param ____ Texto con el nombre de un país, por ejemplo `"Argentina"`.
#'   Si es `NULL` (el valor por defecto) se elige entre todos los países.
#'
#' @return Un texto (vector de caracteres de largo 1) con el dicho.
#' @export
#'
#' @examples
#' dicho_al_azar()
#' dicho_al_azar(pais = "Argentina")
dicho_al_azar <- function(pais = ____) {
  opciones <- dichos

  if (!is.null(pais)) {
    opciones <- dichos[dichos$____ == pais, ]
  }

  fila <- sample(nrow(____), size = 1)
  opciones$____[fila]
}
#' @param pais Texto con el nombre de un país, ...
dicho_al_azar <- function(pais = NULL) {
  opciones <- dichos

  if (!is.null(pais)) {
    opciones <- dichos[dichos$pais == pais, ]
  }

  fila <- sample(nrow(opciones), size = 1)
  opciones$dicho[fila]
}

No te olvides de devtools::document(): cambiamos la documentación.

Desafío 5.3: ¿Y si el país no existe? 3 minutos

Probá dicho_al_azar(pais = "Narnia"). ¿Qué devuelve? ¿Es útil para quien usa el paquete? Escribí en el documento colaborativo qué te gustaría que pase.

Devuelve character(0): un vector de texto vacío, sin ningún aviso. La función “falla en silencio”, y quien la usa no sabe qué hizo mal. Lo vamos a arreglar en el próximo episodio con un mensaje de error claro.

Desafío 5.4 (para llevar a casa): Sumá un dicho de tu país 5 minutos

  1. Agregá una fila a data-raw/dichos.csv con un dicho de tu país.
  2. Volvé a correr data-raw/dichos.R.
  3. Si agregaste un país nuevo, actualizá el número de filas en la documentación de R/data.R.
  4. Corré devtools::load_all() y buscá tu dicho.

Compartilo en el documento colaborativo: ¡juntamos todos los dichos del taller!

Puntos clave

  • usethis::use_data_raw() crea un lugar para los datos crudos y el código que los prepara.
  • usethis::use_data() guarda los datos en data/ para que sean parte del paquete.
  • Los datos se documentan en R/data.R, con un bloque de roxygen2 arriba del nombre entre comillas.
  • Las funciones del paquete pueden usar sus propios datos.