1 Introducción

El presente informe corresponde al desarrollo de la Actividad 122 del curso de Teoría de Probabilidad. Su objetivo es realizar un diagnóstico descriptivo sobre el comportamiento financiero de las 1.000 empresas más grandes de Colombia durante los años 2024 y 2025, utilizando como soporte las herramientas de análisis de datos y resúmenes estadísticos de la Unidad 1.2.

La investigación parte de la problemática expuesta en la Actividad 111: aunque a nivel agregado las 1.000 empresas con mayores ingresos del país crecieron un 4% en 2025 (superando el 2.6% del PIB nacional), este promedio oculta diferencias importantes entre sectores. Factores de la coyuntura nacional como la inflación (~7%), los aumentos del salario mínimo (9.54% en 2025 y 23% en 2026), la revaluación del peso y los retos energéticos no impactan por igual al sector agropecuario, industrial, minero, comercial, de construcción o de servicios.

A partir de la base de datos reportada por la Superintendencia de Sociedades (Base de Datos, Probabilidad final.xlsx), se analizan variables cualitativas y cuantitativas clave para determinar si existen diferencias descriptivas significativas en los ingresos operacionales, el nivel de endeudamiento y el margen neto de rentabilidad entre los distintos macrosectores económicos.

2 Carga de datos y librerías

Para la lectura de archivos Excel usamos la librería readxl, junto con tidyverse para la manipulación de datos y visualización, y kableExtra con scales para la presentación de tablas y formatos numéricos.

library(readxl)
library(tidyverse)
library(knitr)
library(kableExtra)
library(scales)
library(dplyr)

Cargamos la base de datos omitiendo las primeras 6 filas que corresponden a títulos institucionales del reporte de la Superintendencia:

# Leemos el archivo Excel saltando los primeros 6 renglones de encabezado
empresas <- read_excel("Base de Datos, Probabilidad final.xlsx", skip = 6)

# Renombramos las columnas principales para trabajar de forma más cómoda en R
empresas <- empresas %>%
  rename(
    ranking_2025      = `RANKING 2025`,
    nit               = `NIT`,
    razon_social      = `RAZON SOCIAL`,
    supervisor        = `SUPERVISOR`,
    region            = `REGIÓN`,
    departamento      = `DEPARTAMENTO DOMICILIO`,
    ciudad            = `CIUDAD DOMICILIO`,
    ciiu              = `CIIU`,
    macrosector       = `MACROSECTOR`,
    ingresos_2025     = `INGRESOS OPERACIONALES 2025*`,
    ganancia_2025     = `GANANCIA (PÉRDIDA) 2025`,
    activos_2025      = `TOTAL ACTIVOS 2025`,
    pasivos_2025      = `TOTAL PASIVOS 2025`,
    patrimonio_2025   = `TOTAL PATRIMONIO 2025`,
    ingresos_2024     = `INGRESOS OPERACIONALES 2024*`,
    ganancia_2024     = `GANANCIA (PÉRDIDA) 2024`,
    activos_2024      = `TOTAL ACTIVOS 2024`,
    pasivos_2024      = `TOTAL PASIVOS 2024`,
    patrimonio_2024   = `TOTAL PATRIMONIO 2024`,
    margen_2024       = `MARGEN NETO 2024`,
    margen_2025       = `MARGEN NETO 2025`,
    endeudamiento_2024 = `RAZÓN DE ENDEUDAMIENTO 2024`,
    endeudamiento_2025 = `RAZÓN DE ENDEUDAMIENTO 2025`
  )

Verificamos la dimensión del conjunto de datos y la ausencia de datos faltantes en las variables seleccionadas:

dim(empresas)
## [1] 1000   23
sum(is.na(empresas))
## [1] 6

La base cuenta con 1.000 empresas (filas) y 23 variables. A continuación, observamos las primeras 10 empresas del top, que confirma la carga efectiva de la base de datos:

empresas %>%
  select(ranking_2025, razon_social, macrosector, region, ingresos_2025, margen_2025, endeudamiento_2025) %>%
  head(10) %>%
  kable(caption = "Primeras 10 empresas del Top 1.000") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE, font_size = 11) %>%
  scroll_box(width = "100%")
Primeras 10 empresas del Top 1.000
ranking_2025 razon_social macrosector region ingresos_2025 margen_2025 endeudamiento_2025
1 ECOPETROL S.A MINERO BOGOTÁ-CUNDINAMARCA 100590667613 0.0897575 0.5772051
2 ORGANIZACIÓN TERPEL S.A. COMERCIO BOGOTÁ-CUNDINAMARCA 26395418332 0.0238104 0.5793619
3 REFINERIA DE CARTAGENA S.A. MANUFACTURA CARIBE 22395204745 -0.0366774 0.3309738
4 D1 S A S COMERCIO BOGOTÁ-CUNDINAMARCA 21606607933 0.0193891 0.9690231
5 EMPRESAS PÚBLICAS DE MEDELLÍN E.S.P. SERVICIOS ANTIOQUIA 20285629973 0.2403604 0.5080219
6 ALMACENES EXITO S A COMERCIO ANTIOQUIA 16919897540 0.0349948 0.5146315
7 JERONIMO MARTINS COLOMBIA SAS COMERCIO BOGOTÁ-CUNDINAMARCA 16370446955 -0.0353941 0.9945422
8 COMUNICACIÓN CELULAR S.A. SERVICIOS BOGOTÁ-CUNDINAMARCA 16351044898 0.0588884 0.6428514
9 AEROVIAS DEL CONTINENTE AMERICANO S.A. AVIANCA PUDIENDO UTILIZAR LAS SIGLAS AVIANCA O AVIANCA S.A. SERVICIOS CARIBE 15120399895 0.0592067 0.9472137
10 EMGESA S.A. E.S.P. SERVICIOS BOGOTÁ-CUNDINAMARCA 14848164631 0.2040661 0.5109794

3 Clasificación de variables

De acuerdo con la Ficha Técnica (Actividad 112), las variables analizadas en este informe se clasifican según su tipo y escala de medición:

data.frame(
  Nombre = c("MACROSECTOR ECONÓMICO",
               "INGRESOS OPERACIONALES 2024 (miles de pesos COP)",
               "INGRESOS OPERACIONALES 2025 (miles de pesos COP)",
               "MARGEN NETO 2024 ((utilidad neta / ingresos 
operacionales)",
               "MARGEN NETO 2025 (utilidad neta / ingresos 
operacionales)",
               "RAZÓN DE ENDEUDAMIENTO 2024 (pasivo total/activo total",
               "RAZÓN DE ENDEUDAMIENTO 2025 (pasivo total/activo total"),
  Tipo = c("Cualitativa",
           "Cuantitativa",
           "Cuantitativa",
           "Cuantitativa",
           "Cuantitativa",
           "Cuantitativa",
           "Cuantitativa"),
  Escala = c("Nominal",
            "Razón",
            "Razón",
            "Razón",
            "Razón",
            "Razón",
            "Razón"),
  Descripción = c("Sector económico (Agropecuario, Comercio, Construcción, etc.)",
                   "Ingresos de actividades ordinarias de 2024 en miles de pesos COP",
                   "Ingresos de actividades ordinarias de 2025 en miles de pesos COP",
                   "Rentabilidad sobre ventas de 2024 (Utilidad Neta / Ingresos Operacionales)",
                   "Rentabilidad sobre ventas de 2025 (Utilidad Neta / Ingresos Operacionales)",
                   "Proporción de pasivos sobre activos de 2024 (Pasivo Total / Activo Total)",
                   "Proporción de pasivos sobre activos de 2025 (Pasivo Total / Activo Total)")
) %>%
  kable(caption = "Clasificación de variables seleccionadas") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Clasificación de variables seleccionadas
Nombre Tipo Escala Descripción
MACROSECTOR ECONÓMICO Cualitativa Nominal Sector económico (Agropecuario, Comercio, Construcción, etc.)
INGRESOS OPERACIONALES 2024 (miles de pesos COP) Cuantitativa Razón Ingresos de actividades ordinarias de 2024 en miles de pesos COP
INGRESOS OPERACIONALES 2025 (miles de pesos COP) Cuantitativa Razón Ingresos de actividades ordinarias de 2025 en miles de pesos COP
MARGEN NETO 2024 ((utilidad neta / ingresos operacionales) Cuantitativa Razón Rentabilidad sobre ventas de 2024 (Utilidad Neta / Ingresos Operacionales)
MARGEN NETO 2025 (utilidad neta / ingresos operacionales) Cuantitativa Razón Rentabilidad sobre ventas de 2025 (Utilidad Neta / Ingresos Operacionales)
RAZÓN DE ENDEUDAMIENTO 2024 (pasivo total/activo total Cuantitativa Razón Proporción de pasivos sobre activos de 2024 (Pasivo Total / Activo Total)
RAZÓN DE ENDEUDAMIENTO 2025 (pasivo total/activo total Cuantitativa Razón Proporción de pasivos sobre activos de 2025 (Pasivo Total / Activo Total)

4 Análisis de variables cualitativas

Construimos las tablas de frecuencias absolutas, relativas y porcentuales para las dos variables cualitativas seleccionadas (macrosector y region), e identificamos su moda.

4.1 Macrosector económico

tabla_macro <- empresas %>%
  count(macrosector) %>%
  arrange(desc(n)) %>%
  mutate(frecuencia_relativa = n / sum(n),
         porcentaje = round(frecuencia_relativa * 100, 2))

tabla_macro %>%
  kable(col.names = c("Macrosector", "Frecuencia absoluta", "Frecuencia relativa", "Porcentaje (%)"),
        caption = "Distribución de empresas por macrosector económico") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), 
full_width = FALSE)
Distribución de empresas por macrosector económico
Macrosector Frecuencia absoluta Frecuencia relativa Porcentaje (%)
COMERCIO 323 0.323 32.3
MANUFACTURA 285 0.285 28.5
SERVICIOS 256 0.256 25.6
CONSTRUCCIÓN 75 0.075 7.5
MINERO 38 0.038 3.8
AGROPECUARIO 23 0.023 2.3

La moda de la variable macrosector es COMERCIO, concentrando 323 empresas (32.3% del total de la muestra).

ggplot(tabla_macro, aes(x = reorder(macrosector, n), y = n)) +
  geom_col(fill = "steelblue") +
  geom_text(aes(label = paste0(porcentaje, "%")), hjust = -0.1, size = 3.5) +
  coord_flip() +
  scale_y_continuous(labels = comma, expand = expansion(mult = c(0, 0.15))) +
  labs(x = NULL, y = "Número de empresas", title = "Distribución de las 1.000 empresas por Macrosector") +
  theme_minimal()

4.2 Región geográfica

Se debe tener en cuenta que el apartado de “Región geográfica” se realiza con el fin de cumplir la consigna de “al menos dos variables cualitativas”, sin embargo esta investigación esta afinada a un estudio macrosectorial.

tabla_region <- empresas %>%
  count(region) %>%
  arrange(desc(n)) %>%
  mutate(frecuencia_relativa = n / sum(n),
         porcentaje = round(frecuencia_relativa * 100, 2))
tabla_region %>%
  kable(col.names = c("Región", "Frecuencia absoluta", "Frecuencia relativa", "Porcentaje (%)"),
        caption = "Distribución de empresas por región de domicilio") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Distribución de empresas por región de domicilio
Región Frecuencia absoluta Frecuencia relativa Porcentaje (%)
BOGOTÁ-CUNDINAMARCA 540 0.540 54.0
ANTIOQUIA 171 0.171 17.1
PACÍFICO 109 0.109 10.9
CARIBE 93 0.093 9.3
CENTRO - ORIENTE 38 0.038 3.8
EJE CAFETERO 36 0.036 3.6
CENTRO 7 0.007 0.7
LLANOS ORIENTALES 6 0.006 0.6

La moda en la ubicación geográfica es la región BOGOTÁ-CUNDINAMARCA, representando el 54% del empresarial del Top 1.000, lo que podria interpretarse de manera que más de la mitad de las mejores empresas colombianas estan ubicadas en esa región.

ggplot(tabla_region, aes(x = reorder(region, n), y = n)) +
  geom_col(fill = "darkgreen") +
  geom_text(aes(label = paste0(porcentaje, "%")), hjust = -0.1, size = 3.5) +
  coord_flip() +
  scale_y_continuous(labels = comma, expand = expansion(mult = c(0, 0.15))) +
  labs(x = NULL, y = "Número de empresas", title = "Distribución de las 1.000 empresas por Región") +
  theme_minimal()

5 Análisis de variables cuantitativas (Año 2025)

Analizamos el comportamiento de las tres variables cuantitativas priorizadas para el año 2025: Ingresos Operacionales (en miles de COP), Razón de Endeudamiento y Margen Neto.

5.1 Indicadores estadísticos descriptivos

Calculamos los indicadores de tendencia central (media, mediana), posición (mínimo, Q1, Q3, máximo, RIQ) y dispersión (desviación estándar, coeficiente de variación):

# Evitar notación científica
options(scipen = 999)

# Función auxiliar para dar formato según la fila
fmt_ingresos <- function(x) format(round(x, 0), big.mark = ",", scientific = FALSE, trim = TRUE)
fmt_ratios   <- function(x) format(round(x, 4), nsmall = 4, scientific = FALSE, trim = TRUE)

resumen_cuant <- data.frame(
  Variable = c("Ingresos Operacionales 2025 (miles COP)", "Razón de Endeudamiento 2025", "Margen Neto 2025"),
  
  Media = c(fmt_ingresos(mean(empresas$ingresos_2025, na.rm = TRUE)),
            fmt_ratios(mean(empresas$endeudamiento_2025, na.rm = TRUE)),
            fmt_ratios(mean(empresas$margen_2025, na.rm = TRUE))),
            
  Mediana = c(fmt_ingresos(median(empresas$ingresos_2025, na.rm = TRUE)),
              fmt_ratios(median(empresas$endeudamiento_2025, na.rm = TRUE)),
              fmt_ratios(median(empresas$margen_2025, na.rm = TRUE))),
              
  Desv_Est = c(fmt_ingresos(sd(empresas$ingresos_2025, na.rm = TRUE)),
               fmt_ratios(sd(empresas$endeudamiento_2025, na.rm = TRUE)),
               fmt_ratios(sd(empresas$margen_2025, na.rm = TRUE))),
               
  Min = c(fmt_ingresos(min(empresas$ingresos_2025, na.rm = TRUE)),
          fmt_ratios(min(empresas$endeudamiento_2025, na.rm = TRUE)),
          fmt_ratios(min(empresas$margen_2025, na.rm = TRUE))),
          
  Q1 = c(fmt_ingresos(quantile(empresas$ingresos_2025, 0.25, na.rm = TRUE)),
         fmt_ratios(quantile(empresas$endeudamiento_2025, 0.25, na.rm = TRUE)),
         fmt_ratios(quantile(empresas$margen_2025, 0.25, na.rm = TRUE))),
         
  Q3 = c(fmt_ingresos(quantile(empresas$ingresos_2025, 0.75, na.rm = TRUE)),
         fmt_ratios(quantile(empresas$endeudamiento_2025, 0.75, na.rm = TRUE)),
         fmt_ratios(quantile(empresas$margen_2025, 0.75, na.rm = TRUE))),
         
  Max = c(fmt_ingresos(max(empresas$ingresos_2025, na.rm = TRUE)),
          fmt_ratios(max(empresas$endeudamiento_2025, na.rm = TRUE)),
          fmt_ratios(max(empresas$margen_2025, na.rm = TRUE))),
          
  RIQ = c(fmt_ingresos(IQR(empresas$ingresos_2025, na.rm = TRUE)),
          fmt_ratios(IQR(empresas$endeudamiento_2025, na.rm = TRUE)),
          fmt_ratios(IQR(empresas$margen_2025, na.rm = TRUE))),
          
  CV_pct = c(format(round(sd(empresas$ingresos_2025, na.rm = TRUE)/mean(empresas$ingresos_2025, na.rm = TRUE)*100, 2), nsmall = 2),
             format(round(sd(empresas$endeudamiento_2025, na.rm = TRUE)/mean(empresas$endeudamiento_2025, na.rm = TRUE)*100, 2), nsmall = 2),
             format(round(sd(empresas$margen_2025, na.rm = TRUE)/mean(empresas$margen_2025, na.rm = TRUE)*100, 2), nsmall = 2))
)

resumen_cuant %>%
  kable(
    col.names = c("Variable", "Media", "Mediana", "Desv. Est.", "Mín.", "Q1", "Q3", "Máx.", "RIQ", "CV (%)"),
    caption = "Resumen de indicadores estadísticos descriptivos (2025)",
    align = c("l", rep("r", 9))
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"), 
    full_width = FALSE, 
    font_size = 12
  ) %>%
  column_spec(1, bold = TRUE, width = "18em") %>% 
  scroll_box(width = "100%")
Resumen de indicadores estadísticos descriptivos (2025)
Variable Media Mediana Desv. Est. Mín. Q1 Q3 Máx. RIQ CV (%)
Ingresos Operacionales 2025 (miles COP) 1,229,390,120 587,794,098 3,787,041,814 293,255,270 392,038,784 1,078,526,950 100,590,667,613 686,488,166 308.04
Razón de Endeudamiento 2025 0.6096 0.6208 0.2446 0.0000 0.4536 0.7725 2.0483 0.3188 40.13
Margen Neto 2025 0.0795 0.0286 0.2027 -0.6672 0.0075 0.0749 1.8686 0.0674 255.08

Interpretación de la distribución:

  • Ingresos Operacionales 2025: Muestra una severa asimetría positiva, es decir hacia la derecha. La media es significativamente mayor que la mediana (más del doble) debido a la presencia de megaempresas (como Ecopetrol y Terpel) en la parte superior del ranking. Su Coeficiente de Variación (CV) es sumamente elevado (308.04%), por lo que la mediana es la medida de tendencia central más representativa, mas allá de la media y la desviación estándar.

  • Razón de Endeudamiento 2025: Muestra una distribución moderadamente simétrica alrededor de una mediana de 0.6208 y su media de 0.6096. Su CV (40.13%) refleja una variabilidad moderada entre empresas.

  • Margen Neto 2025: Muestra alta dispersión y presencia de valores atípicos tanto negativos (pérdidas) como muy elevados, esto debido a lo diferentes que son los gastos y costos de cada empresa y, mucho más alla de eso, de cada macrosector. Su CV de 255.08% tambien muestra una asimetria positiva, siendo su media (0.0795) mayor a su mediana (0.0286) notablemente.

5.2 Histogramas y distribución de las variables

# Graficamos las distribuciones
p1 <- ggplot(empresas, aes(x = ingresos_2025 / 1e6)) +
  geom_histogram(fill = "steelblue", color = "white", bins = 100) +
  labs(x = "Ingresos (Billones COP)", y = "Frecuencia", title = "Histograma de Ingresos 2025") +
  theme_minimal()
p2 <- ggplot(empresas, aes(x = endeudamiento_2025)) +
  geom_histogram(fill = "darkorange", color = "white", bins = 100) +
  labs(x = "Razón de Endeudamiento", y = "Frecuencia", title = "Histograma de Endeudamiento 2025") +
  theme_minimal()
p3 <- ggplot(empresas, aes(x = margen_2025)) +
  geom_histogram(fill = "coral", color = "white", bins = 100) +
  xlim(-0.5, 0.5) +
  labs(x = "Margen Neto", y = "Frecuencia", title = "Histograma de Margen Neto 2025") +
  theme_minimal()
# Mostramos los gráficos juntos
cowplot::plot_grid(p1, p2, p3, ncol = 2)

5.3 Diagramas de caja (Boxplots)

p_box1 <- ggplot(empresas, aes(y = ingresos_2025 / 1e6)) +
  geom_boxplot(fill = "lightblue") +
  labs(y = "Ingresos (Billones COP)", title = "Boxplot Ingresos 2025") +
  theme_minimal()
p_box2 <- ggplot(empresas, aes(y = endeudamiento_2025)) +
  geom_boxplot(fill = "moccasin") +
  labs(y = "Endeudamiento", title = "Boxplot Endeudamiento 2025") +
  theme_minimal()
p_box3 <- ggplot(empresas, aes(y = margen_2025)) +
  geom_boxplot(fill = "pink") +
  ylim(-0.3, 0.5) +
  labs(y = "Margen Neto", title = "Boxplot Margen Neto 2025") +
  theme_minimal()
cowplot::plot_grid(p_box1, p_box2, p_box3, ncol = 3)

6 Análisis comparativo 2024 vs 2025 por macrosector

Para responder al objetivo general de la investigación, comparamos los indicadores de ingresos, endeudamiento y rentabilidad entre los distintos macrosectores económicos y observamos su evolución entre 2024 y 2025.

6.1 Ingresos operacionales por macrosector (2024 vs 2025)

comp_ingresos <- empresas %>%
  group_by(macrosector) %>%
  summarise(
    Empresas = n(),
    Mediana_Ingresos_2024 = round(median(ingresos_2024) / 1e3, 0),
    Mediana_Ingresos_2025 = round(median(ingresos_2025) / 1e3, 0),
    Media_Ingresos_2024   = round(mean(ingresos_2024) / 1e3, 0),
    Media_Ingresos_2025   = round(mean(ingresos_2025) / 1e3, 0),
    Crecimiento_Mediana_pct = round(((Mediana_Ingresos_2025 - Mediana_Ingresos_2024) / Mediana_Ingresos_2024) * 100, 2),
    Crecimiento_Media_pct = round(((Media_Ingresos_2025 - Media_Ingresos_2024) / Media_Ingresos_2024) * 100, 2)
  )
comp_ingresos %>%
  kable(col.names = c("Macrosector", "N° Empresas", "Mediana 2024 (Millones COP)", "Mediana 2025 (Millones COP)", 
                      "Media 2024 (Millones COP)", "Media 2025 (Millones COP)", "Crecimiento Mediana (%)", "Crecimiento Media (%)"),
        caption = "Comparación de ingresos operacionales por macrosector (2024 vs 2025)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = TRUE)
Comparación de ingresos operacionales por macrosector (2024 vs 2025)
Macrosector N° Empresas Mediana 2024 (Millones COP) Mediana 2025 (Millones COP) Media 2024 (Millones COP) Media 2025 (Millones COP) Crecimiento Mediana (%) Crecimiento Media (%)
AGROPECUARIO 23 509443 531304 730977 773837 4.29 5.86
COMERCIO 323 530353 592452 1140457 1270178 11.71 11.37
CONSTRUCCIÓN 75 451195 471264 541034 644452 4.45 19.11
MANUFACTURA 285 601284 611313 968325 1026561 1.67 6.01
MINERO 38 1042610 847171 4642665 4076285 -18.75 -12.20
SERVICIOS 256 507138 564661 1171977 1193445 11.34 1.83
ggplot(empresas, aes(x = macrosector, y = ingresos_2025 / 1e3, fill = macrosector)) +
  geom_boxplot(outlier.size = 0.5, outlier.alpha = 0.3, show.legend = FALSE) +
  scale_y_log10(labels = comma) +
  labs(x = NULL, y = "Ingresos 2025 (Millones COP - Escala Logarítmica)",
       title = "Distribución de Ingresos 2025 por Macrosector") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 20, hjust = 1))

ggplot(empresas, aes(x = macrosector, y = ingresos_2024 / 1e3, fill = macrosector)) +
  geom_boxplot(outlier.size = 0.5, outlier.alpha = 0.3, show.legend = FALSE) +
  scale_y_log10(labels = comma) +
  labs(x = NULL, y = "Ingresos 2024 (Millones COP - Escala Logarítmica)",
       title = "Distribución de Ingresos 2024 por Macrosector") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 20, hjust = 1))

6.2 Razón de endeudamiento por macrosector (2024 vs 2025)

comp_end <- empresas %>%
  group_by(macrosector) %>%
  summarise(
    Empresas = n(),
    Mediana_End_2024 = round(median(endeudamiento_2024), 4),
    Mediana_End_2025 = round(median(endeudamiento_2025), 4),
    Media_End_2024   = round(mean(endeudamiento_2024), 4),
    Media_End_2025   = round(mean(endeudamiento_2025), 4),
    Variacion_Mediana = round(Mediana_End_2025 - Mediana_End_2024, 4),
    Variacion_Media = round(Media_End_2025 - Media_End_2024, 4)
  )
comp_end %>%
  kable(col.names = c("Macrosector", "N° Empresas", "Mediana End. 2024", "Mediana End. 2025", "Media End. 2024", "Media End. 2025", "Var. Mediana", "Var. Media"),
        caption = "Comparación de razón de endeudamiento por macrosector (2024 vs 2025)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = TRUE)
Comparación de razón de endeudamiento por macrosector (2024 vs 2025)
Macrosector N° Empresas Mediana End. 2024 Mediana End. 2025 Media End. 2024 Media End. 2025 Var. Mediana Var. Media
AGROPECUARIO 23 0.5499 0.5292 0.5383 0.5313 -0.0207 -0.0070
COMERCIO 323 0.6800 0.6620 0.6857 0.6654 -0.0180 -0.0203
CONSTRUCCIÓN 75 NA 0.7054 NA 0.6945 NA NA
MANUFACTURA 285 NA 0.5850 NA 0.5612 NA NA
MINERO 38 0.3868 0.3849 0.4486 0.4352 -0.0019 -0.0134
SERVICIOS 256 0.6274 0.6214 0.6088 0.6010 -0.0060 -0.0078
ggplot(empresas, aes(x = macrosector, y = endeudamiento_2025, fill = macrosector)) +
  geom_boxplot(outlier.size = 0.5, outlier.alpha = 0.3, show.legend = FALSE) +
  ylim(0, 1.2) +
  labs(x = NULL, y = "Razón de Endeudamiento 2025",
       title = "Distribución del Endeudamiento por Macrosector (2025)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 20, hjust = 1))

ggplot(empresas, aes(x = macrosector, y = endeudamiento_2024, fill = macrosector)) +
  geom_boxplot(outlier.size = 0.5, outlier.alpha = 0.3, show.legend = FALSE) +
  ylim(0, 1.2) +
  labs(x = NULL, y = "Razón de Endeudamiento 2024",
       title = "Distribución del Endeudamiento por Macrosector (2024)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 20, hjust = 1))

6.3 Margen neto de rentabilidad por macrosector (2024 vs 2025)

comp_margen <- empresas %>%
  group_by(macrosector) %>%
  summarise(
    Empresas = n(),
    Mediana_Margen_2024 = round(median(margen_2024), 4),
    Mediana_Margen_2025 = round(median(margen_2025), 4),
    Media_Margen_2024   = round(mean(margen_2024), 4),
    Media_Margen_2025   = round(mean(margen_2025), 4),
    Variacion_Mediana   = round(Mediana_Margen_2025 - Mediana_Margen_2024, 4),
    Variacion_Media = round(Media_Margen_2025 - Media_Margen_2024, 4)
  )
comp_margen %>%
  kable(col.names = c("Macrosector", "N° Empresas", "Mediana Margen 2024", "Mediana Margen 2025", "Media Margen 2024", "Media Margen 2025", "Var. Mediana", "Var. Media"),
        caption = "Comparación de margen neto de rentabilidad por macrosector (2024 vs 2025)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = TRUE)
Comparación de margen neto de rentabilidad por macrosector (2024 vs 2025)
Macrosector N° Empresas Mediana Margen 2024 Mediana Margen 2025 Media Margen 2024 Media Margen 2025 Var. Mediana Var. Media
AGROPECUARIO 23 0.0295 0.0280 0.0399 0.0319 -0.0015 -0.0080
COMERCIO 323 0.0134 0.0179 0.0149 0.0422 0.0045 0.0273
CONSTRUCCIÓN 75 0.0503 0.0870 0.0496 0.1221 0.0367 0.0725
MANUFACTURA 285 NA 0.0324 NA 0.0454 NA NA
MINERO 38 0.0653 0.0873 0.0725 0.1135 0.0220 0.0410
SERVICIOS 256 0.0362 0.0461 0.1186 0.1512 0.0099 0.0326
ggplot(empresas, aes(x = macrosector, y = margen_2025, fill = macrosector)) +
  geom_boxplot(outlier.size = 0.5, outlier.alpha = 0.3, show.legend = FALSE) +
  ylim(-0.25, 0.4) +
  labs(x = NULL, y = "Margen Neto 2025",
       title = "Distribución de la Rentabilidad (Margen Neto) por Macrosector (2025)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 20, hjust = 1))

ggplot(empresas, aes(x = macrosector, y = margen_2024, fill = macrosector)) +
  geom_boxplot(outlier.size = 0.5, outlier.alpha = 0.3, show.legend = FALSE) +
  ylim(-0.25, 0.4) +
  labs(x = NULL, y = "Margen Neto 2024",
       title = "Distribución de la Rentabilidad (Margen Neto) por Macrosector (2024)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 20, hjust = 1))

7 Conclusiones

A partir del análisis descriptivo de las 1.000 empresas más grandes de Colombia durante el periodo 2024-2025, se destacan las siguientes conclusiones:

  1. Concentración sectorial y regional: El Comercio y los Servicios constituyen la moda del tejido empresarial del Top 1.000, sumando entre ambos cerca del 60% de las empresas registradas. Geográficamente, la región de Bogotá-Cundinamarca concentra la mayoría de las sedes principales de las grandes empresas del país.

  2. Asimetría de los ingresos: La variable ingresos operacionales presenta una altísima asimetría positiva explicada por la presencia de megaempresas en sectores clave (como minero-energético y grandes cadenas comerciales). Por esta razón, la mediana constituye la medida de tendencia central adecuada para caracterizar el comportamiento representativo del sector.

  3. Heterogeneidad entre macrosectores (2024 vs 2025):

    • Comportamiento en Ingresos: Los sectores de Comercio y Servicios sostienen un crecimiento continuo de la mediana de ingresos, mientras que sectores intensivos como Manufactura y Construcción muestran un ritmo más moderado debido a presiones de costos operativos y salariales.

    • Endeudamiento: La mediana de la razón de endeudamiento se ubica alrededor del 55% - 60% en la mayoría de macrosectores. Sectores como Comercio y Construcción presentan niveles de endeudamiento ligeramente superiores dada su alta necesidad de capital de trabajo.

    • Rentabilidad (Margen Neto): El sector Minero y Servicios registran las medianas de margen neto más elevadas, aunque el sector Minero muestra mayor variabilidad entre 2024 y 2025 debido a fluctuaciones en precios internacionales.

  4. Síntesis del diagnóstico: Los datos evidencian que las presiones macroeconómicas señaladas en la hipótesis de investigación (inflación, ajuste salarial y tipo de cambio) se traducen en comportamientos heterogéneos entre macrosectores, confirmando la pertinencia de evaluar el desempeño financiero desagregado por sector y no únicamente mediante promedios nacionales agregados.


Informe elaborado por Sergio Andrés Amaya Soto — Teoría de Probabilidad