El presente estudio tiene como objetivo principal analizar el mercado inmobiliario a partir de una base de datos de oferta de viviendas. A través de la aplicación de técnicas multivariadas, se busca identificar patrones espaciales, tipologías de oferta y factores clave que influyen en el valor comercial de las propiedades.
Para lograr este propósito, la actividad se estructura en tres ejes analíticos principales:
Análisis de Componentes Principales (PCA): Reducción de la dimensionalidad para caracterizar la variabilidad estructural del mercado.
Análisis de Conglomerados (Clustering): Segmentación y aglutinamiento de propiedades según atributos físicos y económicos.
Análisis de Correspondencias (AC): Exploración de relaciones de asociación entre variables cualitativas y categóricas (como zonas, estratos y tipos de oferta).
Carga de Librerías y Datos
En esta sección se preparan las herramientas computacionales y se importa el conjunto de datos vivienda alojado en el paquete oficial paqueteMODELOS.
# Instalación del paquete si no está presente
if (!requireNamespace("paqueteMODELOS", quietly = TRUE)) {
devtools::install_github("centromagis/paqueteMODELOS", force = TRUE)
}
library(paqueteMODELOS)
# Carga e inspección preliminar de los datos
data("vivienda")
# Verificación de estructura del dataset
str(vivienda)## spc_tbl_ [8,322 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:8322] 1147 1169 1350 5992 1212 ...
## $ zona : chr [1:8322] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
## $ piso : chr [1:8322] NA NA NA "02" ...
## $ estrato : num [1:8322] 3 3 3 4 5 5 4 5 5 5 ...
## $ preciom : num [1:8322] 250 320 350 400 260 240 220 310 320 780 ...
## $ areaconst : num [1:8322] 70 120 220 280 90 87 52 137 150 380 ...
## $ parqueaderos: num [1:8322] 1 1 2 3 1 1 2 2 2 2 ...
## $ banios : num [1:8322] 3 2 2 5 2 3 2 3 4 3 ...
## $ habitaciones: num [1:8322] 6 3 4 3 3 3 3 4 6 3 ...
## $ tipo : chr [1:8322] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:8322] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
## $ longitud : num [1:8322] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:8322] 3.43 3.43 3.44 3.44 3.46 ...
## - attr(*, "spec")=List of 3
## ..$ cols :List of 13
## .. ..$ id : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ zona : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ piso : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ estrato : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ preciom : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ areaconst : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ parqueaderos: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitaciones: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ tipo : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ barrio : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ longitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ latitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## ..$ default: list()
## .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
## ..$ delim : chr ";"
## ..- attr(*, "class")= chr "col_spec"
## - attr(*, "problems")=<externalptr>
Exploración Inicial de los Datos Antes de aplicar los métodos multivariados, evaluamos la presencia de registros incompletos (NA) y la distribución general de las variables cuantitativas principales.
## id zona piso estrato
## Min. : 1 Length:8322 Length:8322 Min. :3.000
## 1st Qu.:2080 Class :character Class :character 1st Qu.:4.000
## Median :4160 Mode :character Mode :character Median :5.000
## Mean :4160 Mean :4.634
## 3rd Qu.:6240 3rd Qu.:5.000
## Max. :8319 Max. :6.000
## NA's :3 NA's :3
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 330.0 Median : 123.0 Median : 2.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.835 Mean : 3.111
## 3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000
## NA's :2 NA's :3 NA's :1605 NA's :3
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:8322 Length:8322 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.54
## Median : 3.000 Mode :character Mode :character Median :-76.53
## Mean : 3.605 Mean :-76.53
## 3rd Qu.: 4.000 3rd Qu.:-76.52
## Max. :10.000 Max. :-76.46
## NA's :3 NA's :3
## latitud
## Min. :3.333
## 1st Qu.:3.381
## Median :3.416
## Mean :3.418
## 3rd Qu.:3.452
## Max. :3.498
## NA's :3
# Dimensiones del conjunto de datos
cat("Total de registros:", nrow(vivienda), "\\nTotal de columnas:", ncol(vivienda))## Total de registros: 8322 \nTotal de columnas: 13
El PCA permite resumir el comportamiento de múltiples variables numéricas continuas en un menor número de dimensiones incorrelacionadas, conservando la mayor cantidad de varianza posible.
1.1 Selección y Filtrado de Variables Seleccionamos únicamente variables cuantitativas relevantes para el valor y la dimensión de las viviendas (preciom, areaconst, habitaciones, baños, parqueaderos, estrato).
# Filtrado de variables numéricas y eliminación de casos incompletos
datos_pca <- vivienda %>%
select(preciom, areaconst, habitaciones, banios, parqueaderos, estrato) %>%
na.omit()
cat("Registros analizados en PCA:", nrow(datos_pca))## Registros analizados en PCA: 6717
1.2 Ejecución del PCA Estandarizamos las variables (scale. = TRUE) para evitar que las variables con escalas grandes (como preciom o areaconst) dominen injustificadamente la varianza total.
# Ejecución del PCA estandarizado
res_pca <- prcomp(datos_pca, scale. = TRUE, center = TRUE)
# Resumen de varianza explicada por cada componente
summary(res_pca)## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6
## Standard deviation 1.8665 1.1059 0.70675 0.59961 0.49435 0.43560
## Proportion of Variance 0.5806 0.2039 0.08325 0.05992 0.04073 0.03162
## Cumulative Proportion 0.5806 0.7845 0.86772 0.92765 0.96838 1.00000
PC1 y PC2 capturan casi toda la información: Solo con los primeros dos componentes conservas el 78.45% de los datos originales.
Criterio de corte (Regla de Kaiser): PC1 y PC2 son los únicos con desviación estándar mayor a 1 (1.86 y 1.10), por lo que son los únicos estadísticamente relevantes.
1.3 Visualización e Interpretación de Componentes
# Scree plot / Gráfico de codo
fviz_eig(res_pca,
addlabels = TRUE,
ylim = c(0, 80),
barfill = "#2c3e50",
barcolor = "#2c3e50",
title = "Varianza Explicada por Componente Principal") +
theme_minimal()
Descarte directo: Mayor a PC3 el aporte es residual (menos del 8% cada
uno). PC4, PC5 y PC6 se consideran ruido y deben eliminarse.
# Biplot / Círculo de correlaciones de variables
fviz_pca_var(res_pca,
col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE,
title = "Círculo de Correlaciones - Variables Numéricas") +
theme_minimal()
En este círculo de correlaciones se analiza datos del mercado
inmobiliario usando las dos dimensiones principales que explican el
78.5% de la información total (58.1% Dim1 + 20.4% Dim2).
Dimensión 1 (Eje horizontal - Tamaño y Valor general):
Todas las flechas apuntan hacia la derecha. Esto significa que Dim1 mide el tamaño y nivel de la propiedad. A mayor valor en este eje, la propiedad es más grande, tiene más baños, más parqueaderos y un precio mayor.
Dimensión 2 (Eje vertical - Tipo de inmueble):
Separa las viviendas por su perfil:
Arriba (estrato): Inmuebles de mayor nivel socioeconómico.
Abajo (habitaciones): Inmuebles enfocados en capacidad de espacio familiar (más cuartos).
Relación entre variables (Ángulo de las flechas):
preciom, parqueaderos, banios y areaconst están muy juntas: a mayor área construida, más baños, más parqueaderos y mayor precio.
estrato y habitaciones apuntan en direcciones opuestas (un ángulo casi de 90° o más): indican dos perfiles distintos (ej. un apartamento de lujo pequeño en estrato alto vs. una casa grande con muchos cuartos pero en un perfil diferente).
El objetivo del agrupamiento es identificar segmentos homogéneos de oferta inmobiliaria basados en sus atributos físicos y económicos.
2.1 Preparación y Escalado de Datos
2.2 Determinación del Número Óptimo de Grupos (\(k\))Utilizamos el método del codo (Elbow Method) y el método de la silueta para definir el número de clusters óptimo.
# Evaluación mediante el método de la silueta media
set.seed(123)
fviz_nbclust(datos_cluster_scaled, kmeans, method = "silhouette", k.max = 8) +
labs(title = "Número Óptimo de Clusters - Método de la Silueta") +
theme_minimal()
El Método de la Silueta determina cuántos grupos (clusters) conviene
crear: evalúa qué tan similares son los datos dentro de su propio grupo
versus qué tan separados están de los otros grupos.
Diagnóstico final:
Elección principal: \(k = 2\) (Silueta promedio máxima \(\approx 0.41\)). Representa la estructura natural más coherente y con mayor separación entre grupos.
Elección secundaria (si el negocio exige más grupos): \(k = 4\) (\(\text{Silueta} \approx 0.31\)). Mantiene una meseta estable junto a \(k = 3\), siendo aceptable si necesitas una segmentación más detallada sin caer a los peores niveles de separación.
Configuración a descartar: \(k \ge 5\), donde la métrica cae por debajo de \(0.28\), lo que indica alta solapación entre los clusters.Veredicto directo: Configura tu algoritmo K-Means con n_clusters = 2 (o centers = 2 en R) para obtener la máxima calidad estadística.
2.3 Clustering con K-Means
# Selección de k = 2 grupos para la segmentación del mercado
set.seed(123)
res_km <- kmeans(datos_cluster_scaled, centers = 2, nstart = 25)
# Asignación del cluster a la base de datos
datos_pca$cluster <- as.factor(res_km$cluster)# Mapa de clusters sobre los dos primeros ejes del PCA
fviz_cluster(res_km,
data = datos_cluster_scaled,
ellipse.type = "convex",
palette = "jco",
ggtheme = theme_minimal(),
main = "Segmentación de Viviendas mediante K-Means (k = 2)")
Este gráfico proyecta la segmentación del algoritmo K-Means sobre las
dos dimensiones principales del PCA (que juntas representan el 78.5% de
la varianza total).
División clara en el eje principal (Dim1): La separación entre grupos ocurre casi en su totalidad sobre el eje horizontal Dim1 (58.1%).
Cluster 2 (Amarillo - Izquierda): Agrupa viviendas con valores bajos/negativos en Dim1. Representa el segmento de inmuebles más pequeños, de menor precio, con menos baños y parqueaderos.
Cluster 1 (Azul - Derecha): Agrupa viviendas con valores positivos en Dim1. Representa el segmento de propiedades de mayor tamaño, mayor área construida y precios altos.
Dispersión y variabilidad (Dim2):
El Cluster 2 (Amarillo) está mucho más concentrado y compacto.
El Cluster 1 (Azul) está ampliamente disperso sobre el eje vertical Dim2 (20.4%), lo que indica una alta variabilidad interna dentro del grupo de propiedades de mayor valor (mezclando distintos estratos y cantidades de habitaciones).
2.4 Caracterización de los Segmentos de Mercado
# Resumen descriptivo por cluster
perfiles_clusters <- datos_pca %>%
group_by(cluster) %>%
summarise(
Cantidad = n(),
Precio_Promedio = mean(preciom),
Area_Promedio = mean(areaconst),
Habitaciones_Prom = mean(habitaciones),
Baños_Prom = mean(banios),
Parqueaderos_Prom = mean(parqueaderos),
Estrato_Prom = mean(estrato)
)
kable(perfiles_clusters, digits = 2, caption = "Perfil Promedio por Conglomerado de Vivienda")| cluster | Cantidad | Precio_Promedio | Area_Promedio | Habitaciones_Prom | Baños_Prom | Parqueaderos_Prom | Estrato_Prom |
|---|---|---|---|---|---|---|---|
| 1 | 2006 | 845.72 | 328.35 | 4.61 | 4.82 | 2.89 | 5.45 |
| 2 | 4711 | 308.42 | 118.45 | 3.18 | 2.59 | 1.38 | 4.57 |
Análisis del Perfil Promedio por Conglomerado
El análisis de medias confirma la segmentación en dos perfiles de mercado claramente diferenciados:
Cluster 1 — Inmuebles de Alta Gama / Amplios (\(n = 2,006\)): Representa el 29.8% de la muestra. Agrupa propiedades de mayor valor comercial (\(\text{precio promedio} = 845.72\)), con un área significativamente más grande (\(328.35\text{ m}^2\)) y mayor infraestructura (promedios de \(4.61\) habitaciones, \(4.82\) baños y \(2.89\) parqueaderos). Se ubican predominantemente en estrato alto (promedio de \(5.45\)).
Cluster 2 — Inmuebles Estándar / Compactos (\(n = 4,711\)): Representa la mayoría del mercado (70.2%). Agrupa propiedades más accesibles (\(\text{precio promedio} = 308.42\)) y de menor escala (\(118.45\text{ m}^2\)), diseñadas para formatos familiares estándar (\(3.18\) habitaciones, \(2.59\) baños y \(1.38\) parqueaderos), situadas en estrato medio-alto (promedio de \(4.57\)).
Conclusión: El precio promedio del Cluster 1 casi triplica al del Cluster 2, impulsado principalmente por disponer del triple de área construida y el doble de capacidad de parqueaderos y baños.
El Análisis de Correspondencias explora la relación asociativa entre variables categóricas cualitativas del mercado.
3.1 Construcción de Tabla de Contingencia Analizamos la relación entre la Zona geográfica y el Estrato socioeconómico de la oferta.
# Selección y limpieza de variables categóricas
datos_ac <- vivienda %>%
select(zona, estrato) %>%
filter(!is.na(zona), !is.na(estrato)) %>%
mutate(
zona = as.factor(zona),
estrato = as.factor(paste("Estrato", estrato))
)
# Tabla de cruzada / contingencia
tabla_contingencia <- table(datos_ac$zona, datos_ac$estrato)
tabla_contingencia##
## Estrato 3 Estrato 4 Estrato 5 Estrato 6
## Zona Centro 105 14 4 1
## Zona Norte 572 407 769 172
## Zona Oeste 54 84 290 770
## Zona Oriente 340 8 2 1
## Zona Sur 382 1616 1685 1043
Análisis de la Tabla de Contingencia (Zona vs. Estrato)
La distribución cruzada revela una alta asociación geográfica según el nivel socioeconómico de la oferta inmobiliaria:
Zona Oeste — Polo exclusivo / Estrato 6: Concentra la mayor oferta de Estrato 6 de toda la ciudad (770 viviendas), representando más del \(64\%\) de su oferta local.
Zona Sur — Dominio absoluto del mercado: Es la zona con mayor volumen de propiedades (\(4,726\) inmuebles). Distribuye su oferta de forma masiva entre los estratos medios y altos (Estrato 4: \(1,616\), Estrato 5: \(1,685\) y Estrato 6: \(1,043\)).
Zona Norte — Diversificada de clase media a alta: Presenta un volumen considerable con foco principal en Estrato 5 (\(769\)) y Estrato 3 (\(572\)).
Zonas Centro y Oriente — Perfil popular / Estrato 3: Ambas zonas muestran una oferta casi exclusiva de Estrato 3 (\(105\) en el Centro y \(340\) en el Oriente), con presencia casi nula en estratos 5 y 6.
Existe una clara polarización geográfica: los estratos 5 y 6 se concentran fuertemente en las zonas Oeste, Sur y Norte, mientras que el Centro y Oriente atienden casi exclusivamente el segmento de Estrato 3.
3.2 Ejecución del Análisis de Correspondencias Simple (CA)
# Ejecución del Análisis de Correspondencias
res_ca <- CA(tabla_contingencia, graph = FALSE)
# Resumen de los resultados del AC
summary(res_ca)##
## Call:
## CA(X = tabla_contingencia, graph = FALSE)
##
## The chi square of independence between the two variables is equal to 3830.435 (p-value = 0 ).
##
## Eigenvalues
## Dim.1 Dim.2 Dim.3
## Variance 0.322 0.127 0.011
## % of var. 69.966 27.680 2.354
## Cumulative % of var. 69.966 97.646 100.000
##
## Rows
## Iner*1000 Dim.1 ctr cos2 Dim.2 ctr cos2
## Zona Centro | 47.079 | 1.725 13.761 0.942 | 0.364 1.547 0.042 |
## Zona Norte | 46.762 | 0.390 10.887 0.750 | -0.147 3.920 0.107 |
## Zona Oeste | 135.034 | -0.569 14.476 0.345 | 0.783 69.204 0.653 |
## Zona Oriente | 184.564 | 2.015 53.171 0.928 | 0.537 9.563 0.066 |
## Zona Sur | 47.004 | -0.209 7.704 0.528 | -0.188 15.767 0.428 |
## Dim.3 ctr cos2
## Zona Centro 0.228 7.148 0.016 |
## Zona Norte -0.170 61.735 0.143 |
## Zona Oeste -0.037 1.820 0.001 |
## Zona Oriente 0.160 10.006 0.006 |
## Zona Sur 0.061 19.291 0.044 |
##
## Columns
## Iner*1000 Dim.1 ctr cos2 Dim.2 ctr cos2
## Estrato 3 | 253.402 | 1.187 76.333 0.970 | 0.207 5.851 0.029 |
## Estrato 4 | 47.744 | -0.154 1.895 0.128 | -0.380 28.966 0.773 |
## Estrato 5 | 25.471 | -0.132 1.796 0.227 | -0.204 10.824 0.542 |
## Estrato 6 | 133.827 | -0.519 19.976 0.481 | 0.539 54.359 0.518 |
## Dim.3 ctr cos2
## Estrato 3 0.015 0.350 0.000 |
## Estrato 4 0.136 43.547 0.099 |
## Estrato 5 -0.133 54.323 0.231 |
## Estrato 6 0.028 1.780 0.001 |
Análisis del Análisis de Correspondencias (CA)
Dependencia estadística: El test de Chi-cuadrado (\(\text{p-value} = 0\)) confirma que la ubicación geográfica (Zona) y el Estrato están fuertemente asociados y no son independientes.
Calidad de representación: Con solo 2 dimensiones se explica el 97.65% de la variabilidad total (Dim1: \(69.97\%\) + Dim2: \(27.68\%\)).
Asociaciones principales por Dimensión: Dimensión 1 (Estrato 3 vs. Resto): Separa drásticamente el Estrato 3 (\(\text{ctr} = 76.3\%\)), el cual se asocia fuertemente con la Zona Oriente (\(\text{ctr} = 53.2\%\)) y Zona Centro (\(\text{ctr} = 13.8\%\)). Dimensión 2 (Estrato Exclusivo vs. Medio): Separa el Estrato 6 (\(\text{ctr} = 54.4\%\)), altamente asociado a la Zona Oeste (\(\text{ctr} = 69.2\%\)), frente a los estratos medios (4 y 5) más ligados a las zonas Sur y Norte.
Oriente y Centro \(\rightarrow\) Asociados casi exclusivamente al Estrato Oeste \(\rightarrow\) Asociado fuertemente al Estrato. Sur y Norte \(\rightarrow\) Concentran los Estratos 4 y 5.
3.3 Mapas Perceptuales y Visualización de Asociaciones
# Visualización simétrica del mapa de correspondencias
fviz_ca_biplot(res_ca,
repel = TRUE,
col.row = "#1f78b4",
col.col = "#e31a1c",
title = "Mapa de Correspondencias: Zona vs. Estrato Socioeconómico") +
theme_minimal()Hallazgos del Análisis de Correspondencias: Proximidad Espacial: Existe una clara asociación geográfica entre determinadas zonas y niveles de estrato.
Las Zonas Oeste y Norte muestran una fuerte atracción y correspondencia con estratos altos (5 y 6).
Las Zonas Oriente y Sur/Poblados tienden a agruparse en torno a ofertas de estrato medio-bajo (2 y 3).
1. Reducción de Dimensionalidad (PCA)
Dominio de la escala sobre el valor: El \(78.5\%\) de la variabilidad del mercado se sintetiza en solo dos componentes. El eje principal (Dim1) está dominado por la magnitud del inmueble (área construida, baños y parqueaderos), los cuales dictan directamente el precio.
Perfil diferenciador: La segunda dimensión (Dim2) separa las propiedades por su enfoque, diferenciando entre inmuebles de estrato alto/lujo frente a viviendas familiares con mayor número de habitaciones.
2. Segmentación de Mercado (Clustering K-Means)
Estructura óptima en dos clusters: El análisis de silueta (\(k=2\), con un valor promedio de \(0.41\)) confirmó que el mercado se divide de forma natural en dos grandes categorías bien definidas:
Cluster 1 — Alta Gama / Grandes Superficies (\(29.8\%\)): Propiedades de mayor valor comercial (\(\text{precio promedio} = 845.72\), área promedio de \(328.35\text{ m}^2\)) ubicadas en estrato promedio de \(5.45\).
Cluster 2 — Estándar / Accesibles (\(70.2\%\)): Formato mayoritario del mercado, enfocado en viviendas compactas (\(\text{precio promedio} = 308.42\), área promedio de \(118.45\text{ m}^2\)) situadas en estrato promedio de \(4.57\).
3. Patron de Distribución Geográfica (Análisis de Correspondencias)
Segregación territorial marcada: El análisis (\(97.65\%\) de varianza explicada) demuestra una fuerte dependencia entre la ubicación y el estrato socioeconómico (\(\text{p-value} = 0\)).
Zonificación socioeconómica:
Zona Oeste: Sector de oferta exclusiva, concentrando el Estrato 6.
Zonas Sur y Norte: Núcleo de la clase media-alta, concentrando la oferta de Estratos 4 y 5.
Zonas Oriente y Centro: Sectores populares y accesibles, con oferta casi concentrada en Estrato 3.
Información de la Sesión de R
## R version 4.5.2 (2025-10-31 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 10 x64 (build 19045)
##
## Matrix products: default
## LAPACK version 3.12.1
##
## locale:
## [1] LC_COLLATE=Spanish_Colombia.utf8 LC_CTYPE=Spanish_Colombia.utf8
## [3] LC_MONETARY=Spanish_Colombia.utf8 LC_NUMERIC=C
## [5] LC_TIME=Spanish_Colombia.utf8
##
## time zone: America/Bogota
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] paqueteMODELOS_0.1.0 summarytools_1.1.5 gridExtra_2.3
## [4] GGally_2.4.0 broom_1.0.13 boot_1.3-32
## [7] knitr_1.51 cluster_2.1.8.3 FactoMineR_2.16
## [10] factoextra_2.2.0 ggplot2_4.0.2 tidyr_1.3.2
## [13] dplyr_1.2.0
##
## loaded via a namespace (and not attached):
## [1] tidyselect_1.2.1 farver_2.1.2 S7_0.2.1
## [4] fastmap_1.2.0 digest_0.6.39 estimability_2.0.0
## [7] timechange_0.4.0 lifecycle_1.0.5 multcompView_0.1-12
## [10] magrittr_2.0.4 compiler_4.5.2 rlang_1.1.7
## [13] sass_0.4.10 tools_4.5.2 yaml_2.3.12
## [16] ggsignif_0.6.4 labeling_0.4.3 htmlwidgets_1.6.4
## [19] scatterplot3d_0.3-45 plyr_1.8.9 xml2_1.5.2
## [22] showtextdb_3.0 RColorBrewer_1.1-3 abind_1.4-8
## [25] withr_3.0.2 purrr_1.2.1 grid_4.5.2
## [28] ggpubr_1.0.0 sysfonts_0.8.9 xtable_1.8-4
## [31] emmeans_2.0.4 scales_1.4.0 MASS_7.3-65
## [34] flashClust_1.1-4 cli_3.6.5 mvtnorm_1.4-2
## [37] rmarkdown_2.30 generics_0.1.4 otel_0.2.0
## [40] rstudioapi_0.18.0 reshape2_1.4.5 cachem_1.1.0
## [43] pander_0.6.6 stringr_1.6.0 matrixStats_1.5.0
## [46] base64enc_0.1-6 vctrs_0.7.1 Matrix_1.7-4
## [49] carData_3.0-6 jsonlite_2.0.0 car_3.1-5
## [52] rapportools_1.2 rstatix_1.1.0 ggrepel_0.9.8
## [55] Formula_1.2-6 irlba_2.3.7 magick_2.9.0
## [58] jquerylib_0.1.4 glue_1.8.0 ggstats_0.13.0
## [61] ggtext_0.1.2 DT_0.34.0 lubridate_1.9.5
## [64] stringi_1.8.7 gtable_0.3.6 tibble_3.3.1
## [67] pillar_1.11.1 htmltools_0.5.9 showtext_0.9-8
## [70] R6_2.6.1 tcltk_4.5.2 evaluate_1.0.5
## [73] lattice_0.22-7 backports_1.5.0 leaps_3.2
## [76] gridtext_0.1.6 ggsci_5.2.0 bslib_0.10.0
## [79] Rcpp_1.1.2 checkmate_2.3.4 xfun_0.56
## [82] pkgconfig_2.0.3