X– title: “Taller Práctico: Fundamentos de R para BI” output: html_notebook editor_options: markdown: wrap: sentence —
En este cuaderno de trabajo exploraremos el ecosistema Tidyverse. En la Inteligencia de Negocios, el 80% del tiempo se invierte en limpiar y estructurar los datos (Data Wrangling). Tidyverse nos proporciona una sintaxis clara y concatenada para transformar datos, calcular métricas y construir visualizaciones de impacto.
Para ejecutar cada bloque de código (chunk), puedes hacer
clic en el botón verde de “Play” en la esquina superior derecha del
bloque, o usar el atajo Ctrl + Shift + Enter.
Primero, activamos las librerías necesarias. tidyverse
incluye herramientas para manipulación (dplyr) y
visualización (ggplot2). lubridate es esencial
para manejar fechas.
# install.packages("tidyverse") # Descomentar y ejecutar solo si no está instalado
library(tidyverse)
library(lubridate)
A continuación, simularemos un conjunto de datos transaccionales,
emulando un registro de facturación electrónica. En un caso real, aquí
usaríamos funciones como read_csv() o
read_excel().
# Fijamos una semilla para asegurar la reproducibilidad del ejercicio
set.seed(123)
datos_facturacion <- tibble(
id_factura = 1001:2000,
fecha_emision = sample(seq(as.Date('2026-01-01'), as.Date('2026-06-30'), by="day"), 1000, replace = TRUE),
nit_empresa = sample(c("900111", "800333", "901555", "890777", "900999"), 1000, replace = TRUE),
sector_economico = sample(c("Retail", "Manufactura", "Servicios", "Agro", "Tecnología"), 1000, replace = TRUE),
subtotal = round(runif(1000, 100000, 5000000), 0),
estado_doc = sample(c("Aceptada", "Pendiente", "Rechazada"), 1000, replace = TRUE, prob = c(0.75, 0.15, 0.10))
)
# glimpse() nos da una vista técnica rápida de las columnas y los tipos de datos
glimpse(datos_facturacion)
## Rows: 1,000
## Columns: 6
## $ id_factura <int> 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009,…
## $ fecha_emision <date> 2026-06-08, 2026-06-28, 2026-01-14, 2026-06-19, 2026…
## $ nit_empresa <chr> "890777", "900999", "890777", "900999", "900999", "90…
## $ sector_economico <chr> "Tecnología", "Manufactura", "Servicios", "Retail", "…
## $ subtotal <dbl> 2708594, 3405807, 4300265, 2829351, 562526, 3585078, …
## $ estado_doc <chr> "Aceptada", "Aceptada", "Rechazada", "Aceptada", "Ace…
%>%)El corazón de dplyr es el operador %>%
(se lee como “y luego…”). Nos permite tomar un conjunto de datos y
pasarlo por una tubería de transformaciones lógicas sin crear variables
intermedias.
Los “verbos” principales que usaremos: *
filter(): Selecciona filas basado en
condiciones lógicas. * mutate(): Crea o
modifica columnas (ideal para cálculos financieros). *
select(): Extrae solo las columnas de
interés.
facturas_limpias <- datos_facturacion %>%
# 1. Filtramos solo los documentos que ingresaron exitosamente
filter(estado_doc == "Aceptada") %>%
# 2. Calculamos los impuestos y extraemos el mes de la fecha
mutate(
valor_iva = subtotal * 0.19,
total_factura = subtotal + valor_iva,
mes_emision = month(fecha_emision, label = TRUE, abbr = FALSE)
) %>%
# 3. Limpiamos el dataset seleccionando solo las variables útiles
select(id_factura, mes_emision, sector_economico, subtotal, valor_iva, total_factura) %>%
# 4. Ordenamos por el valor total de mayor a menor
arrange(desc(total_factura))
# Mostramos el resultado
facturas_limpias
## # A tibble: 761 × 6
## id_factura mes_emision sector_economico subtotal valor_iva total_factura
## <int> <ord> <chr> <dbl> <dbl> <dbl>
## 1 1146 March Servicios 4993850 948832. 5942682.
## 2 1551 January Manufactura 4985448 947235. 5932683.
## 3 1276 March Retail 4984727 947098. 5931825.
## 4 1851 May Retail 4962007 942781. 5904788.
## 5 1467 February Tecnología 4958627 942139. 5900766.
## 6 1415 June Manufactura 4948370 940190. 5888560.
## 7 1026 April Retail 4932005 937081. 5869086.
## 8 1598 March Retail 4923936 935548. 5859484.
## 9 1989 June Agro 4912495 933374. 5845869.
## 10 1168 June Manufactura 4906191 932176. 5838367.
## # ℹ 751 more rows
Para construir un Dashboard, necesitamos resumir la transaccionalidad
en indicadores clave. Esto lo logramos con la combinación de
group_by() y summarise().
kpi_sectores <- facturas_limpias %>%
group_by(sector_economico) %>%
summarise(
volumen_operaciones = n(), # Cuenta la cantidad de facturas
ingreso_total = sum(total_factura), # Suma el valor facturado
ticket_promedio = mean(total_factura) # Calcula el valor promedio
) %>%
arrange(desc(ingreso_total))
kpi_sectores
## # A tibble: 5 × 4
## sector_economico volumen_operaciones ingreso_total ticket_promedio
## <chr> <int> <dbl> <dbl>
## 1 Manufactura 167 514359826. 3079999.
## 2 Agro 158 481234167. 3045786.
## 3 Retail 142 436783135. 3075938.
## 4 Servicios 146 435059414. 2979859.
## 5 Tecnología 148 421824982. 2850169.
tendencia_mensual <- facturas_limpias %>%
group_by(mes_emision) %>%
summarise(ingreso_mensual = sum(total_factura))
tendencia_mensual
## # A tibble: 6 × 2
## mes_emision ingreso_mensual
## <ord> <dbl>
## 1 January 362351631.
## 2 February 334795583.
## 3 March 417865380.
## 4 April 387808882.
## 5 May 356808873.
## 6 June 429631175.
ggplot2 funciona mediante un sistema de capas
superpuestas. 1. Datos: Qué tabla vamos a usar. 2.
Estéticas (aes): Qué variables van en X,
Y, y colores. 3. Geometrías (geom_): Qué
forma visual tomarán los datos (barras, líneas, puntos).
ggplot(data = kpi_sectores, aes(x = reorder(sector_economico, ingreso_total), y = ingreso_total)) +
geom_col(fill = "#1f77b4") +
coord_flip() + # Girar el gráfico facilita la lectura de etiquetas categóricas
labs(
title = "Ingresos Consolidados por Sector Económico",
subtitle = "Acumulado H1 - 2026",
x = "Sector",
y = "Ingreso Total (COP)"
) +
theme_minimal()
# Cuando el eje X es una categoría ordinal (como el mes), agregamos group = 1
ggplot(data = tendencia_mensual, aes(x = mes_emision, y = ingreso_mensual, group = 1)) +
geom_line(color = "#d62728", size = 1.2) +
geom_point(color = "#8c564b", size = 3) +
labs(
title = "Evolución de la Facturación Efectiva",
x = "Mes",
y = "Facturación Total (COP)"
) +
theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
En BI, R rara vez es el destino final. Frecuentemente usamos scripts para procesar grandes volúmenes y enviamos los resúmenes a bases de datos o herramientas de visualización corporativa.
# Exportamos la tabla resumen garantizando la codificación UTF-8
write_excel_csv(kpi_sectores, "consolidado_sectores_2026.csv")