Open Ignacio-Ibarra opened 5 days ago
Agrego un comentario acerca de la implementación de la función get_file_location()
dentro del contexto de nuestro paquete argendataR
, específicamente para automatizar el llenado del parámetro script
en la función write_output()
, así como en otras funciones relevantes como agregar_fuente_raw()
y actualizar_fuente_raw()
o las otras mencionadas arriba.
Objetivo: Queremos que get_file_location()
devuelva automáticamente el nombre del script actual (ej. "sarasa.R") cuando se llama dentro de write_output()
, agregar_fuente_raw()
, actualizar_fuente_raw()
, y otras funciones del paquete, independientemente de si el script se ejecuta en RStudio, a través de source()
desde la consola o línea por línea.
Funcionalidad: La función get_file_location()
se ha diseñado para detectar el contexto de ejecución:
rstudioapi::getSourceEditorContext()
para obtener el nombre del archivo.sys.calls()
) para identificar si el script fue ejecutado a través de source()
, extrayendo el nombre del archivo de los argumentos de la llamada.Inclusión en Funciones: La función write_output()
se modificará para llamar a get_file_location()
internamente, eliminando la necesidad de que el usuario especifique manualmente el parámetro script
. Asimismo, se sugiere incorporar esta lógica en otras funciones del paquete, como agregar_fuente_raw()
y actualizar_fuente_raw()
, para mantener la coherencia y facilitar el manejo de metadatos.
Pruebas: Hemos realizado pruebas utilizando un script de ejemplo ("sarasa.R") y se confirmó que get_file_location()
devuelve correctamente el nombre del archivo en diferentes contextos de ejecución.
Así podría ser la implementación.
# argendataR.R
get_file_location <- function() {
# 1. Si estamos en RStudio, intenta obtener el nombre del archivo actual.
if (interactive() && "rstudioapi" %in% rownames(installed.packages())) {
path <- tryCatch({
rstudioapi::getSourceEditorContext()$path
}, error = function(e) NULL)
# Si se obtiene un path, devolver solo el nombre del archivo
if (!is.null(path) && nzchar(path)) {
print("Obteniendo script_name desde RStudio (getSourceEditorContext)")
return(basename(path))
}
}
# 2. Si se ejecuta con source() desde la consola, intenta rastrear la pila de llamadas.
calls <- sys.calls()
for (call in rev(calls)) { # Recorre la pila en orden inverso
if (is.call(call) && identical(call[[1]], as.name("source"))) {
# Extrae el nombre del archivo del argumento de `source`
print("Obteniendo script_name desde llamada a source() en la consola")
return(basename(as.character(call[[2]])))
}
}
# 3. Si se ejecuta línea por línea en la consola, retorna un nombre predeterminado
print("Obteniendo script_name desde ejecución interactiva (consola o línea por línea)")
return("Consola o ejecución interactiva")
}
# La función write_output utiliza automáticamente get_file_location
write_output <- function(df, output_name, fuentes, subtopico, analista, pk,
es_serie_tiempo, columna_indice_tiempo, nivel_agregacion,
etiquetas_indicadores, unidades) {
# Obtiene el nombre del script llamador automáticamente
script_name <- get_file_location()
# Simula el guardado del dataset y metadatos, incluyendo el nombre del script
print(glue::glue("Guardando output '{output_name}' generado por '{script_name}'"))
print(glue::glue("Metadatos:\nFuentes: {paste(fuentes, collapse = ', ')}\n",
"Subtópico: {subtopico}\nAnalista: {analista}\n",
"Llave primaria: {paste(pk, collapse = ', ')}\n",
"Es serie de tiempo: {es_serie_tiempo}\n",
"Columna índice de tiempo: {columna_indice_tiempo}\n",
"Nivel de agregación: {nivel_agregacion}\n",
"Etiquetas de indicadores: {paste(names(etiquetas_indicadores), collapse = ', ')}\n",
"Unidades: {paste(names(unidades), collapse = ', ')}"))
}
Ejemplo de uso.
# sarasa.R
require(dplyr)
source("argendataR.R")
# Simulación de data wrangling
df_output <- data.frame(
anio = c(2020, 2021, 2022),
sector = c("Agricultura", "Industria", "Servicios"),
valor = c(10.5, 15.2, 12.3)
)
output_name <- "example_output"
fuentes <- c("R36C13", "R36C9", "R38C7")
subtopico <- "ACECON"
analista <- ""
pk <- c("anio", "sector")
es_serie_tiempo <- TRUE
columna_indice_tiempo <- "anio"
nivel_agregacion <- "pais"
etiquetas_indicadores <- list("sector" = "Sector")
unidades <- list("valor" = "Porcentaje del PIB a precios básicos")
df_output %>% write_output(
output_name = output_name,
fuentes = fuentes,
subtopico = subtopico,
analista = analista,
pk = pk,
es_serie_tiempo = es_serie_tiempo,
columna_indice_tiempo = columna_indice_tiempo,
nivel_agregacion = nivel_agregacion,
etiquetas_indicadores = etiquetas_indicadores,
unidades = unidades
)
Ejecutando desde la consola de RStudio
> source("sarasa.R")
[1] "Obteniendo script_name desde RStudio (getSourceEditorContext)"
Guardando output 'example_output' generado por 'sarasa.R'
Metadatos:
Fuentes: R36C13, R36C9, R38C7
Subtópico: ACECON
Analista:
Llave primaria: anio, sector
Es serie de tiempo: TRUE
Columna índice de tiempo: anio
Nivel de agregación: pais
Etiquetas de indicadores: sector
Unidades: valor
Ejecutando desde una sesión de R en terminal bash
$ R
R version 4.4.0 (2024-04-24 ucrt) -- "Puppy Cup"
Copyright (C) 2024 The R Foundation for Statistical Computing
Platform: x86_64-w64-mingw32/x64
R es un software libre y viene sin GARANTIA ALGUNA.
Usted puede redistribuirlo bajo ciertas circunstancias.
Escriba 'license()' o 'licence()' para detalles de distribucion.
R es un proyecto colaborativo con muchos contribuyentes.
Escriba 'contributors()' para obtener más información y
'citation()' para saber cómo citar R o paquetes de R en publicaciones.
Escriba 'demo()' para demostraciones, 'help()' para el sistema on-line de ayuda,
o 'help.start()' para abrir el sistema de ayuda HTML con su navegador.
Escriba 'q()' para salir de R.
> source("sarasa.R")
Cargando paquete requerido: dplyr
Adjuntando el paquete: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
[1] "Obteniendo script_name desde llamada a source() en la consola"
Guardando output 'example_output' generado por 'sarasa.R'
Metadatos:
Fuentes: R36C13, R36C9, R38C7
Subtópico: ACECON
Analista:
Llave primaria: anio, sector
Es serie de tiempo: TRUE
Columna índice de tiempo: anio
Nivel de agregación: pais
Etiquetas de indicadores: sector
Unidades: valor
Todos los códigos que crean o actualizan fuentes, raw o clean, utilizand funciones del paquete
argendataR
que han sido creadas para cada caso.Estas son:
raw
nueva utilizamos la funciónargendataR::agregar_fuente_raw
.raw
nueva utilizamos la funciónargendataR::actualizar_fuente_raw
.clean
nueva utilizamosargendataR::agregar_fuente_clean
.clean
nueva utilizamosargendataR::actualizar_fuente_clean
.En todos los casos, las funciones posee un parámetro
script
el cual es la ruta dentro del repositorio /etl/ donde se ubica el script que ejecuta dicha acción. Ejemplo de codigo donde se hace una limpieza de una fuente de datos de AFIP y se actualiza en la base de datos de fuentes limpias.Como se puede observar, en la anteúltima linea se setea el parámetro script, pasándole la variable code_name, la cual se desprende de:
El problema de esta linea es que sólo se puede ejecutar cuando el script se está ejecutando en un entorno de RStudio, en cambio si quisiéramos hacer
Esto se podría resolver con una función que pueda manejar el entorno en el que está corriendo el script, desde consola o dentro de RStudio. Un ejemplo
Incluso dicha función podría estar incorporada dentro de las mismas funciones para agregar o actualizar fuentes de modo tal que se automatice el parámetro
script