Cápitulo 4 Clustering por participiones

Clustering por K-medias

Se cargan las librerías

#install.packages("ggplot2")
#install.packages("factoextra")
library(ggplot2)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa

También es pertinente cargar los datos que se utilizarán para el estudio. A continuación, se presentan las primeras tes filas del data.frame.

# Cargando el data set
data("USArrests")
# Normalizando la data
df <- scale(USArrests)
# Visualizando las primeras 3 filas
head(df, n = 3)
##             Murder   Assault   UrbanPop         Rape
## Alabama 1.24256408 0.7828393 -0.5209066 -0.003416473
## Alaska  0.50786248 1.1068225 -1.2117642  2.484202941
## Arizona 0.07163341 1.4788032  0.9989801  1.042878388

Primero que todo, se estima el númreo óptimo de clusters.

fviz_nbclust(df, kmeans, method = "wss") +
geom_vline(xintercept = 4, linetype = 2)

Después de haber hecho esto se calcula las K-medias con K=4

set.seed(123)
km.res <- kmeans(df, 4, nstart = 25)
print(km.res)
## K-means clustering with 4 clusters of sizes 8, 13, 16, 13
## 
## Cluster means:
##       Murder    Assault   UrbanPop        Rape
## 1  1.4118898  0.8743346 -0.8145211  0.01927104
## 2 -0.9615407 -1.1066010 -0.9301069 -0.96676331
## 3 -0.4894375 -0.3826001  0.5758298 -0.26165379
## 4  0.6950701  1.0394414  0.7226370  1.27693964
## 
## Clustering vector:
##        Alabama         Alaska        Arizona       Arkansas     California 
##              1              4              4              1              4 
##       Colorado    Connecticut       Delaware        Florida        Georgia 
##              4              3              3              4              1 
##         Hawaii          Idaho       Illinois        Indiana           Iowa 
##              3              2              4              3              2 
##         Kansas       Kentucky      Louisiana          Maine       Maryland 
##              3              2              1              2              4 
##  Massachusetts       Michigan      Minnesota    Mississippi       Missouri 
##              3              4              2              1              4 
##        Montana       Nebraska         Nevada  New Hampshire     New Jersey 
##              2              2              4              2              3 
##     New Mexico       New York North Carolina   North Dakota           Ohio 
##              4              4              1              2              3 
##       Oklahoma         Oregon   Pennsylvania   Rhode Island South Carolina 
##              3              3              3              3              1 
##   South Dakota      Tennessee          Texas           Utah        Vermont 
##              2              1              4              3              2 
##       Virginia     Washington  West Virginia      Wisconsin        Wyoming 
##              3              3              2              2              3 
## 
## Within cluster sum of squares by cluster:
## [1]  8.316061 11.952463 16.212213 19.922437
##  (between_SS / total_SS =  71.2 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Sin embargo, también es posible calcular la media de cada variable por clustering usando los datos originales.

aggregate(USArrests, by=list(cluster=km.res$cluster), mean)
##   cluster   Murder   Assault UrbanPop     Rape
## 1       1 13.93750 243.62500 53.75000 21.41250
## 2       2  3.60000  78.53846 52.07692 12.17692
## 3       3  5.65625 138.87500 73.87500 18.78125
## 4       4 10.81538 257.38462 76.00000 33.19231

Además, si se desea agregar el punto de clasificaciones a los datos originales se plantea que es posible utilizar la siguiente lógica en el código.

dd <- cbind(USArrests, cluster = km.res$cluster)
head(dd)
##            Murder Assault UrbanPop Rape cluster
## Alabama      13.2     236       58 21.2       1
## Alaska       10.0     263       48 44.5       4
## Arizona       8.1     294       80 31.0       4
## Arkansas      8.8     190       50 19.5       1
## California    9.0     276       91 40.6       4
## Colorado      7.9     204       78 38.7       4

También, se emplea la función kmenas() para entender el número de Clusters para cada observación.

km.res$cluster
##        Alabama         Alaska        Arizona       Arkansas     California 
##              1              4              4              1              4 
##       Colorado    Connecticut       Delaware        Florida        Georgia 
##              4              3              3              4              1 
##         Hawaii          Idaho       Illinois        Indiana           Iowa 
##              3              2              4              3              2 
##         Kansas       Kentucky      Louisiana          Maine       Maryland 
##              3              2              1              2              4 
##  Massachusetts       Michigan      Minnesota    Mississippi       Missouri 
##              3              4              2              1              4 
##        Montana       Nebraska         Nevada  New Hampshire     New Jersey 
##              2              2              4              2              3 
##     New Mexico       New York North Carolina   North Dakota           Ohio 
##              4              4              1              2              3 
##       Oklahoma         Oregon   Pennsylvania   Rhode Island South Carolina 
##              3              3              3              3              1 
##   South Dakota      Tennessee          Texas           Utah        Vermont 
##              2              1              4              3              2 
##       Virginia     Washington  West Virginia      Wisconsin        Wyoming 
##              3              3              2              2              3
head(km.res$cluster, 4)
##  Alabama   Alaska  Arizona Arkansas 
##        1        4        4        1

Es posible conocer el tamaño del Cluster realizado por medio de la siguiente función.

km.res$size
## [1]  8 13 16 13

Para tener un análisis de las medias se plantea la obtención de las mismas y de esta manera conocer las medidas de tendencia central para cada caso.

km.res$centers
##       Murder    Assault   UrbanPop        Rape
## 1  1.4118898  0.8743346 -0.8145211  0.01927104
## 2 -0.9615407 -1.1066010 -0.9301069 -0.96676331
## 3 -0.4894375 -0.3826001  0.5758298 -0.26165379
## 4  0.6950701  1.0394414  0.7226370  1.27693964

Esto se puede representar de manera vizual para mejorar la comprensión.

# Visualizando las k-medias
fviz_cluster(km.res, data = df,
palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
ellipse.type = "euclid", # Concentration ellipse
star.plot = TRUE, # Add segments from centroids to items
repel = TRUE, # Avoid label overplotting (slow)
ggtheme = theme_minimal()
)

Capítulo 5: K-medias

Clustering por K-medias

Nuevamente, se cargan los datos y se instalan los paquetes correspondientes.

library(cluster)
library(factoextra)
# Calculando PAM 
data("USArrests") # Load the data set
df <- scale(USArrests) # Scale the data
head(df, n = 3) # View the firt 3 rows of the data
##             Murder   Assault   UrbanPop         Rape
## Alabama 1.24256408 0.7828393 -0.5209066 -0.003416473
## Alaska  0.50786248 1.1068225 -1.2117642  2.484202941
## Arizona 0.07163341 1.4788032  0.9989801  1.042878388

Se estima en número optimo del número de los clusters

#  Estimating the optimal number of clusters
fviz_nbclust(df, pam, method = "silhouette")+
theme_classic()

En términos del trabajo también resulta relevante calcular el PAM Clustering con K=2, para ello se realiza lo mostrado en la siguiente línea de código.

pam.res <- pam(df, 2)
print(pam.res)
## Medoids:
##            ID     Murder    Assault   UrbanPop       Rape
## New Mexico 31  0.8292944  1.3708088  0.3081225  1.1603196
## Nebraska   27 -0.8008247 -0.8250772 -0.2445636 -0.5052109
## Clustering vector:
##        Alabama         Alaska        Arizona       Arkansas     California 
##              1              1              1              2              1 
##       Colorado    Connecticut       Delaware        Florida        Georgia 
##              1              2              2              1              1 
##         Hawaii          Idaho       Illinois        Indiana           Iowa 
##              2              2              1              2              2 
##         Kansas       Kentucky      Louisiana          Maine       Maryland 
##              2              2              1              2              1 
##  Massachusetts       Michigan      Minnesota    Mississippi       Missouri 
##              2              1              2              1              1 
##        Montana       Nebraska         Nevada  New Hampshire     New Jersey 
##              2              2              1              2              2 
##     New Mexico       New York North Carolina   North Dakota           Ohio 
##              1              1              1              2              2 
##       Oklahoma         Oregon   Pennsylvania   Rhode Island South Carolina 
##              2              2              2              2              1 
##   South Dakota      Tennessee          Texas           Utah        Vermont 
##              2              1              1              2              2 
##       Virginia     Washington  West Virginia      Wisconsin        Wyoming 
##              2              2              2              2              2 
## Objective function:
##    build     swap 
## 1.441358 1.368969 
## 
## Available components:
##  [1] "medoids"    "id.med"     "clustering" "objective"  "isolation" 
##  [6] "clusinfo"   "silinfo"    "diss"       "call"       "data"

Si se desea agrerar las clasificaciones de puntos a los datos originales se emplea esto.

dd <- cbind(USArrests, cluster = pam.res$cluster)
head(dd, n = 3)
##         Murder Assault UrbanPop Rape cluster
## Alabama   13.2     236       58 21.2       1
## Alaska    10.0     263       48 44.5       1
## Arizona    8.1     294       80 31.0       1

A continuación se accede a los resultados de la función pam() y se desarrollan los medoids de racismo en New Mexico, Nebraska.

pam.res$medoids
##                Murder    Assault   UrbanPop       Rape
## New Mexico  0.8292944  1.3708088  0.3081225  1.1603196
## Nebraska   -0.8008247 -0.8250772 -0.2445636 -0.5052109

Se presenta un Cluster de numeros

head(pam.res$clustering)
##    Alabama     Alaska    Arizona   Arkansas California   Colorado 
##          1          1          1          2          1          1

Finalmente, se vizualian los resultados del PAM clusters

fviz_cluster(pam.res,
palette = c("#00AFBB", "#FC4E07"), # color palette
ellipse.type = "t", # Concentration ellipse
repel = TRUE, # Avoid label overplotting (slow)
ggtheme = theme_classic()
)

Capítulo 6: CLARA - Aplicaciones del clustering largo

Calculando CLARA

Se cargan las librerías correspondientes. También se generan 500 objestos, pero cada uno está dividido en dos clusters. Para estos también se especifican los nombres de las columnas y las filas.

library(cluster)
library(factoextra)
set.seed(1234)

# Se generan 500 objetos, cada uno dividido entre dos clusters 
df <- rbind(cbind(rnorm(200,0,8), rnorm(200,0,8)),
cbind(rnorm(300,50,8), rnorm(300,50,8)))

# Se especifican los nombres de las columnas y filas 
colnames(df) <- c("x", "y")
rownames(df) <- paste0("S", 1:nrow(df))

# Se previsualizan los datos 
head(df, nrow = 6)
##             x        y
## S1  -9.656526 3.881815
## S2   2.219434 5.574150
## S3   8.675529 1.484111
## S4 -18.765582 5.605868
## S5   3.432998 2.493448
## S6   4.048447 6.083699

Como en los casos anteriores se estima el númreo óptimo de clusters que debe tener el modelo.

fviz_nbclust(df, clara, method = "silhouette")+
theme_classic()

Se computa CLARA y se presentan los componentes de la función clara.res.

# Compute CLARA
clara.res <- clara(df, 2, samples = 50, pamLike = TRUE)
# Print components of clara.res
print(clara.res)
## Call:     clara(x = df, k = 2, samples = 50, pamLike = TRUE) 
## Medoids:
##              x         y
## S121 -1.531137  1.145057
## S455 48.357304 50.233499
## Objective function:   9.87862
## Clustering vector:    Named int [1:500] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
##  - attr(*, "names")= chr [1:500] "S1" "S2" "S3" "S4" "S5" "S6" "S7" ...
## Cluster sizes:            200 300 
## Best sample:
##  [1] S37  S49  S54  S63  S68  S71  S76  S80  S82  S101 S103 S108 S109 S118 S121
## [16] S128 S132 S138 S144 S162 S203 S210 S216 S231 S234 S249 S260 S261 S286 S299
## [31] S304 S305 S312 S315 S322 S350 S403 S450 S454 S455 S456 S465 S488 S497
## 
## Available components:
##  [1] "sample"     "medoids"    "i.med"      "clustering" "objective" 
##  [6] "clusinfo"   "diss"       "call"       "silinfo"    "data"

Si se busca agregar las clasificaciones de los datos originales a los puntos se ejecuta el siguiente código.

dd <- cbind(df, cluster = clara.res$cluster)
head(dd, n = 4)
##             x        y cluster
## S1  -9.656526 3.881815       1
## S2   2.219434 5.574150       1
## S3   8.675529 1.484111       1
## S4 -18.765582 5.605868       1

Es posible acceder a los resultados generados por clara() según como se muestra a continuación.

# Medoids
clara.res$medoids
##              x         y
## S121 -1.531137  1.145057
## S455 48.357304 50.233499

Se realiza el Clustering respectivo.

# Clustering
head(clara.res$clustering, 10)
##  S1  S2  S3  S4  S5  S6  S7  S8  S9 S10 
##   1   1   1   1   1   1   1   1   1   1

También, se visualizan los Clusters de CLARA.

fviz_cluster(clara.res,
palette = c("#00AFBB", "#FC4E07"), # color palette
ellipse.type = "t", # Concentration ellipse
geom = "point", pointsize = 1,
ggtheme = theme_classic()
)

Capítulo 7: Clustering aglomerativo

library("factoextra")
library("cluster")
# Load the data
data("USArrests")
# Standardize the data
df <- scale(USArrests)
# Show the first 6 rows
head(df, nrow = 6)
##                Murder   Assault   UrbanPop         Rape
## Alabama    1.24256408 0.7828393 -0.5209066 -0.003416473
## Alaska     0.50786248 1.1068225 -1.2117642  2.484202941
## Arizona    0.07163341 1.4788032  0.9989801  1.042878388
## Arkansas   0.23234938 0.2308680 -1.0735927 -0.184916602
## California 0.27826823 1.2628144  1.7589234  2.067820292
## Colorado   0.02571456 0.3988593  0.8608085  1.864967207

Debido a medidas similares se computa la “dissimilarity” en la matriz de valores del data frame.

# df = the standardized data
res.dist <- dist(df, method = "euclidean")
as.matrix(res.dist)[1:6, 1:6]
##             Alabama   Alaska  Arizona Arkansas California Colorado
## Alabama    0.000000 2.703754 2.293520 1.289810   3.263110 2.651067
## Alaska     2.703754 0.000000 2.700643 2.826039   3.012541 2.326519
## Arizona    2.293520 2.700643 0.000000 2.717758   1.310484 1.365031
## Arkansas   1.289810 2.826039 2.717758 0.000000   3.763641 2.831051
## California 3.263110 3.012541 1.310484 3.763641   0.000000 1.287619
## Colorado   2.651067 2.326519 1.365031 2.831051   1.287619 0.000000

Se emplea a función hclust() para realizar el dendrograma.

# hclust() can be used as follow:
res.hc <- hclust(d = res.dist, method = "ward.D2")
# Dendrogram
# cex: label size
fviz_dend(res.hc, cex = 0.5) 
## Warning: The `<scale>` argument of `guides()` cannot be `FALSE`. Use "none" instead as
## of ggplot2 3.3.4.
## ℹ The deprecated feature was likely used in the factoextra package.
##   Please report the issue at <https://github.com/kassambara/factoextra/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Posterior a esto se verifica el árbol del cluster.

# Verify the cluster tree
# Compute cophentic distance
res.coph <- cophenetic(res.hc)
# Correlation between cophenetic distance and
# the original distance
cor(res.dist, res.coph)
## [1] 0.6975266

Ante esto se realiza lo siguiente para confirmar el valor adecuado.

res.hc2 <- hclust(res.dist, method = "average")
cor(res.dist, cophenetic(res.hc2))
## [1] 0.7180382

Se corta el dendrograma en diferentes grupos, más especificamente, en cuatro grupos.

# Cut tree into 4 groups
grp <- cutree(res.hc, k = 4)
head(grp, n = 4)
##  Alabama   Alaska  Arizona Arkansas 
##        1        2        2        3

También, se realiza una tabla con los grupos.

# Number of members in each cluster
table(grp)
## grp
##  1  2  3  4 
##  7 12 19 12

Y se plantean los nombres de cada uno de los grupos.

# Get the names for the members of cluster 1
rownames(df)[grp == 1]
## [1] "Alabama"        "Georgia"        "Louisiana"      "Mississippi"   
## [5] "North Carolina" "South Carolina" "Tennessee"

Se realiza una gráfica teniendo en cuenta lo realizado anteriormente.

# Cut in 4 groups and color by groups
fviz_dend(res.hc, k = 4, # Cut in four groups
cex = 0.5, # label size
k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
color_labels_by_k = TRUE, # color labels by groups
rect = TRUE # Add rectangle around groups
)

También se desarrolla otra manera de visualización de datos empleando la función fviz_cluster()

# Using the function fviz_cluster()
fviz_cluster(list(data = df, cluster = grp),
palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
ellipse.type = "convex", # Concentration ellipse
repel = TRUE, # Avoid label overplotting (slow)
show.clust.cent = FALSE, ggtheme = theme_minimal())

El resultado final es un Agglomerative nesting (Hierarical clustering) lo cual se presenta a como un dendrograma.

# Cluster R package
# Agglomerative Nesting (Hierarchical Clustering)
res.agnes <- agnes(x = USArrests, # data matrix
stand = TRUE, # Standardize the data
metric = "euclidean", # metric for distance matrix
method = "ward" # Linkage method
)
# DIvisive ANAlysis Clustering
res.diana <- diana(x = USArrests, # data matrix
stand = TRUE, # standardize the data
metric = "euclidean" # metric for distance matrix
)
# After running agnes() and diana(), you can use the function fviz_dend()[in factoextra] to visualize the output:
fviz_dend(res.agnes, cex = 0.6, k = 4)

Capítulo 8: clostering aglomerativo

Se hace una preparación de los datos por medio de un dataframe, además, se hace un subset que contenga 10 columnas para posteriormente plantear una comparación entre dendrogramas con su respectiva gráfica.

Se cargan las librerías correspondientes.

#install.packages("dendextend")
#install.packages("corrplot")
library(dendextend)
## 
## ---------------------
## Welcome to dendextend version 1.17.1
## Type citation('dendextend') for how to cite the package.
## 
## Type browseVignettes(package = 'dendextend') for the package vignette.
## The github page is: https://github.com/talgalili/dendextend/
## 
## Suggestions and bug-reports can be submitted at: https://github.com/talgalili/dendextend/issues
## You may ask questions at stackoverflow, use the r and dendextend tags: 
##   https://stackoverflow.com/questions/tagged/dendextend
## 
##  To suppress this message use:  suppressPackageStartupMessages(library(dendextend))
## ---------------------
## 
## Attaching package: 'dendextend'
## The following object is masked from 'package:stats':
## 
##     cutree
library(corrplot)
## corrplot 0.92 loaded

Se preparan los datos que serán utilizados para este análisis.

#Data preparation
df <- scale(USArrests)
# Subset containing 10 rows
set.seed(123)
ss <- sample(1:50, 10)
df <- df[ss,]
#Comparing dendrograms
# Compute distance matrix
res.dist <- dist(df, method = "euclidean")
# Compute 2 hierarchical clusterings
hc1 <- hclust(res.dist, method = "average")
hc2 <- hclust(res.dist, method = "ward.D2")
# Create two dendrograms
dend1 <- as.dendrogram (hc1)
dend2 <- as.dendrogram (hc2)
# Create a list to hold dendrograms
dend_list <- dendlist(dend1, dend2)
#Visual comparison of two dendrograms
#Draw a tanglegram:
tanglegram(dend1, dend2)

Al haber realizado ahora se genera el mismo gráfico pero cambiando sus características estéticas de la siguiente forma.

#Customized the tanglegram using many other options as follow:
tanglegram(dend1, dend2,
highlight_distinct_edges = FALSE, # Turn-off dashed lines
common_subtrees_color_lines = FALSE, # Turn-off line colors
common_subtrees_color_branches = TRUE, # Color common branches
main = paste("Entanglement =", round(entanglement(dend_list), 2))
)

Se consigue la matriz de correlación

#Correlation matrix between a list of dendrograms
# Cophenetic correlation matrix
cor.dendlist(dend_list, method = "cophenetic")
##           [,1]      [,2]
## [1,] 1.0000000 0.9925544
## [2,] 0.9925544 1.0000000

También se crea una matriz de correlación con el método de Baker

# Baker correlation matrix
cor.dendlist(dend_list, method = "baker")
##           [,1]      [,2]
## [1,] 1.0000000 0.9895528
## [2,] 0.9895528 1.0000000

Se halla el coeficiente de correlación de Cophenetic

# Cophenetic correlation coefficient
cor_cophenetic(dend1, dend2)
## [1] 0.9925544

También se halla el coeficiente de correlación de Baker

# Baker correlation coefficient
cor_bakers_gamma(dend1, dend2)
## [1] 0.9895528

Entonces, con estos datos se comparan los dendogramas

#COMPARING DENDROGRAMS
# Create multiple dendrograms by chaining
dend1 <- df %>% dist %>% hclust("complete") %>% as.dendrogram
dend2 <- df %>% dist %>% hclust("single") %>% as.dendrogram
dend3 <- df %>% dist %>% hclust("average") %>% as.dendrogram
dend4 <- df %>% dist %>% hclust("centroid") %>% as.dendrogram
# Compute correlation matrix
dend_list <- dendlist("Complete" = dend1, "Single" = dend2,
"Average" = dend3, "Centroid" = dend4)
cors <- cor.dendlist(dend_list)
# Print correlation matrix
round(cors, 2)
##          Complete Single Average Centroid
## Complete     1.00   0.46    0.45     0.30
## Single       0.46   1.00    0.23     0.17
## Average      0.45   0.23    1.00     0.31
## Centroid     0.30   0.17    0.31     1.00

Se visualiza la matriz de correlación usando una función del paquete corrplot

# Visualize the correlation matrix using corrplot package
corrplot(cors, "pie", "lower")

Capítulo 9: Visualización de Dendogramas

En este capítulo se explican y presentan métodos para gráficar o presentar dendogramas de distintas clases.

#install.packages("igraph")
library(factoextra)
library(dendextend)
library(igraph)
## 
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## The following object is masked from 'package:base':
## 
##     union

Se cargan los datos correspondientes

# Load data
data(USArrests)
# Compute distances and hierarchical clustering
dd <- dist(scale(USArrests), method = "euclidean")
hc <- hclust(dd, method = "ward.D2")
#Visualizing dendrograms
fviz_dend(hc, cex = 0.5)

Es posible usar los argumentos de main, sub, xlab y ylab para cambiar las características como se muestra a continuación.

fviz_dend(hc, cex = 0.5,
main = "Dendrogram - ward.D2",
xlab = "Objects", ylab = "Distance", sub = "")

También se puede visualizar de manera horizontal.

#To draw a horizontal dendrogram, type this:
fviz_dend(hc, cex = 0.5, horiz = TRUE)

También es posible cortar el árbol a una altura determinada para particionar los datos en varios grupos, como se describe en el capítulo anterior: Agrupación jerárquica (Capítulo 7). En este caso, es posible colorear ramas alrededor de cada grupo.

#To change the plot theme
fviz_dend(hc, k = 4, # Cut in four groups
cex = 0.5, # label size
k_colors = c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07"),
color_labels_by_k = TRUE, # color labels by groups
ggtheme = theme_gray() # Change theme
)

Para un cambio estético, en el código a continuación, se cambiaran los colores del grupo usando la paleta de colores “jco” (journal of clinical oncology):

fviz_dend(hc, cex = 0.5, k = 4, # Cut in four groups
k_colors = "jco")

También se puede representar con cuadros y de manera horizontal.

fviz_dend(hc, k = 4, cex = 0.4, horiz = TRUE, k_colors = "jco",
rect = TRUE, rect_border = "jco", rect_fill = TRUE)

Además, se puece crear un dendograma horizontal añdiendo la opción _circular” al código.

fviz_dend(hc, cex = 0.5, k = 4,
k_colors = "jco", type = "circular")

Otras formas de visualización como la siguiente son posibles.

fviz_dend(hc, k = 4, k_colors = "jco",
type = "phylogenic", repel = TRUE)

Ahora se muestra como se crea un dendrograma completo. Pero primero es necesario determinar las específicaciones y para expreraslo se presentan dos gráficos incompletos que, eventualmente, darán lugar al dendrograma en su totalidad.

# Case of dendrogram with large data sets
#Zooming in the dendrogram
fviz_dend(hc, xlim = c(1, 20), ylim = c(1, 8))

#Plotting a sub-tree of dendrograms
# Create a plot of the whole dendrogram,
# and extract the dendrogram data
dend_plot <- fviz_dend(hc, k = 4, # Cut in four groups
cex = 0.5, # label size
k_colors = "jco"
)
dend_data <- attr(dend_plot, "dendrogram") # Extract dendrogram data
# Cut the dendrogram at height h = 10
dend_cuts <- cut(dend_data, h = 10)
# Visualize the truncated version containing
# two branches
fviz_dend(dend_cuts$upper)
## Warning in min(-diff(our_dend_heights)): no non-missing arguments to min;
## returning Inf

A pesar de lo realizado anteriormente ahora se presenta el digarama completo.

# Plot the whole dendrogram
print(dend_plot)

Ahora se realiza el primer sub-árbol.

# Plot subtree 1
fviz_dend(dend_cuts$lower[[1]], main = "Subtree 1")

A continuación, de la misma manera, se presenta el segundo sub-árbol.

# Plot subtree 2
fviz_dend(dend_cuts$lower[[2]], main = "Subtree 2")

Esto se puede hacer de manera circular también.

#You can also plot circular trees as follow:
fviz_dend(dend_cuts$lower[[2]], type = "circular")

Con el paquete dendextend también es posible manipular y crear dendogramas. A continuación se presenta un ejemplo de como realizar esto.

#Manipulating dendrograms using dendextend
#Standard R code for creating a dendrogram:
data <- scale(USArrests)
dist.res <- dist(data)
hc <- hclust(dist.res, method = "ward.D2")
dend <- as.dendrogram(hc)
plot(dend)

#R code for creating a dendrogram using chaining operator
library(dendextend)
dend <- USArrests[1:5,] %>% # data
scale %>% # Scale the data
dist %>% # calculate a distance matrix,
hclust(method = "ward.D2") %>% # Hierarchical clustering
as.dendrogram # Turn the object into a dendrogram.
plot(dend)

Otro ejemplo del uso de dendextend se presenta aquí.

#Example
library(dendextend)
# 1. Create a customized dendrogram
mycols <- c("#2E9FDF", "#00AFBB", "#E7B800", "#FC4E07")
dend <- as.dendrogram(hc) %>%
set("branches_lwd", 1) %>% # Branches line width
set("branches_k_color", mycols, k = 4) %>% # Color branches by groups
set("labels_colors", mycols, k = 4) %>% # Color labels by groups
set("labels_cex", 0.5) # Change label size
# 2. Create plot
fviz_dend(dend)

Capítulo 10: Heatmap, estadísticas interactivas

Como en los casos anteriores se preparan los datos y se descargan los paquetes correspondientes.

df <- scale(mtcars)

# Default plot
heatmap(df, scale = "none")

Se pueden añadir distintos colores de la siguiente forma

col<- colorRampPalette(c("red", "white", "blue"))(256)

#install.packages("RColorBrewer")
library("RColorBrewer")
col <- colorRampPalette(brewer.pal(10, "RdYlBu"))(256)
# Use RColorBrewer color palette names
library("RColorBrewer")
col <- colorRampPalette(brewer.pal(10, "RdYlBu"))(256)
heatmap(df, scale = "none", col =  col, 
        RowSideColors = rep(c("blue", "pink"), each = 16),
        ColSideColors = c(rep("purple", 5), rep("orange", 6)))

También es posible utilizar la función del paquete ggplot llamada heatmap.2()

#install.packages("gplots")
library("gplots")
## 
## Attaching package: 'gplots'
## The following object is masked from 'package:stats':
## 
##     lowess
heatmap.2(df, scale = "none", col = bluered(100), 
          trace = "none", density.info = "none")

Al igual que en los casos anteriores es posible mejorar la imagen de estos mapas por medio de la función pheatmap() como se muestra a continuación.

#install.packages("pheatmap")
library("pheatmap")
pheatmap(df, cutree_rows = 4)

También es posible usar el paquete dentextend para mejorar los heatmaps

library(dendextend)
# order for rows
Rowv  <- mtcars %>% scale %>% dist %>% hclust %>% as.dendrogram %>%
   set("branches_k_color", k = 3) %>% set("branches_lwd", 1.2) %>%
   ladderize
# Order for columns: We must transpose the data
Colv  <- mtcars %>% scale %>% t %>% dist %>% hclust %>% as.dendrogram %>%
   set("branches_k_color", k = 2, value = c("orange", "blue")) %>%
   set("branches_lwd", 1.2) %>%
   ladderize

En la anteriores líneas de código se organizó la información, a continuación se realizará el gráfico.

library(gplots)
heatmap.2(scale(mtcars), scale = "none", col = bluered(100), 
          Rowv = Rowv, Colv = Colv,
          trace = "none", density.info = "none")

Para realizar heatmaps complejos es necesario empleear la siguiente línea de código.

if (!requireNamespace("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
BiocManager::install("ComplexHeatmap")
## 'getOption("repos")' replaces Bioconductor standard repositories, see
## 'help("repositories", package = "BiocManager")' for details.
## Replacement repositories:
##     CRAN: http://rspm/default/__linux__/focal/latest
## Bioconductor version 3.18 (BiocManager 1.30.22), R 4.3.2 (2023-10-31)
## Warning: package(s) not installed when version(s) same as or greater than current; use
##   `force = TRUE` to re-install: 'ComplexHeatmap'
## Installation paths not writeable, unable to update packages
##   path: /opt/R/4.3.2/lib/R/library
##   packages:
##     lattice, Matrix
library(ComplexHeatmap)
## Loading required package: grid
## ========================================
## ComplexHeatmap version 2.18.0
## Bioconductor page: http://bioconductor.org/packages/ComplexHeatmap/
## Github page: https://github.com/jokergoo/ComplexHeatmap
## Documentation: http://jokergoo.github.io/ComplexHeatmap-reference
## 
## If you use it in published research, please cite either one:
## - Gu, Z. Complex Heatmap Visualization. iMeta 2022.
## - Gu, Z. Complex heatmaps reveal patterns and correlations in multidimensional 
##     genomic data. Bioinformatics 2016.
## 
## 
## The new InteractiveComplexHeatmap package can directly export static 
## complex heatmaps into an interactive Shiny app with zero effort. Have a try!
## 
## This message can be suppressed by:
##   suppressPackageStartupMessages(library(ComplexHeatmap))
## ========================================
## ! pheatmap() has been masked by ComplexHeatmap::pheatmap(). Most of the arguments
##    in the original pheatmap() are identically supported in the new function. You 
##    can still use the original function by explicitly calling pheatmap::pheatmap().
## 
## Attaching package: 'ComplexHeatmap'
## The following object is masked from 'package:pheatmap':
## 
##     pheatmap
Heatmap(df, 
        name = "mtcars", #title of legend
        column_title = "Variables", row_title = "Samples",
        row_names_gp = gpar(fontsize = 7) # Text size for row names
        )

Se carga también la librería Circlize

library(circlize)
## ========================================
## circlize version 0.4.15
## CRAN page: https://cran.r-project.org/package=circlize
## Github page: https://github.com/jokergoo/circlize
## Documentation: https://jokergoo.github.io/circlize_book/book/
## 
## If you use it in published research, please cite:
## Gu, Z. circlize implements and enhances circular visualization
##   in R. Bioinformatics 2014.
## 
## This message can be suppressed by:
##   suppressPackageStartupMessages(library(circlize))
## ========================================
## 
## Attaching package: 'circlize'
## The following object is masked from 'package:igraph':
## 
##     degree
mycols <- colorRamp2(breaks = c(-2, 0, 2), 
                    colors = c("green", "white", "red"))
Heatmap(df, name = "mtcars", col = mycols)

library("circlize")
library("RColorBrewer")
Heatmap(df, name = "mtcars",
        col = colorRamp2(c(-2, 0, 2), brewer.pal(n=3, name="RdBu")))

library(dendextend)
row_dend = hclust(dist(df)) # row clustering
col_dend = hclust(dist(t(df))) # column clustering
Heatmap(df, name = "mtcars", 
        row_names_gp = gpar(fontsize = 6.5),
        cluster_rows = color_branches(row_dend, k = 4),
        cluster_columns = color_branches(col_dend, k = 2))

Para dividir en dos o más parte un heatmap el procedimiento a seguir es el siguiente.

# Divide into 2 groups
set.seed(2)
Heatmap(df, name = "mtcars", k = 2)

# split by a vector specifying rowgroups
Heatmap(df, name = "mtcars", split = mtcars$cyl,
        row_names_gp = gpar(fontsize = 7))

También es posible hacer particiones en una serie definida de la siguiente forma.

# Split by combining multiple variables
Heatmap(df, name ="mtcars", 
        split = data.frame(cyl = mtcars$cyl, am = mtcars$am),
        row_names_gp = gpar(fontsize = 7))

Es posible realizar una o una serie de anotaciones dentro del “heatmap”.

# Define some graphics to display the distribution of columns
.hist = anno_histogram(df, gp = gpar(fill = "lightblue"))
.density = anno_density(df, type = "line", gp = gpar(col = "blue"))
ha_mix_top = HeatmapAnnotation(
  hist = .hist, density = .density,
  height = unit(3.8, "cm")
  )
# Define some graphics to display the distribution of rows
.violin = anno_density(df, type = "violin", 
                       gp = gpar(fill = "lightblue"), which = "row")
.boxplot = anno_boxplot(df, which = "row")
ha_mix_right = HeatmapAnnotation(violin = .violin, bxplt = .boxplot,
                              which = "row", width = unit(4, "cm"))
# Combine annotation with heatmap
Heatmap(df, name = "mtcars", 
        column_names_gp = gpar(fontsize = 8),
        top_annotation = ha_mix_top) + ha_mix_right

Es posible combinar varios heatmaps por medio del siguiente código.

# Heatmap 1
ht1 = Heatmap(df, name = "ht1", km = 2,
              column_names_gp = gpar(fontsize = 9))
# Heatmap 2
ht2 = Heatmap(df, name = "ht2", 
        col = circlize::colorRamp2(c(-2, 0, 2), c("green", "white", "red")),
        column_names_gp = gpar(fontsize = 9))
# Combine the two heatmaps
ht1 + ht2

Además de lo visto anteriormente también es factible realizar una matriz de expresión génica. Esto significa que en los datos de expresión génica las filas son genes y las columans son muestras. Esto implica que se puede adjuntar más información sobre los genes después del mapa de calor de expresiones, como la longitud del gent y el tipo de genes.

expr <- readRDS(paste0(system.file(package = "ComplexHeatmap"),
                      "/extdata/gene_expression.rds"))
mat <- as.matrix(expr[, grep("cell", colnames(expr))])
type <- gsub("s\\d+_", "", colnames(mat))
ha = HeatmapAnnotation(
  df = data.frame(type = type),
   annotation_height = unit(4, "mm")
  )

Heatmap(mat, name = "expression", km = 5, top_annotation = ha,
    show_row_names = FALSE, show_column_names = FALSE) +
Heatmap(expr$length, name = "length", width = unit(5, "mm"),
    col = circlize::colorRamp2(c(0, 100000), c("white", "orange"))) +
Heatmap(expr$type, name = "type", width = unit(5, "mm")) +
Heatmap(expr$chr, name = "chr", width = unit(5, "mm"),
    col = circlize::rand_color(length(unique(expr$chr))))
## There are 23 unique colors in the vector `col` and 23 unique values in
## `matrix`. `Heatmap()` will treat it as an exact discrete one-to-one
## mapping. If this is not what you want, slightly change the number of
## colors, e.g. by adding one more color or removing a color.

Segunda sección

Capítulo 3 II. Componentes principales del análisis

El análisis de componentes principales (PCA) nos permite resumir y visualizar la información en un conjunto de datos que contiene observaciones cuantitativas interrelacionadas.

Cada variable podría considerarse como una dimensión diferente, pero el número de cuatro o más dimensiones podría ser difícil de visualizar.

PCA se puede utilizar para extraer la información importante de datos multivariados y para expresar esta información como un conjunto de pocas variables nuevas llamadas componentes principales. Cada componente principal corresponde a una combinación lineal de las variables originales. Sin embargo, el número de componentes principales sólo puede ser igual o menor que el número de originales.

Entonces, para desarrollar esto se cargaron los análisis.

#install.packages("FactoMineR")
library("FactoMineR")
library("factoextra")

Se descargan los datos que se emplearán para el análisis

#Se descargan los datos 
data(decathlon2)
head(decathlon2)
##           X100m Long.jump Shot.put High.jump X400m X110m.hurdle Discus
## SEBRLE    11.04      7.58    14.83      2.07 49.81        14.69  43.75
## CLAY      10.76      7.40    14.26      1.86 49.37        14.05  50.72
## BERNARD   11.02      7.23    14.25      1.92 48.93        14.99  40.87
## YURKOV    11.34      7.09    15.19      2.10 50.42        15.31  46.26
## ZSIVOCZKY 11.13      7.30    13.48      2.01 48.62        14.17  45.67
## McMULLEN  10.83      7.31    13.76      2.13 49.91        14.38  44.41
##           Pole.vault Javeline X1500m Rank Points Competition
## SEBRLE          5.02    63.19  291.7    1   8217    Decastar
## CLAY            4.92    60.15  301.5    2   8122    Decastar
## BERNARD         5.32    62.77  280.1    4   8067    Decastar
## YURKOV          4.72    63.44  276.4    5   8036    Decastar
## ZSIVOCZKY       4.42    55.37  268.0    7   8004    Decastar
## McMULLEN        4.42    56.37  285.1    8   7995    Decastar

Se toman los datos principales para el objetivo de estudio.

decathlon2.active <- decathlon2[1:23, 1:10]
head(decathlon2.active[, 1:6], 4)
##         X100m Long.jump Shot.put High.jump X400m X110m.hurdle
## SEBRLE  11.04      7.58    14.83      2.07 49.81        14.69
## CLAY    10.76      7.40    14.26      1.86 49.37        14.05
## BERNARD 11.02      7.23    14.25      1.92 48.93        14.99
## YURKOV  11.34      7.09    15.19      2.10 50.42        15.31
res.pca <- PCA(decathlon2.active, graph = FALSE)

#output
print(res.pca)
## **Results for the Principal Component Analysis (PCA)**
## The analysis was performed on 23 individuals, described by 10 variables
## *The results are available in the following objects:
## 
##    name               description                          
## 1  "$eig"             "eigenvalues"                        
## 2  "$var"             "results for the variables"          
## 3  "$var$coord"       "coord. for the variables"           
## 4  "$var$cor"         "correlations variables - dimensions"
## 5  "$var$cos2"        "cos2 for the variables"             
## 6  "$var$contrib"     "contributions of the variables"     
## 7  "$ind"             "results for the individuals"        
## 8  "$ind$coord"       "coord. for the individuals"         
## 9  "$ind$cos2"        "cos2 for the individuals"           
## 10 "$ind$contrib"     "contributions of the individuals"   
## 11 "$call"            "summary statistics"                 
## 12 "$call$centre"     "mean of the variables"              
## 13 "$call$ecart.type" "standard error of the variables"    
## 14 "$call$row.w"      "weights for the individuals"        
## 15 "$call$col.w"      "weights for the variables"

A continuación, se propone una forma de vizualisar y de esta manera interpretar los datos.

eig.val <- get_eigenvalue(res.pca)

eig.val
##        eigenvalue variance.percent cumulative.variance.percent
## Dim.1   4.1242133        41.242133                    41.24213
## Dim.2   1.8385309        18.385309                    59.62744
## Dim.3   1.2391403        12.391403                    72.01885
## Dim.4   0.8194402         8.194402                    80.21325
## Dim.5   0.7015528         7.015528                    87.22878
## Dim.6   0.4228828         4.228828                    91.45760
## Dim.7   0.3025817         3.025817                    94.48342
## Dim.8   0.2744700         2.744700                    97.22812
## Dim.9   0.1552169         1.552169                    98.78029
## Dim.10  0.1219710         1.219710                   100.00000
fviz_eig(res.pca, addlabels = TRUE, ylim = c(0, 50))

Se realiza una gráfica de variables

var <- get_pca_var(res.pca)

var
## Principal Component Analysis Results for variables
##  ===================================================
##   Name       Description                                    
## 1 "$coord"   "Coordinates for the variables"                
## 2 "$cor"     "Correlations between variables and dimensions"
## 3 "$cos2"    "Cos2 for the variables"                       
## 4 "$contrib" "contributions of the variables"

Se crean los componetes de la gráfica

# Coordinates
head(var$coord)
##                   Dim.1       Dim.2      Dim.3       Dim.4      Dim.5
## X100m        -0.8506257 -0.17939806  0.3015564  0.03357320 -0.1944440
## Long.jump     0.7941806  0.28085695 -0.1905465 -0.11538956  0.2331567
## Shot.put      0.7339127  0.08540412  0.5175978  0.12846837 -0.2488129
## High.jump     0.6100840 -0.46521415  0.3300852  0.14455012  0.4027002
## X400m        -0.7016034  0.29017826  0.2835329  0.43082552  0.1039085
## X110m.hurdle -0.7641252 -0.02474081  0.4488873 -0.01689589  0.2242200
# Cos2: quality on the factore map
head(var$cos2)
##                  Dim.1        Dim.2      Dim.3        Dim.4      Dim.5
## X100m        0.7235641 0.0321836641 0.09093628 0.0011271597 0.03780845
## Long.jump    0.6307229 0.0788806285 0.03630798 0.0133147506 0.05436203
## Shot.put     0.5386279 0.0072938636 0.26790749 0.0165041211 0.06190783
## High.jump    0.3722025 0.2164242070 0.10895622 0.0208947375 0.16216747
## X400m        0.4922473 0.0842034209 0.08039091 0.1856106269 0.01079698
## X110m.hurdle 0.5838873 0.0006121077 0.20149984 0.0002854712 0.05027463
# Contributions to the principal components
head(var$contrib)
##                  Dim.1      Dim.2     Dim.3       Dim.4     Dim.5
## X100m        17.544293  1.7505098  7.338659  0.13755240  5.389252
## Long.jump    15.293168  4.2904162  2.930094  1.62485936  7.748815
## Shot.put     13.060137  0.3967224 21.620432  2.01407269  8.824401
## High.jump     9.024811 11.7715838  8.792888  2.54987951 23.115504
## X400m        11.935544  4.5799296  6.487636 22.65090599  1.539012
## X110m.hurdle 14.157544  0.0332933 16.261261  0.03483735  7.166193

Circulo de correlación

# Coordinates of variables
head(var$coord, 4) 
##                Dim.1       Dim.2      Dim.3      Dim.4      Dim.5
## X100m     -0.8506257 -0.17939806  0.3015564  0.0335732 -0.1944440
## Long.jump  0.7941806  0.28085695 -0.1905465 -0.1153896  0.2331567
## Shot.put   0.7339127  0.08540412  0.5175978  0.1284684 -0.2488129
## High.jump  0.6100840 -0.46521415  0.3300852  0.1445501  0.4027002

Todo esto se grafica de esta manera.

#plot
fviz_pca_var(res.pca, col.var = "black")

Otra represantación rápida podría ser la siguiente.

head(var$cos2, 4)
##               Dim.1       Dim.2      Dim.3      Dim.4      Dim.5
## X100m     0.7235641 0.032183664 0.09093628 0.00112716 0.03780845
## Long.jump 0.6307229 0.078880629 0.03630798 0.01331475 0.05436203
## Shot.put  0.5386279 0.007293864 0.26790749 0.01650412 0.06190783
## High.jump 0.3722025 0.216424207 0.10895622 0.02089474 0.16216747
corrplot::corrplot(var$cos2, is.corr=FALSE)

# Total cos2 of variables on Dim.1 and Dim.2
fviz_cos2(res.pca, choice = "var", axes = 1:2)

# Color by cos2 values: quality on the factor map

fviz_pca_var(res.pca, col.var = "cos2",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), 
             repel = TRUE) # Avoid text overlapping

# Indicate cos2 by transparency
fviz_pca_var(res.pca, alpha.var = "cos2")

La contribución de variables de componentes principales están de de acuerdo a la virabilidad dada por los compontes que estos mismos expresan.

head(var$contrib, 4)
##               Dim.1      Dim.2     Dim.3     Dim.4     Dim.5
## X100m     17.544293  1.7505098  7.338659 0.1375524  5.389252
## Long.jump 15.293168  4.2904162  2.930094 1.6248594  7.748815
## Shot.put  13.060137  0.3967224 21.620432 2.0140727  8.824401
## High.jump  9.024811 11.7715838  8.792888 2.5498795 23.115504
corrplot::corrplot(var$contrib, is.corr=FALSE)

# Top 10 Contributions of variables to PC1
fviz_contrib(res.pca, choice = "var", axes = 1, top = 10)

# Top 10 Contributions of variables to PC2
fviz_contrib(res.pca, choice = "var", axes = 2, top = 10)

#Total contribution of PC1 and PC2
fviz_contrib(res.pca, choice = "var", axes = 1:2, top = 10)

La línea discontinua roja en el gráfico anterior indica la contribución promedio esperada. Se puede ver que las variables - X100m, Long.jump y Pole.vault - son las que más contribuyen a las dimensiones 1 y 2.

Las variables más importantes (o contribuyentes) se pueden resaltar en el gráfico de correlación de la siguiente manera:

fviz_pca_var(res.pca, col.var = "contrib",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"))

# Change the transparency by contrib values
fviz_pca_var(res.pca, alpha.var = "contrib")

Es posible colorear las variables por cualquier variable continua personalizada. La variable de color debe tener la misma longitud que el número de variables activas en el PCA (donde n = 10).

# Create a random continuous variable of length 10
set.seed(123)
my.cont.var <- rnorm(10)

# Color variables by the continuous variable
fviz_pca_var(res.pca, col.var = my.cont.var,
             gradient.cols = c("blue", "yellow", "red"),
             legend.title = "Cont.Var")

Es factible utilizar la función dimdesc() para identificar las variables asociadas más importantes para tener un análisis de componetes principales.

res.desc <- dimdesc(res.pca, axes = c(1,2), proba = 0.05)

# Description of dimension 1
res.desc$Dim.1
## 
## Link between the variable and the continuous variables (R-square)
## =================================================================================
##              correlation      p.value
## Long.jump      0.7941806 6.059893e-06
## Discus         0.7432090 4.842563e-05
## Shot.put       0.7339127 6.723102e-05
## High.jump      0.6100840 1.993677e-03
## Javeline       0.4282266 4.149192e-02
## X400m         -0.7016034 1.910387e-04
## X110m.hurdle  -0.7641252 2.195812e-05
## X100m         -0.8506257 2.727129e-07
# Description of dimension 2
res.desc$Dim.2
## 
## Link between the variable and the continuous variables (R-square)
## =================================================================================
##            correlation      p.value
## Pole.vault   0.8074511 3.205016e-06
## X1500m       0.7844802 9.384747e-06
## High.jump   -0.4652142 2.529390e-02

Por medio de los siguientes métodos se puede realizar una gráfica individual.

Los resultados individuales se extraen con la función get_pca_ind()

ind <- get_pca_ind(res.pca)
ind
## Principal Component Analysis Results for individuals
##  ===================================================
##   Name       Description                       
## 1 "$coord"   "Coordinates for the individuals" 
## 2 "$cos2"    "Cos2 for the individuals"        
## 3 "$contrib" "contributions of the individuals"
# Coordinates of individuals
head(ind$coord)
##                Dim.1      Dim.2      Dim.3       Dim.4       Dim.5
## SEBRLE     0.1955047  1.5890567  0.6424912  0.08389652  1.16829387
## CLAY       0.8078795  2.4748137 -1.3873827  1.29838232 -0.82498206
## BERNARD   -1.3591340  1.6480950  0.2005584 -1.96409420  0.08419345
## YURKOV    -0.8889532 -0.4426067  2.5295843  0.71290837  0.40782264
## ZSIVOCZKY -0.1081216 -2.0688377 -1.3342591 -0.10152796 -0.20145217
## McMULLEN   0.1212195 -1.0139102 -0.8625170  1.34164291  1.62151286
# Quality of individuals
head(ind$cos2)
##                 Dim.1      Dim.2       Dim.3       Dim.4        Dim.5
## SEBRLE    0.007530179 0.49747323 0.081325232 0.001386688 0.2689026575
## CLAY      0.048701249 0.45701660 0.143628117 0.125791741 0.0507850580
## BERNARD   0.197199804 0.28996555 0.004294015 0.411819183 0.0007567259
## YURKOV    0.096109800 0.02382571 0.778230322 0.061812637 0.0202279796
## ZSIVOCZKY 0.001574385 0.57641944 0.239754152 0.001388216 0.0054654972
## McMULLEN  0.002175437 0.15219499 0.110137872 0.266486530 0.3892621478
# Contributions of individuals
head(ind$contrib)
##                Dim.1      Dim.2      Dim.3       Dim.4       Dim.5
## SEBRLE    0.04029447  5.9714533  1.4483919  0.03734589  8.45894063
## CLAY      0.68805664 14.4839248  6.7537381  8.94458283  4.21794385
## BERNARD   1.94740183  6.4234107  0.1411345 20.46819433  0.04393073
## YURKOV    0.83308415  0.4632733 22.4517396  2.69663605  1.03075263
## ZSIVOCZKY 0.01232413 10.1217143  6.2464325  0.05469230  0.25151025
## McMULLEN  0.01549089  2.4310854  2.6102794  9.55055888 16.29493304

Ahora se presentan los gráficos resultantes de estos datos.

fviz_pca_ind(res.pca)

Aplicando color se puede visualizar así.

#Color by cos2 value

fviz_pca_ind(res.pca, col.ind = "cos2", 
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE) # Avoid text overlapping (slow if many points)

También se pueden aplicar puntos.

#Point size by cos2 value

fviz_pca_ind(res.pca, pointsize = "cos2", 
             pointshape = 21, fill = "#E7B800",
             repel = TRUE) # Avoid text overlapping (slow if many points)

Se pueden combinar ambas representaciones

#Both size and color by cos2

fviz_pca_ind(res.pca, col.ind = "cos2", pointsize = "cos2",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE) # Avoid text overlapping (slow if many points)

También se pudo crear un diagrama de barras de la calidad de representación (cos2) de los individuos.

fviz_cos2(res.pca, choice = "ind")

# Total contribution on PC1 and PC2
fviz_contrib(res.pca, choice = "ind", axes = 1:2)

En cuanto a las variables, los individuos pueden ser coloreados por cualquier variable continua personalizada con el argumento col.ind

# Create a random continuous variable of length 23,
# Same length as the number of active individuals in the PCA

set.seed(123)
my.cont.var <- rnorm(23)

# Color individuals by the continuous variable

fviz_pca_ind(res.pca, col.ind = my.cont.var,
             gradient.cols = c("blue", "yellow", "red"),
             legend.title = "Cont.Var")

Tanto las variables complementarias continuas como las categóricas no se utilizan para la determinación de los componentes principales, sino que se utilizan como elementos predichos a partir de sus coordenadas a través de la información proporcionada por el PCA.

Para especificar individuos y variables adicionales, la función PCA() se puede utilizar de la siguiente manera.

res.pca_2 <- PCA(decathlon2, ind.sup = 24:27, 
               quanti.sup = 11:12, quali.sup = 13, graph=FALSE)

Para variables cuantativas se especifica así.

res.pca_2$quanti.sup
## $coord
##             Dim.1       Dim.2      Dim.3       Dim.4       Dim.5
## Rank   -0.7014777 -0.24519443 -0.1834294  0.05575186 -0.07382647
## Points  0.9637075  0.07768262  0.1580225 -0.16623092 -0.03114711
## 
## $cor
##             Dim.1       Dim.2      Dim.3       Dim.4       Dim.5
## Rank   -0.7014777 -0.24519443 -0.1834294  0.05575186 -0.07382647
## Points  0.9637075  0.07768262  0.1580225 -0.16623092 -0.03114711
## 
## $cos2
##            Dim.1       Dim.2      Dim.3      Dim.4        Dim.5
## Rank   0.4920710 0.060120310 0.03364635 0.00310827 0.0054503477
## Points 0.9287322 0.006034589 0.02497110 0.02763272 0.0009701427

La gráfica se realiza siguiendo la misma lógica anteriormente planteada.

#visualize
fviz_pca_var(res.pca_2)

Se cambia el color

# Change color of variables
fviz_pca_var(res.pca_2,
             col.var = "black",     # Active variables
             col.quanti.sup = "red" # Suppl. quantitative variables
)

Se ocultan las variables activas en el gráfico y se muestran sólo las variables complementarias.

fviz_pca_var(res.pca_2, invisible = "var")

Aquí se esconden las variables suplemnetarias

fviz_pca_var(res.pca_2, invisible = "quanti.sup")

Para el caso predictivo de resultados individuales se emplea la siguiente función.

res.pca_2$ind.sup
## $coord
##              Dim.1       Dim.2      Dim.3      Dim.4       Dim.5
## KARPOV   0.7947206  0.77951227 -1.6330203  1.7242283 -0.75070396
## WARNERS -0.3864645 -0.12159237 -1.7387332 -0.7063341 -0.03230011
## Nool    -0.5591306  1.97748871 -0.4830358 -2.2784526 -0.25461493
## Drews   -1.1092038  0.01741477 -3.0488182 -1.5343468 -0.32642192
## 
## $cos2
##              Dim.1        Dim.2      Dim.3      Dim.4        Dim.5
## KARPOV  0.05104677 4.911173e-02 0.21553730 0.24028620 0.0455487744
## WARNERS 0.02422707 2.398250e-03 0.49039677 0.08092862 0.0001692349
## Nool    0.02897149 3.623868e-01 0.02162236 0.48108780 0.0060077529
## Drews   0.09207094 2.269527e-05 0.69560547 0.17617609 0.0079736753
## 
## $dist
##   KARPOV  WARNERS     Nool    Drews 
## 3.517470 2.482899 3.284943 3.655527

Se puede visualizar todos los individuos (activos y suplementarios). También podemos agregar las variables cualitativas suplementarias con la siguiente función.

p_2 <- fviz_pca_ind(res.pca_2, col.ind.sup = "blue", repel = TRUE)
p_2 <- fviz_add(p_2, res.pca_2$quali.sup$coord, color = "red")
p_2

Los resultados concernientes a las variables cuantitativas suplementarias son los dados a continuación.

res.pca_2$quali
## $coord
##              Dim.1      Dim.2       Dim.3      Dim.4      Dim.5
## Decastar -1.343451  0.1218097 -0.03789524  0.1808357  0.1343364
## OlympicG  1.231497 -0.1116589  0.03473730 -0.1657661 -0.1231417
## 
## $cos2
##              Dim.1       Dim.2        Dim.3      Dim.4       Dim.5
## Decastar 0.9051233 0.007440939 0.0007201669 0.01639956 0.009050062
## OlympicG 0.9051233 0.007440939 0.0007201669 0.01639956 0.009050062
## 
## $v.test
##              Dim.1      Dim.2      Dim.3      Dim.4      Dim.5
## Decastar -2.970766  0.4034256 -0.1528767  0.8971036  0.7202457
## OlympicG  2.970766 -0.4034256  0.1528767 -0.8971036 -0.7202457
## 
## $dist
## Decastar OlympicG 
## 1.412108 1.294433 
## 
## $eta2
##                 Dim.1      Dim.2       Dim.3      Dim.4      Dim.5
## Competition 0.4011568 0.00739783 0.001062332 0.03658159 0.02357972

Esto se grafica de la siguiente forma.

fviz_pca_ind(res.pca_2, habillage = 13,
             addEllipses =TRUE, ellipse.type = "confidence",
             palette = "jco", repel = TRUE) 

Cápitulo 4: análisis de correspondencias en R

El análisis de correspondencias (AC) es una extensión del análisis de componentes principales adecuado para explorar las relaciones entre variables cualitativas (o datos categóricos). Al igual que el análisis de componentes principales, proporciona una solución para resumir y visualizar conjuntos de datos en gráficos bidimensionales.

Para empezar se instalan los paquetes y liberías correspondientes.

#install.packages(c("FactoMineR", "factoextra"))
library("FactoMineR")
library("factoextra")

También, se cargan los datos necesarios para el análisis.

data(housetasks)
head(housetasks)
##            Wife Alternating Husband Jointly
## Laundry     156          14       2       4
## Main_meal   124          20       5       4
## Dinner       77          11       7      13
## Breakfeast   82          36      15       7
## Tidying      53          11       1      57
## Dishes       32          24       4      53

La tabla de contingencia anterior no es muy grande. Por lo tanto, es fácil inspeccionar e interpretar visualmente los perfiles de fila y columna:

library("gplots")
# 1. convert the data as a table
dt <- as.table(as.matrix(housetasks))
# 2. Graph
balloonplot(t(dt), main ="housetasks", xlab ="", ylab="",
            label = FALSE, show.margins = FALSE)

Para una tabla de contingencia pequeña, puede usar la prueba Chi-cuadrado para evaluar si existe una dependencia significativa entre las categorías de fila y columna:

chisq <- chisq.test(housetasks)
chisq
## 
##  Pearson's Chi-squared test
## 
## data:  housetasks
## X-squared = 1944.5, df = 36, p-value < 2.2e-16

Se puede utilizar la función CA()[paquete FactoMiner]. Un formato simplificado es:

library("FactoMineR")
res.ca <- CA(housetasks, graph = FALSE)

print(res.ca)
## **Results of the Correspondence Analysis (CA)**
## The row variable has  13  categories; the column variable has 4 categories
## The chi square of independence between the two variables is equal to 1944.456 (p-value =  0 ).
## *The results are available in the following objects:
## 
##    name              description                   
## 1  "$eig"            "eigenvalues"                 
## 2  "$col"            "results for the columns"     
## 3  "$col$coord"      "coord. for the columns"      
## 4  "$col$cos2"       "cos2 for the columns"        
## 5  "$col$contrib"    "contributions of the columns"
## 6  "$row"            "results for the rows"        
## 7  "$row$coord"      "coord. for the rows"         
## 8  "$row$cos2"       "cos2 for the rows"           
## 9  "$row$contrib"    "contributions of the rows"   
## 10 "$call"           "summary called parameters"   
## 11 "$call$marge.col" "weights of the columns"      
## 12 "$call$marge.row" "weights of the rows"

Para interpretar el análisis de correspondencias, el primer paso es evaluar si existe una dependencia significativa entre las filas y las columnas.

Un método riguroso es utilizar el para examinar la asociación entre las variables de fila y columna. Esto aparece en la parte superior del informe generado por una función. Una estadística chi-cuadrado alta significa un fuerte vínculo entre las variables de fila y columna.chi-square statisticsummary(res.ca)print(res.ca)

# Chi-square statistics
chi2 <- 1944.456
# Degree of freedom
df <- (nrow(housetasks) - 1) * (ncol(housetasks) - 1)
# P-value
pval <- pchisq(chi2, df = df, lower.tail = FALSE)
pval
## [1] 0

Los valores propios y la proporción de varianzas retenidas por los diferentes ejes se pueden extraer utilizando una función. Los valores propios son grandes para el primer eje y pequeños para el eje siguiente por lo que se emplea la función .get_eigenvalue()

library("factoextra")
eig.val <- get_eigenvalue(res.ca)
eig.val
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  0.5428893         48.69222                    48.69222
## Dim.2  0.4450028         39.91269                    88.60491
## Dim.3  0.1270484         11.39509                   100.00000

Se realiza un diagrama para la interpretación.

fviz_screeplot(res.ca, addlabels = TRUE, ylim = c(0, 50))

También es posible calcular un valor propio promedio por encima del cual el eje debe mantenerse en la solución.

El código R a continuación, dibuja el diagrama de pedregal con una línea discontinua roja que especifica el valor propio promedio:

fviz_screeplot(res.ca) +
 geom_hline(yintercept=33.33, linetype=2, color="red")

La función fviz_ca_biplot() se puede utilizar para dibujar el biplot de las variables de filas y columnas.

# repel= TRUE to avoid text overlapping (slow if many point)
fviz_ca_biplot(res.ca, repel = TRUE)

La distancia entre cualquier punto de fila o punto de columna da una medida de su similitud (o disimilitud). Los puntos de fila con un perfil similar se cierran en el mapa de factores. Lo mismo ocurre con los puntos de columna.

La función get_ca_row() se utiliza para extraer los resultados de las variables de fila. Esta función devuelve una lista que contiene las coordenadas, el cos2, la contribución y la inercia de las variables de fila:

row <- get_ca_row(res.ca)
row
## Correspondence Analysis - Results for rows
##  ===================================================
##   Name       Description                
## 1 "$coord"   "Coordinates for the rows" 
## 2 "$cos2"    "Cos2 for the rows"        
## 3 "$contrib" "contributions of the rows"
## 4 "$inertia" "Inertia of the rows"

Se puede acceder a los diferentes componentes de la siguiente manera:

# Coordinates
head(row$coord)
##                 Dim 1      Dim 2       Dim 3
## Laundry    -0.9918368  0.4953220 -0.31672897
## Main_meal  -0.8755855  0.4901092 -0.16406487
## Dinner     -0.6925740  0.3081043 -0.20741377
## Breakfeast -0.5086002  0.4528038  0.22040453
## Tidying    -0.3938084 -0.4343444 -0.09421375
## Dishes     -0.1889641 -0.4419662  0.26694926
# Cos2: quality on the factore map
head(row$cos2)
##                Dim 1     Dim 2      Dim 3
## Laundry    0.7399874 0.1845521 0.07546047
## Main_meal  0.7416028 0.2323593 0.02603787
## Dinner     0.7766401 0.1537032 0.06965666
## Breakfeast 0.5049433 0.4002300 0.09482670
## Tidying    0.4398124 0.5350151 0.02517249
## Dishes     0.1181178 0.6461525 0.23572969
# Contributions to the principal components
head(row$contrib)
##                 Dim 1    Dim 2    Dim 3
## Laundry    18.2867003 5.563891 7.968424
## Main_meal  12.3888433 4.735523 1.858689
## Dinner      5.4713982 1.321022 2.096926
## Breakfeast  3.8249284 3.698613 3.069399
## Tidying     1.9983518 2.965644 0.488734
## Dishes      0.4261663 2.844117 3.634294

El siguiente código R muestra las coordenadas de cada punto de fila en cada dimensión (1, 2 y 3):

head(row$coord)
##                 Dim 1      Dim 2       Dim 3
## Laundry    -0.9918368  0.4953220 -0.31672897
## Main_meal  -0.8755855  0.4901092 -0.16406487
## Dinner     -0.6925740  0.3081043 -0.20741377
## Breakfeast -0.5086002  0.4528038  0.22040453
## Tidying    -0.3938084 -0.4343444 -0.09421375
## Dishes     -0.1889641 -0.4419662  0.26694926

Todo esto se gráfica y obtenemos los siguiente

fviz_ca_row(res.ca, repel = TRUE)

Es posible cambiar el color y la forma de los puntos de fila utilizando los argumentos y de la siguiente manera.

fviz_ca_row(res.ca, col.row="steelblue", shape.row = 15)

El cos2 mide el grado de asociación entre filas/columnas y un eje particular. El cos2 de los puntos de fila se puede extraer de la siguiente manera:

head(row$cos2, 4)
##                Dim 1     Dim 2      Dim 3
## Laundry    0.7399874 0.1845521 0.07546047
## Main_meal  0.7416028 0.2323593 0.02603787
## Dinner     0.7766401 0.1537032 0.06965666
## Breakfeast 0.5049433 0.4002300 0.09482670
# Color by cos2 values: quality on the factor map
fviz_ca_row(res.ca, col.row = "cos2",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), 
             repel = TRUE)

También es posible cambiar la transparencia de los puntos de fila de acuerdo con sus valores cos2 utilizando la opción

# Change the transparency by cos2 values
fviz_ca_row(res.ca, alpha.row="cos2")

Puede visualizar el cos2 de los puntos de fila en todas las dimensiones utilizando el paquete corrplot:

library("corrplot")
corrplot(row$cos2, is.corr=FALSE)

También es posible crear un gráfico de barras de filas cos2

# Cos2 of rows on Dim.1 and Dim.2
fviz_cos2(res.ca, choice = "row", axes = 1:2)

La contribución de las filas (en %) a la definición de las dimensiones se puede extraer de la siguiente manera:

head(row$contrib)
##                 Dim 1    Dim 2    Dim 3
## Laundry    18.2867003 5.563891 7.968424
## Main_meal  12.3888433 4.735523 1.858689
## Dinner      5.4713982 1.321022 2.096926
## Breakfeast  3.8249284 3.698613 3.069399
## Tidying     1.9983518 2.965644 0.488734
## Dishes      0.4261663 2.844117 3.634294

Esto se gráfica para su práctica interpretación.

library("corrplot")
corrplot(row$contrib, is.corr=FALSE) 

La función fviz_contrib se puede utilizar para dibujar un gráfico de barras de contribuciones de filas. Si los datos contienen muchas filas, puede decidir mostrar solo las filas contribuyentes superiores. El código R a continuación muestra las 10 filas superiores que contribuyen a las dimensiones:

# Contributions of rows to dimension 1
fviz_contrib(res.ca, choice = "row", axes = 1, top = 10)

# Contributions of rows to dimension 2
fviz_contrib(res.ca, choice = "row", axes = 2, top = 10)

La contribución total a las dimensiones 1 y 2 puede obtenerse de la siguiente manera:

# Total contribution to dimension 1 and 2
fviz_contrib(res.ca, choice = "row", axes = 1:2, top = 10)

Los puntos de fila más importantes (o contribuyentes) se pueden resaltar en el gráfico de dispersión de la siguiente manera:

fviz_ca_row(res.ca, col.row = "contrib",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), 
             repel = TRUE)

Se controla la transparencia de los puntos así:

# Change the transparency by contrib values
fviz_ca_row(res.ca, alpha.row="contrib",
             repel = TRUE)

La función get_ca_col() se utiliza para extraer los resultados de las variables de columna. Esta función devuelve una lista que contiene las coordenadas, el cos2, la contribución y la inercia de las variables de columnas:

col <- get_ca_col(res.ca)
col
## Correspondence Analysis - Results for columns
##  ===================================================
##   Name       Description                   
## 1 "$coord"   "Coordinates for the columns" 
## 2 "$cos2"    "Cos2 for the columns"        
## 3 "$contrib" "contributions of the columns"
## 4 "$inertia" "Inertia of the columns"

Para obtener acceso a los diferentes componentes, se empleea lo siguiente:

# Coordinates of column points
head(col$coord)
##                   Dim 1      Dim 2       Dim 3
## Wife        -0.83762154  0.3652207 -0.19991139
## Alternating -0.06218462  0.2915938  0.84858939
## Husband      1.16091847  0.6019199 -0.18885924
## Jointly      0.14942609 -1.0265791 -0.04644302
# Quality of representation
head(col$cos2)
##                   Dim 1     Dim 2       Dim 3
## Wife        0.801875947 0.1524482 0.045675847
## Alternating 0.004779897 0.1051016 0.890118521
## Husband     0.772026244 0.2075420 0.020431728
## Jointly     0.020705858 0.9772939 0.002000236
# Contributions
head(col$contrib)
##                 Dim 1     Dim 2      Dim 3
## Wife        44.462018 10.312237 10.8220753
## Alternating  0.103739  2.782794 82.5492464
## Husband     54.233879 17.786612  6.1331792
## Jointly      1.200364 69.118357  0.4954991

El se utiliza para producir el gráfico de puntos de columna. Para crear una gráfica simple, escriba lo siguiente:

fviz_ca_col(res.ca)

Al igual que los puntos de fila, también es posible colorear los puntos de columna por sus valores cos2:

fviz_ca_col(res.ca, col.col = "cos2", 
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE)

El siguiente código R crea un gráfico de barras de columnas cos2:

fviz_cos2(res.ca, choice = "col", axes = 1:2)

Para visualizar la contribución de las filas a las dos primeras dimensiones, escriba lo siguiente:

fviz_contrib(res.ca, choice = "col", axes = 1:2)

Como se mencionó anteriormente, la gráfica estándar del análisis de correspondencias es una bigráfica simétrica en la que tanto las filas (puntos azules) como las columnas (triángulos rojos) se representan en el mismo espacio utilizando el . Estas coordenadas representan los perfiles de fila y columna. En este caso, solo se puede interpretar realmente la distancia entre puntos de fila o la distancia entre puntos de columna

fviz_ca_biplot(res.ca, repel = TRUE)

Para hacer un bigráfico asimétrico, los puntos de filas (o columnas) se trazan a partir de las coordenadas estándar (S) y los perfiles de las columnas (o las filas) se trazan a partir de las coordenadas principales (P).

Para un eje dado, las coordenadas estándar y principal están relacionadas de la siguiente manera:

fviz_ca_biplot(res.ca, 
               map ="rowprincipal", arrow = c(TRUE, TRUE),
               repel = TRUE)

En el siguiente caso las columnas están en coordenadas principales y las filas en coordenadas estándar multiplicadas por la raíz cuadrada de la masa. Para una fila dada, el cuadrado de la nueva coordenada en un eje i es exactamente la contribución de esta fila a la inercia del eje i.

fviz_ca_biplot(res.ca, map ="colgreen", arrow = c(TRUE, FALSE),
               repel = TRUE)

Para identificar fácilmente los puntos de fila y columna que están más asociados con las dimensiones principales. Las variables de fila/columna se ordenan por sus coordenadas en la salida.dimdesc()dimdesc()

# Dimension description
res.desc <- dimdesc(res.ca, axes = c(1,2))

Descripción de la dimensión 1:

# Description of dimension 1 by row points
head(res.desc[[1]]$row, 4)
##                 coord
## Laundry    -0.9918368
## Main_meal  -0.8755855
## Dinner     -0.6925740
## Breakfeast -0.5086002
# Description of dimension 1 by column points
head(res.desc[[1]]$col, 4)
##                   coord
## Wife        -0.83762154
## Alternating -0.06218462
## Jointly      0.14942609
## Husband      1.16091847

Descripción de la dimensión 2:

# Description of dimension 2 by row points
res.desc[[2]]$row
##                 coord
## Holidays   -1.4350066
## Finances   -0.6178684
## Insurance  -0.4737832
## Dishes     -0.4419662
## Tidying    -0.4343444
## Shopping   -0.4033171
## Official    0.2536132
## Dinner      0.3081043
## Breakfeast  0.4528038
## Main_meal   0.4901092
## Laundry     0.4953220
## Driving     0.6534143
## Repairs     0.8642647
# Description of dimension 1 by column points
res.desc[[2]]$col
##                  coord
## Jointly     -1.0265791
## Alternating  0.2915938
## Wife         0.3652207
## Husband      0.6019199

Se usa el el conjunto de datos [en el paquete FactoMineR]. Contiene 18 filas y 8 columnas:

data(children)
head(children)
##               unqualified cep bepc high_school_diploma university thirty fifty
## money                  51  64   32                  29         17     59    66
## future                 53  90   78                  75         22    115   117
## unemployment           71 111   50                  40         11     79    88
## circumstances           1   7    5                   5          4      9     8
## hard                    7  11    4                   3          2      2    17
## economic                7  13   12                  11         11     18    19
##               more_fifty
## money                 70
## future                86
## unemployment         177
## circumstances          5
## hard                  18
## economic              17

Como se mencionó anteriormente, las filas y columnas suplementarias no se utilizan para la definición de las dimensiones principales. Sus coordenadas se predicen utilizando solo la información proporcionada por la CA realizada en filas/columnas activas.

res.ca <- CA (children, row.sup = 15:18, col.sup = 6:8,
              graph = FALSE)
fviz_ca_biplot(res.ca, repel = TRUE)

También es posible ocultar filas y columnas suplementarias usando el argumento :invisible

fviz_ca_biplot(res.ca, repel = TRUE,
               invisible = c("row.sup", "col.sup"))

Resultados previstos (coordenadas y cos2) para las filas suplementarias:

res.ca$row.sup
## $coord
##                  Dim 1     Dim 2      Dim 3      Dim 4
## comfort      0.2096705 0.7031677 0.07111168  0.3071354
## disagreement 0.1462777 0.1190106 0.17108916 -0.3132169
## world        0.5233045 0.1429707 0.08399269 -0.1063597
## to_live      0.3083067 0.5020193 0.52093397  0.2557357
## 
## $cos2
##                   Dim 1      Dim 2       Dim 3      Dim 4
## comfort      0.06892759 0.77524032 0.007928672 0.14790342
## disagreement 0.13132177 0.08692632 0.179649183 0.60210272
## world        0.87587685 0.06537746 0.022564054 0.03618163
## to_live      0.13899699 0.36853645 0.396830367 0.09563620

Gráfico de puntos de fila activos y suplementarios:

fviz_ca_row(res.ca, repel = TRUE) 

Resultados previstos (coordenadas y cos2) para las columnas suplementarias:

res.ca$col.sup
## $coord
##                  Dim 1       Dim 2       Dim 3       Dim 4
## thirty      0.10541339 -0.05969594 -0.10322613  0.06977996
## fifty      -0.01706444  0.04907657 -0.01568923 -0.01306117
## more_fifty -0.17706810 -0.04813788  0.10077299 -0.08517528
## 
## $cos2
##                Dim 1      Dim 2       Dim 3       Dim 4
## thirty     0.1375601 0.04411543 0.131910759 0.060278490
## fifty      0.0108695 0.08990298 0.009188167 0.006367804
## more_fifty 0.2860989 0.02114509 0.092666735 0.066200714

Gráfico de puntos de columna activos y suplementarios:

fviz_ca_col(res.ca, repel = TRUE) 

Los resultados pueden ser filtrados con el siguiente procedimiento en las líneas de código a continuación.

# Visualize rows with cos2 >= 0.8
fviz_ca_row(res.ca, select.row = list(cos2 = 0.8))

# Top 5 active rows and 5 suppl. rows with the highest cos2
fviz_ca_row(res.ca, select.row = list(cos2 = 5))

# Select by names
name <- list(name = c("employment", "fear", "future"))
fviz_ca_row(res.ca, select.row = name)

# Top 5 contributing rows and columns
fviz_ca_biplot(res.ca, select.row = list(contrib = 5), 
               select.col = list(contrib = 5)) +
  theme_minimal()

Capítulo 5: Análisis de corrsepondencia múltiple

El análisis de correspondencia múltiple (MCA) es una extensión del análisis de correspondencia simple para resumir y visualizar una tabla de datos que contiene más de dos variables categóricas. También puede verse como una generalización del análisis de componentes principales cuando las variables a analizar son categóricas en lugar de cuantitativas.

library("FactoMineR")
library("factoextra")
#se cargan los datos 
data(poison)
head(poison[, 1:7], 3)
##   Age Time   Sick Sex   Nausea Vomiting Abdominals
## 1   9   22 Sick_y   F Nausea_y  Vomit_n     Abdo_y
## 2   5    0 Sick_n   F Nausea_n  Vomit_n     Abdo_n
## 3   6   16 Sick_y   F Nausea_n  Vomit_y     Abdo_y

Se crea un Subconjunto solo de individuos activos y variables para análisis de correspondencia múltiple:

poison.active <- poison[1:55, 5:15]
head(poison.active[, 1:6], 3)
##     Nausea Vomiting Abdominals   Fever   Diarrhae   Potato
## 1 Nausea_y  Vomit_n     Abdo_y Fever_y Diarrhea_y Potato_y
## 2 Nausea_n  Vomit_n     Abdo_n Fever_n Diarrhea_n Potato_y
## 3 Nausea_n  Vomit_y     Abdo_y Fever_y Diarrhea_y Potato_y
# Summary of the 4 first variables
summary(poison.active)[, 1:4]
##       Nausea      Vomiting   Abdominals     Fever   
##  Nausea_n:43   Vomit_n:33   Abdo_n:18   Fever_n:20  
##  Nausea_y:12   Vomit_y:22   Abdo_y:37   Fever_y:35

Las funciones de resumen () devuelven el tamaño de cada categoría de variable. También es posible trazar la frecuencia de las categorías de variables. El código R a continuación, traza las primeras 4 columnas:

for (i in 1:4) {
plot(poison.active[,i], main=colnames(poison.active)[i],
ylab = "Count", col="steelblue", las = 2)
}

En el código R a continuación, el MCA se realiza solo en el activo individuos/variables:

res.mca <- MCA(poison.active, graph = FALSE)
print(res.mca)
## **Results of the Multiple Correspondence Analysis (MCA)**
## The analysis was performed on 55 individuals, described by 11 variables
## *The results are available in the following objects:
## 
##    name              description                       
## 1  "$eig"            "eigenvalues"                     
## 2  "$var"            "results for the variables"       
## 3  "$var$coord"      "coord. of the categories"        
## 4  "$var$cos2"       "cos2 for the categories"         
## 5  "$var$contrib"    "contributions of the categories" 
## 6  "$var$v.test"     "v-test for the categories"       
## 7  "$var$eta2"       "coord. of variables"             
## 8  "$ind"            "results for the individuals"     
## 9  "$ind$coord"      "coord. for the individuals"      
## 10 "$ind$cos2"       "cos2 for the individuals"        
## 11 "$ind$contrib"    "contributions of the individuals"
## 12 "$call"           "intermediate results"            
## 13 "$call$marge.col" "weights of columns"              
## 14 "$call$marge.li"  "weights of rows"

La visualización e interpretación de los datos se presenta a continuación.

La proporción de varianzas retenidas por las diferentes dimensiones (ejes) se puede extraer usando la función get_eigenvalue() [paquete factoextra] de la siguiente manera:

library("factoextra")
eig.val <- get_eigenvalue(res.mca)
head(eig.val)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1 0.33523140        33.523140                    33.52314
## Dim.2 0.12913979        12.913979                    46.43712
## Dim.3 0.10734849        10.734849                    57.17197
## Dim.4 0.09587950         9.587950                    66.75992
## Dim.5 0.07883277         7.883277                    74.64319
## Dim.6 0.07108981         7.108981                    81.75217

Estos datos se grafican de la siguiente forma.

fviz_screeplot(res.mca, addlabels = TRUE, ylim = c(0, 45))

La función fviz_mca_biplot() [paquete factoextra] se usa para dibujar el biplot de individuos y categorías de variables:

fviz_mca_biplot(res.mca,
repel = TRUE, # Avoid text overlapping (slow if many point)
ggtheme = theme_minimal())

La función get_mca_var() [de facto extra] se utiliza para extraer los resultados de las categorías de variables. Esta función devuelve una lista que contiene las coordenadas, el cos2 y la contribución de las categorías de variables:

var <- get_mca_var(res.mca)
var
## Multiple Correspondence Analysis Results for variables
##  ===================================================
##   Name       Description                  
## 1 "$coord"   "Coordinates for categories" 
## 2 "$cos2"    "Cos2 for categories"        
## 3 "$contrib" "contributions of categories"

Se puede acceder a los diferentes componentes de la siguiente manera:

# Coordinates
head(var$coord)
##               Dim 1       Dim 2        Dim 3       Dim 4       Dim 5
## Nausea_n  0.2673909  0.12139029 -0.265583253  0.03376130  0.07370500
## Nausea_y -0.9581506 -0.43498187  0.951673323 -0.12097801 -0.26410958
## Vomit_n   0.4790279 -0.40919465  0.084492799  0.27361142  0.05245250
## Vomit_y  -0.7185419  0.61379197 -0.126739198 -0.41041713 -0.07867876
## Abdo_n    1.3180221 -0.03574501 -0.005094243 -0.15360951 -0.06986987
## Abdo_y   -0.6411999  0.01738946  0.002478280  0.07472895  0.03399075
# Cos2: quality on the factore map
head(var$cos2)
##              Dim 1        Dim 2        Dim 3       Dim 4       Dim 5
## Nausea_n 0.2562007 0.0528025759 2.527485e-01 0.004084375 0.019466197
## Nausea_y 0.2562007 0.0528025759 2.527485e-01 0.004084375 0.019466197
## Vomit_n  0.3442016 0.2511603912 1.070855e-02 0.112294813 0.004126898
## Vomit_y  0.3442016 0.2511603912 1.070855e-02 0.112294813 0.004126898
## Abdo_n   0.8451157 0.0006215864 1.262496e-05 0.011479077 0.002374929
## Abdo_y   0.8451157 0.0006215864 1.262496e-05 0.011479077 0.002374929
# Contributions to the principal components
head(var$contrib)
##              Dim 1       Dim 2        Dim 3      Dim 4      Dim 5
## Nausea_n  1.515869  0.81100008 4.670018e+00 0.08449397 0.48977906
## Nausea_y  5.431862  2.90608363 1.673423e+01 0.30277007 1.75504164
## Vomit_n   3.733667  7.07226253 3.627455e-01 4.25893721 0.19036376
## Vomit_y   5.600500 10.60839380 5.441183e-01 6.38840581 0.28554563
## Abdo_n   15.417637  0.02943661 7.192511e-04 0.73219636 0.18424268
## Abdo_y    7.500472  0.01432051 3.499060e-04 0.35620363 0.08963157

Para visualizar la correlación entre las variables y las dimensiones principales de MCA se plantea lo siguiente.

fviz_mca_var(res.mca, choice = "mca.cor",
             repel = TRUE, # Avoid text overlapping (slow)
             ggtheme = theme_minimal())

El siguiente código R muestra las coordenadas de cada categoría de variable en cada dimensión (1, 2 y 3)

head(round(var$coord, 2), 4)
##          Dim 1 Dim 2 Dim 3 Dim 4 Dim 5
## Nausea_n  0.27  0.12 -0.27  0.03  0.07
## Nausea_y -0.96 -0.43  0.95 -0.12 -0.26
## Vomit_n   0.48 -0.41  0.08  0.27  0.05
## Vomit_y  -0.72  0.61 -0.13 -0.41 -0.08

Use la función fviz_mca_var() [de factoextra] para visualizar solo categorías de variables:

fviz_mca_var(res.mca,
repel = TRUE, # Avoid text overlapping (slow)
ggtheme = theme_minimal())

Es posible cambiar el color y la forma de los puntos variables usando los argumentos col.var y shape.var de la siguiente manera.

fviz_mca_var(res.mca, col.var="black", shape.var = 15,
repel = TRUE)

Las dos dimensiones 1 y 2 son suficientes para retener el 46% de la inercia total (variación) contenida en los datos. No todos los puntos se muestran igual de bien en las dos dimensiones. La calidad de la representación se denomina coseno al cuadrado (cos2), que mide el grado de asociación entre las categorías de variables y un eje particular.

En R es posible conocer estos valores de la siguiente forma.

head(var$cos2, 4)
##              Dim 1      Dim 2      Dim 3       Dim 4       Dim 5
## Nausea_n 0.2562007 0.05280258 0.25274850 0.004084375 0.019466197
## Nausea_y 0.2562007 0.05280258 0.25274850 0.004084375 0.019466197
## Vomit_n  0.3442016 0.25116039 0.01070855 0.112294813 0.004126898
## Vomit_y  0.3442016 0.25116039 0.01070855 0.112294813 0.004126898

Esto permite la realización de la siguiente gráfica.

# Color by cos2 values: quality on the factor map
fviz_mca_var(res.mca, col.var = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE, # Avoid text overlapping
ggtheme = theme_minimal())

# Change the transparency by cos2 values
fviz_mca_var(res.mca, alpha.var="cos2",
repel = TRUE,
ggtheme = theme_minimal())

Puede visualizar el cos2 de las categorías de fila en todas las dimensiones usando el paquete corrplot:

library("corrplot")
corrplot(var$cos2, is.corr=FALSE)

# Cos2 of variable categories on Dim.1 and Dim.2
fviz_cos2(res.mca, choice = "var", axes = 1:2)

La contribución de las categorías de variables (en %) a la definición de las dimensiones se puede extraer de la siguiente manera

head(round(var$contrib,2), 4)
##          Dim 1 Dim 2 Dim 3 Dim 4 Dim 5
## Nausea_n  1.52  0.81  4.67  0.08  0.49
## Nausea_y  5.43  2.91 16.73  0.30  1.76
## Vomit_n   3.73  7.07  0.36  4.26  0.19
## Vomit_y   5.60 10.61  0.54  6.39  0.29
# Contributions of rows to dimension 1
fviz_contrib(res.mca, choice = "var", axes = 1, top = 15)

# Contributions of rows to dimension 2
fviz_contrib(res.mca, choice = "var", axes = 2, top = 15)

# Total contribution to dimension 1 and 2
fviz_contrib(res.mca, choice = "var", axes = 1:2, top = 15)

Las categorías de variables más importantes (o contribuyentes) se pueden resaltar en el diagrama de dispersión de la siguiente manera:

fviz_mca_var(res.mca, col.var = "contrib",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE, # avoid text overlapping (slow)
             ggtheme = theme_minimal()
)

También es posible controlar la transparencia de las categorías de variables según sus valores de contribución utilizando la opción alpha.var = “contrib”.

# Change the transparency by contrib values
fviz_mca_var(res.mca, alpha.var="contrib",
repel = TRUE, ggtheme = theme_minimal())

La función get_mca_ind()[de factoextra] se utiliza para extraer los resultados de las personas. Esta función devuelve una lista que contiene las coordenadas, el cos2 y las contribuciones de los individuos.

ind <- get_mca_ind(res.mca)
ind
## Multiple Correspondence Analysis Results for individuals
##  ===================================================
##   Name       Description                       
## 1 "$coord"   "Coordinates for the individuals" 
## 2 "$cos2"    "Cos2 for the individuals"        
## 3 "$contrib" "contributions of the individuals"

Se hace lo siguiente para obtener acceso a los diferentes componentes.

# Coordinates of column points
head(ind$coord)
##        Dim 1       Dim 2       Dim 3       Dim 4       Dim 5
## 1 -0.4525811 -0.26415072  0.17151614  0.01369348 -0.11696806
## 2  0.8361700 -0.03193457 -0.07208249 -0.08550351  0.51978710
## 3 -0.4481892  0.13538726 -0.22484048 -0.14170168 -0.05004753
## 4  0.8803694 -0.08536230 -0.02052044 -0.07275873 -0.22935022
## 5 -0.4481892  0.13538726 -0.22484048 -0.14170168 -0.05004753
## 6 -0.3594324 -0.43604390 -1.20932223  1.72464616  0.04348157
# Quality of representation
head(ind$cos2)
##        Dim 1        Dim 2        Dim 3        Dim 4        Dim 5
## 1 0.34652591 0.1180447167 0.0497683175 0.0003172275 0.0231460846
## 2 0.55589562 0.0008108236 0.0041310808 0.0058126211 0.2148103098
## 3 0.54813888 0.0500176790 0.1379484860 0.0547920948 0.0068349171
## 4 0.74773962 0.0070299584 0.0004062504 0.0051072923 0.0507479873
## 5 0.54813888 0.0500176790 0.1379484860 0.0547920948 0.0068349171
## 6 0.02485357 0.0365775483 0.2813443706 0.5722083217 0.0003637178
# Contributions
head(ind$contrib)
##      Dim 1      Dim 2        Dim 3        Dim 4      Dim 5
## 1 1.110927 0.98238297  0.498254685  0.003555817 0.31554778
## 2 3.792117 0.01435818  0.088003703  0.138637089 6.23134138
## 3 1.089470 0.25806722  0.856229950  0.380768961 0.05776914
## 4 4.203611 0.10259105  0.007132055  0.100387990 1.21319013
## 5 1.089470 0.25806722  0.856229950  0.380768961 0.05776914
## 6 0.700692 2.67693398 24.769968729 56.404214518 0.04360547

La función fviz_mca_ind() [de facto extra] se usa para visualizar solo individuos. También es posible colorear a los individuos por sus valores de cos2. Se realiza de la siguiente forma.

fviz_mca_ind(res.mca, col.ind = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE, # Avoid text overlapping (slow if many points)
ggtheme = theme_minimal())

El siguiente código R crea un gráfico de barras de individuos cos2 y contribuciones.

# Cos2 of individuals
fviz_cos2(res.mca, choice = "ind", axes = 1:2, top = 20)

# Contribution of individuals to the dimensions
fviz_contrib(res.mca, choice = "ind", axes = 1:2, top = 20)

En R también es posible colorear individuos por grupos.

fviz_mca_ind(res.mca,
label = "none", # hide individual labels
habillage = "Vomiting", # color by groups
palette = c("#00AFBB", "#E7B800"),
addEllipses = TRUE, ellipse.type = "confidence",
ggtheme = theme_minimal())

# habillage = index of the column to be used as grouping variable
fviz_mca_ind(res.mca, habillage = 2, addEllipses = TRUE)

fviz_mca_ind(res.mca, habillage = poison$Vomiting, addEllipses = TRUE)

Si se busca colorear individuos usando múltiples variables categóricas al mismo tiempo se emplea la función fviz_ellipses().

fviz_ellipses(res.mca, c("Vomiting", "Fever"),
geom = "point")
## Warning: `gather_()` was deprecated in tidyr 1.2.0.
## ℹ Please use `gather()` instead.
## ℹ The deprecated feature was likely used in the factoextra package.
##   Please report the issue at <https://github.com/kassambara/factoextra/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

También se pueden especificar índices de variables categóricas

fviz_ellipses(res.mca, 1:4, geom = "point")

La función dimdesc() [en FactoMineR] se puede utilizar para identificar las variables más correlacionadas con una dimensión dada.

res.desc <- dimdesc(res.mca, axes = c(1,2))
# Description of dimension 1
res.desc[[1]]
## 
## Link between the variable and the categorical variable (1-way anova)
## =============================================
##                   R2      p.value
## Abdominals 0.8451157 4.055640e-23
## Diarrhae   0.7994680 3.910776e-20
## Fever      0.7846788 2.600566e-19
## Mayo       0.3829749 4.756234e-07
## Vomiting   0.3442016 2.510738e-06
## Nausea     0.2562007 8.062777e-05
## Cheese     0.1944181 7.534834e-04
## 
## Link between variable and the categories of the categorical variables
## ================================================================
##                       Estimate      p.value
## Abdominals=Abdo_n    0.5671866 4.055640e-23
## Diarrhae=Diarrhea_n  0.5380920 3.910776e-20
## Fever=Fever_n        0.5330918 2.600566e-19
## Mayo=Mayo_n          0.4644981 4.756234e-07
## Vomiting=Vomit_n     0.3466915 2.510738e-06
## Nausea=Nausea_n      0.3547892 8.062777e-05
## Cheese=Cheese_n      0.3830043 7.534834e-04
## Cheese=Cheese_y     -0.3830043 7.534834e-04
## Nausea=Nausea_y     -0.3547892 8.062777e-05
## Vomiting=Vomit_y    -0.3466915 2.510738e-06
## Mayo=Mayo_y         -0.4644981 4.756234e-07
## Fever=Fever_y       -0.5330918 2.600566e-19
## Diarrhae=Diarrhea_y -0.5380920 3.910776e-20
## Abdominals=Abdo_y   -0.5671866 4.055640e-23
# Description of dimension 2
res.desc[[2]]
## 
## Link between the variable and the categorical variable (1-way anova)
## =============================================
##                  R2      p.value
## Courgette 0.4464145 2.500166e-08
## Potato    0.3957543 2.690662e-07
## Vomiting  0.2511604 9.728027e-05
## Icecream  0.1409011 4.743927e-03
## 
## Link between variable and the categories of the categorical variables
## ================================================================
##                       Estimate      p.value
## Courgette=Courg_n    0.4176013 2.500166e-08
## Potato=Potato_y      0.4977523 2.690662e-07
## Vomiting=Vomit_y     0.1838104 9.728027e-05
## Icecream=Icecream_n  0.2597197 4.743927e-03
## Icecream=Icecream_y -0.2597197 4.743927e-03
## Vomiting=Vomit_n    -0.1838104 9.728027e-05
## Potato=Potato_n     -0.4977523 2.690662e-07
## Courgette=Courg_y   -0.4176013 2.500166e-08

Para hacer un biplot de individuos y categorías variables se escribe lo siguiente.

# Biplot of individuals and variable categories
fviz_mca_biplot(res.mca, repel = TRUE,
ggtheme = theme_minimal())

fviz_mca_var(res.mca, choice = "mca.cor",
repel = TRUE)

El siguiente código R traza categorías de variables cualitativas (variables activas y complementarias):

fviz_mca_var(res.mca, repel = TRUE,
ggtheme= theme_minimal())

fviz_mca_ind(res.mca,
label = "ind.sup", #Show the label of ind.sup only
ggtheme = theme_minimal())

Si tiene muchos individuos/categorías de variables, es posible visualizar solo algunos de ellos usando los argumentos select.ind y select.var

# Visualize variable categories with cos2 >= 0.4
fviz_mca_var(res.mca, select.var = list(cos2 = 0.4))

# Top 10 active variables with the highest cos2
fviz_mca_var(res.mca, select.var= list(cos2 = 10))

# Select by names
name <- list(name = c("Fever_n", "Abdo_y", "Diarrhea_n",
"Fever_Y", "Vomit_y", "Vomit_n"))
fviz_mca_var(res.mca, select.var = name)

# top 5 contributing individuals and variable categories
fviz_mca_biplot(res.mca, select.ind = list(contrib = 5),
select.var = list(contrib = 5),
ggtheme = theme_minimal())

Independientemente de las funciones que decida usar, en la lista anterior, el paquete factoextra puede manejar la salida.

fviz_eig(res.mca) # Scree plot

fviz_mca_biplot(res.mca) # Biplot of rows and columns

Capítulo 6: análisis factorial de datos mixtos en R

El análisis factorial de datos mixtos (FAMD) es un método componente principal dedicado a analizar un conjunto de datos que contiene variables cuantitativas y cualitativas. Permite analizar la similitud entre individuos teniendo en cuenta una mezcla de tipos de variables. Además, se puede explorar la asociación entre todas las variables, tanto cuantitativas como cualitativas.

Como en los anteriores cápitulos, en principio, también se cargan las librerías.

library("FactoMineR")
library("factoextra")

También, se cargan los datos correspondientes que se utilizaran posteriormente.

library("FactoMineR")
data(wine)
df <- wine[,c(1,2, 16, 22, 29, 28, 30,31)]
head(df[, 1:7], 4)
##           Label Soil Plante Acidity Harmony Intensity Overall.quality
## 2EL      Saumur Env1  2.000   2.107   3.143     2.857           3.393
## 1CHA     Saumur Env1  2.000   2.107   2.964     2.893           3.214
## 1FON Bourgueuil Env1  1.750   2.179   3.143     3.074           3.536
## 1VAU     Chinon Env2  2.304   3.179   2.038     2.462           2.464
str(df)
## 'data.frame':    21 obs. of  8 variables:
##  $ Label          : Factor w/ 3 levels "Saumur","Bourgueuil",..: 1 1 2 3 1 2 2 1 3 1 ...
##  $ Soil           : Factor w/ 4 levels "Reference","Env1",..: 2 2 2 3 1 1 1 2 2 3 ...
##  $ Plante         : num  2 2 1.75 2.3 1.76 ...
##  $ Acidity        : num  2.11 2.11 2.18 3.18 2.57 ...
##  $ Harmony        : num  3.14 2.96 3.14 2.04 3.64 ...
##  $ Intensity      : num  2.86 2.89 3.07 2.46 3.64 ...
##  $ Overall.quality: num  3.39 3.21 3.54 2.46 3.74 ...
##  $ Typical        : num  3.25 3.04 3.18 2.25 3.44 ...

Para computar el FAMD se realiza lo siguiente

library(FactoMineR)
res.famd <- FAMD(df, graph = FALSE)
print(res.famd)
## *The results are available in the following objects:
## 
##   name          description                             
## 1 "$eig"        "eigenvalues and inertia"               
## 2 "$var"        "Results for the variables"             
## 3 "$ind"        "results for the individuals"           
## 4 "$quali.var"  "Results for the qualitative variables" 
## 5 "$quanti.var" "Results for the quantitative variables"

La proporción de varianzas retenidas por las diferentes dimensiones (ejes) se puede extraer utilizando la función get_eigenvalue() [paquete factoextra] de la siguiente manera:

library("factoextra")
eig.val <- get_eigenvalue(res.famd)
head(eig.val) 
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  4.8315174        43.922886                    43.92289
## Dim.2  1.8568797        16.880724                    60.80361
## Dim.3  1.5824794        14.386176                    75.18979
## Dim.4  1.1491200        10.446546                    85.63633
## Dim.5  0.6518053         5.925503                    91.56183

La función fviz_eig() o fviz_screeplot() [paquete factoextra] se puede utilizar para dibujar el diagrama de pedregal (los porcentajes de inercia explicados por cada dimensión FAMD):

fviz_screeplot(res.famd)

La función fviz_eig() o fviz_screeplot() [paquete factoextra] se puede utilizar para dibujar el diagrama de pedregal (los porcentajes de inercia explicados por cada dimensión FAMD):

var <- get_famd_var(res.famd)
var
## FAMD results for variables 
##  ===================================================
##   Name       Description                      
## 1 "$coord"   "Coordinates"                    
## 2 "$cos2"    "Cos2, quality of representation"
## 3 "$contrib" "Contributions"

Se puede acceder a la diferencia entre estos datos de la siguiente forma.

# Coordinates of variables
head(var$coord)
##                     Dim.1       Dim.2       Dim.3       Dim.4        Dim.5
## Plante          0.7344160 0.060551966 0.105902048 0.004011299 0.0010340559
## Acidity         0.1732738 0.491118153 0.126394029 0.115376784 0.0045862935
## Harmony         0.8943968 0.023628146 0.040124469 0.003653813 0.0086624633
## Intensity       0.6991811 0.134639254 0.065382234 0.023214984 0.0064730431
## Overall.quality 0.9115699 0.005246728 0.009336677 0.005445276 0.0007961880
## Typical         0.7808611 0.027094327 0.001549791 0.083446627 0.0005912942
# Cos2: quality of representation on the factore map
head(var$cos2)
##                      Dim.1        Dim.2        Dim.3        Dim.4        Dim.5
## Plante          0.53936692 3.666541e-03 1.121524e-02 1.609052e-05 1.069272e-06
## Acidity         0.03002381 2.411970e-01 1.597545e-02 1.331180e-02 2.103409e-05
## Harmony         0.79994566 5.582893e-04 1.609973e-03 1.335035e-05 7.503827e-05
## Intensity       0.48885427 1.812773e-02 4.274836e-03 5.389355e-04 4.190029e-05
## Overall.quality 0.83095973 2.752815e-05 8.717353e-05 2.965103e-05 6.339153e-07
## Typical         0.60974400 7.341026e-04 2.401853e-06 6.963340e-03 3.496288e-07
# Contributions to the  dimensions
head(var$contrib)
##                     Dim.1      Dim.2      Dim.3      Dim.4      Dim.5
## Plante          15.200526  3.2609526 6.69215972  0.3490757 0.15864490
## Acidity          3.586323 26.4485720 7.98708850 10.0404466 0.70362936
## Harmony         18.511716  1.2724651 2.53554453  0.3179662 1.32899551
## Intensity       14.471254  7.2508336 4.13163258  2.0202401 0.99309457
## Overall.quality 18.867156  0.2825562 0.59000304  0.4738648 0.12215119
## Typical         16.161818  1.4591321 0.09793437  7.2617850 0.09071638

Estas variables se gráfican a continuación.

# Plot of variables
fviz_famd_var(res.famd, repel = TRUE)

# Contribution to the first dimension
fviz_contrib(res.famd, "var", axes = 1)

# Contribution to the second dimension
fviz_contrib(res.famd, "var", axes = 2)

Para extraer los resultados de las variables cuantitativas, se plantea lo siguiente:

quanti.var <- get_famd_var(res.famd, "quanti.var")
quanti.var 
## FAMD results for quantitative variables 
##  ===================================================
##   Name       Description                      
## 1 "$coord"   "Coordinates"                    
## 2 "$cos2"    "Cos2, quality of representation"
## 3 "$contrib" "Contributions"
fviz_famd_var(res.famd, "quanti.var", repel = TRUE,
              col.var = "black")

Las variables cuantitativas más contribuyentes se pueden resaltar en el diagrama de dispersión usando el argumento col.var = “contrib”. Esto produce un degradado de colores, que se puede personalizar utilizando el argumento gradient.cols.

fviz_famd_var(res.famd, "quanti.var", col.var = "contrib", 
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE)

Del mismo modo, puede resaltar variables cuantitativas utilizando sus valores cos2 que representan la calidad de la representación en el mapa factorial. Si una variable está bien representada por dos dimensiones, la suma del cos2 se cierra a uno. Para algunos de los elementos, es posible que se requieran más de 2 dimensiones para representar perfectamente los datos.

# Color by cos2 values: quality on the factor map
fviz_famd_var(res.famd, "quanti.var", col.var = "cos2",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), 
             repel = TRUE)

Al igual que las variables cuantitativas, los resultados de las variables cualitativas se pueden extraer de la siguiente manera:

quali.var <- get_famd_var(res.famd, "quali.var")
quali.var 
## FAMD results for qualitative variable categories 
##  ===================================================
##   Name       Description                      
## 1 "$coord"   "Coordinates"                    
## 2 "$cos2"    "Cos2, quality of representation"
## 3 "$contrib" "Contributions"

Esto se grafica a continuación.

fviz_famd_var(res.famd, "quali.var", col.var = "contrib", 
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07")
             )

Si se desean hacer gráficos individuales se realiza lo siguiente.

ind <- get_famd_ind(res.famd)
ind
## FAMD results for individuals 
##  ===================================================
##   Name       Description                      
## 1 "$coord"   "Coordinates"                    
## 2 "$cos2"    "Cos2, quality of representation"
## 3 "$contrib" "Contributions"

Para trazar individuos, use la función fviz_mfa_ind() [in factoextra]. De forma predeterminada, los individuos están coloreados en azul. Sin embargo, al igual que las variables, también es posible colorear a los individuos por sus valores de cos2 y contribución:

fviz_famd_ind(res.famd, col.ind = "cos2", 
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE)

Es posible colorear a los individuos utilizando cualquiera de las variables cualitativas en la tabla de datos inicial. Para ello, se utiliza el argumento habillage en la función fviz_famd_ind().

fviz_mfa_ind(res.famd, 
             habillage = "Label", # color by groups 
             palette = c("#00AFBB", "#E7B800", "#FC4E07"),
             addEllipses = TRUE, ellipse.type = "confidence", 
             repel = TRUE # Avoid text overlapping
             ) 

fviz_ellipses(res.famd, c("Label", "Soil"), repel = TRUE)

Una forma alternativa sería la siguiente.

fviz_ellipses(res.famd, 1:2, geom = "point")

Capítulo 7: análisis de factores múltiples

El análisis factorial múltiple (MFA) es un método de análisis de datos multivariante para resumir y visualizar una tabla de datos compleja en la que los individuos se describen mediante varios conjuntos de variables (cuantitativas y/o cualitativas) estructuradas en grupos. Tiene en cuenta la contribución de todos los grupos activos de variables para definir la distancia entre individuos.

Se instalan los paquetes y las liberías.

#install.packages(c("FactoMineR", "factoextra"))

library("FactoMineR")
library("factoextra")


data(wine)
colnames(wine)
##  [1] "Label"                         "Soil"                         
##  [3] "Odor.Intensity.before.shaking" "Aroma.quality.before.shaking" 
##  [5] "Fruity.before.shaking"         "Flower.before.shaking"        
##  [7] "Spice.before.shaking"          "Visual.intensity"             
##  [9] "Nuance"                        "Surface.feeling"              
## [11] "Odor.Intensity"                "Quality.of.odour"             
## [13] "Fruity"                        "Flower"                       
## [15] "Spice"                         "Plante"                       
## [17] "Phenolic"                      "Aroma.intensity"              
## [19] "Aroma.persistency"             "Aroma.quality"                
## [21] "Attack.intensity"              "Acidity"                      
## [23] "Astringency"                   "Alcohol"                      
## [25] "Balance"                       "Smooth"                       
## [27] "Bitterness"                    "Intensity"                    
## [29] "Harmony"                       "Overall.quality"              
## [31] "Typical"

El siguiente código R realiza el MFA en los datos de los vinos utilizando los grupos: olor, visual, olor después de agitar y sabor. Estos grupos se denominan grupos activos. El grupo restante de variables - origen (el primer grupo) y juicio general (el sexto grupo) - se denominan grupos complementarios; num.grupo.sup = c(1, 6):

library(FactoMineR)
data(wine)
res.mfa <- MFA(wine,
              group = c(2, 5, 3, 10, 9, 2),
              type = c("n", "s", "s", "s", "s", "s"),
              name.group = c("origin","odor","visual", "odor.after.shaking", "taste", "overall"),
              num.group.sup = c(1, 6),
              graph = FALSE)

print(res.mfa)
## **Results of the Multiple Factor Analysis (MFA)**
## The analysis was performed on 21 individuals, described by 31 variables
## *Results are available in the following objects :
## 
##    name                 description                                           
## 1  "$eig"               "eigenvalues"                                         
## 2  "$separate.analyses" "separate analyses for each group of variables"       
## 3  "$group"             "results for all the groups"                          
## 4  "$partial.axes"      "results for the partial axes"                        
## 5  "$inertia.ratio"     "inertia ratio"                                       
## 6  "$ind"               "results for the individuals"                         
## 7  "$quanti.var"        "results for the quantitative variables"              
## 8  "$quanti.var.sup"    "results for the quantitative supplementary variables"
## 9  "$quali.var.sup"     "results for the categorical supplementary variables" 
## 10 "$summary.quanti"    "summary for the quantitative variables"              
## 11 "$summary.quali"     "summary for the categorical variables"               
## 12 "$global.pca"        "results for the global PCA"

La proporción de varianzas retenidas por las diferentes dimensiones (ejes) se puede extraer usando la función get_eigenvalue() [paquete factoextra] de la siguiente manera:

library("factoextra")
eig.val <- get_eigenvalue(res.mfa)
head(eig.val)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  3.4619504        49.378382                    49.37838
## Dim.2  1.3667683        19.494446                    68.87283
## Dim.3  0.6154291         8.777969                    77.65080
## Dim.4  0.3721997         5.308747                    82.95954
## Dim.5  0.2703825         3.856511                    86.81605
## Dim.6  0.2024033         2.886912                    89.70297

La función fviz_eig() o fviz_screeplot() [paquete factoextra] se puede utilizar para dibujar el gráfico de pantalla:

fviz_screeplot(res.mfa)

La función get_mfa_var() [de facto extra] se utiliza para extraer los resultados de grupos de variables. Esta función devuelve una lista que contiene las coordenadas, el cos2 y la contribución de dos grupos.

group <- get_mfa_var(res.mfa, "group")
group
## Multiple Factor Analysis results for variable groups 
##  ===================================================
##   Name           Description                                          
## 1 "$coord"       "Coordinates"                                        
## 2 "$cos2"        "Cos2, quality of representation"                    
## 3 "$contrib"     "Contributions"                                      
## 4 "$correlation" "Correlation between groups and principal dimensions"

Se puede acceder a los diferentes componentes de la siguiente manera:

# Coordinates of groups
head(group$coord)
##                        Dim.1      Dim.2      Dim.3      Dim.4      Dim.5
## odor               0.7820738 0.61977283 0.37353451 0.17260092 0.08553276
## visual             0.8546846 0.04014481 0.01438360 0.04550736 0.02966750
## odor.after.shaking 0.9247734 0.46892047 0.18009116 0.10139051 0.11589439
## taste              0.9004187 0.23793016 0.04741982 0.05270088 0.03928784
# Cos2: quality of representation on the factore map
head(group$cos2)
##                        Dim.1       Dim.2        Dim.3       Dim.4        Dim.5
## odor               0.3799491 0.238613517 0.0866745169 0.018506155 0.0045445922
## visual             0.7284016 0.001607007 0.0002062976 0.002065011 0.0008776492
## odor.after.shaking 0.6245535 0.160582210 0.0236855692 0.007507471 0.0098089810
## taste              0.7222292 0.050429542 0.0020031144 0.002474125 0.0013749986
# Contributions to the dimensions
head(group$contrib)
##                       Dim.1     Dim.2     Dim.3    Dim.4    Dim.5
## odor               22.59055 45.345861 60.694972 46.37321 31.63399
## visual             24.68795  2.937207  2.337166 12.22660 10.97242
## odor.after.shaking 26.71250 34.308703 29.262699 27.24089 42.86313
## taste              26.00900 17.408230  7.705163 14.15930 14.53047

Para trazar los grupos se realiza lo siguiente.

fviz_mfa_var(res.mfa, "group")

Para dibujar un gráfico de barras de la contribución de los grupos a las dimensiones, se usa la función fviz_contrib():

# Contribution to the first dimension
fviz_contrib(res.mfa, "group", axes = 1)

# Contribution to the second dimension
fviz_contrib(res.mfa, "group", axes = 2)

La función get_mfa_var() [de facto extra] se utiliza para extraer los resultados de las variables cuantitativas. Esta función devuelve una lista que contiene las coordenadas, el cos2 y la contribución de las variables:

quanti.var <- get_mfa_var(res.mfa, "quanti.var")
quanti.var
## Multiple Factor Analysis results for quantitative variables 
##  ===================================================
##   Name       Description                      
## 1 "$coord"   "Coordinates"                    
## 2 "$cos2"    "Cos2, quality of representation"
## 3 "$contrib" "Contributions"

Se pueden acceder a los diferentes componentes de la siguiente manera.

# Coordinates
head(quanti.var$coord)
##                                   Dim.1       Dim.2       Dim.3      Dim.4
## Odor.Intensity.before.shaking 0.5908036  0.66723783 -0.02326175  0.3287015
## Aroma.quality.before.shaking  0.8352510 -0.07539908 -0.35417877  0.1414425
## Fruity.before.shaking         0.7160259 -0.15069626 -0.53748761  0.2517063
## Flower.before.shaking         0.4387181 -0.40937751  0.63731284  0.4029075
## Spice.before.shaking          0.0380525  0.86501993  0.12795122 -0.1822298
## Visual.intensity              0.8811873  0.23833245  0.14099033 -0.2128871
##                                     Dim.5
## Odor.Intensity.before.shaking  0.05786231
## Aroma.quality.before.shaking   0.04992114
## Fruity.before.shaking          0.18981578
## Flower.before.shaking          0.12200773
## Spice.before.shaking           0.36741971
## Visual.intensity              -0.17676282
# Cos2: quality on the factore map
head(quanti.var$cos2)
##                                     Dim.1       Dim.2       Dim.3      Dim.4
## Odor.Intensity.before.shaking 0.349048863 0.445206325 0.000541109 0.10804466
## Aroma.quality.before.shaking  0.697644264 0.005685021 0.125442602 0.02000597
## Fruity.before.shaking         0.512693037 0.022709361 0.288892928 0.06335608
## Flower.before.shaking         0.192473567 0.167589944 0.406167661 0.16233443
## Spice.before.shaking          0.001447992 0.748259477 0.016371514 0.03320769
## Visual.intensity              0.776491025 0.056802358 0.019878273 0.04532093
##                                     Dim.5
## Odor.Intensity.before.shaking 0.003348047
## Aroma.quality.before.shaking  0.002492121
## Fruity.before.shaking         0.036030029
## Flower.before.shaking         0.014885886
## Spice.before.shaking          0.134997242
## Visual.intensity              0.031245096
# Contributions to the dimensions
head(quanti.var$contrib)
##                                    Dim.1      Dim.2       Dim.3     Dim.4
## Odor.Intensity.before.shaking 4.49733206 14.5296787  0.03921898 12.948424
## Aroma.quality.before.shaking  8.98882147  0.1855354  9.09194110  2.397581
## Fruity.before.shaking         6.60581103  0.7411389 20.93864000  7.592798
## Flower.before.shaking         2.47993227  5.4694372 29.43858302 19.454686
## Spice.before.shaking          0.01865671 24.4200703  1.18658923  3.979718
## Visual.intensity              7.91221841  1.4660681  1.13941864  4.295418
##                                    Dim.5
## Odor.Intensity.before.shaking  0.5523351
## Aroma.quality.before.shaking   0.4111309
## Fruity.before.shaking          5.9439566
## Flower.before.shaking          2.4557588
## Spice.before.shaking          22.2708049
## Visual.intensity               4.0764862

Correlación entre variables cuantitativas y dimensiones.

El siguiente código R traza variables cuantitativas coloreadas por grupos. La paleta de argumentos se usa para cambiar los colores del grupo . Las variables cuantitativas complementarias están en flecha discontinua y color violeta. Se usa la función repel = TRUE, para evitar la superposición de texto.

fviz_mfa_var(res.mfa, "quanti.var", palette = "jco",
col.var.sup = "violet", repel = TRUE)

Para que la trama sea más legible, podemos usar geom = c(“punto”, “texto”) en lugar de geom = c(“flecha”, “texto”). Cambiaremos también la posición de la leyenda de “derecha” a “abajo”, usando el argumento leyenda = “abajo”:

fviz_mfa_var(res.mfa, "quanti.var", palette = "jco",
col.var.sup = "violet", repel = TRUE,
geom = c("point", "text"), legend = "bottom")

El siguiente código R muestra las 20 principales categorías de variables que contribuyen a las dimensiones:

# Contributions to dimension 1
fviz_contrib(res.mfa, choice = "quanti.var", axes = 1, top = 20,
palette = "jco")

# Contributions to dimension 2
fviz_contrib(res.mfa, choice = "quanti.var", axes = 2, top = 20,
palette = "jco")

Las variables cuantitativas que más contribuyen se pueden resaltar en el diagrama de dispersión usando el argumento col.var = “contrib”. Esto produce colores degradados, que se pueden personalizar usando el argumento gradiente.cols

fviz_mfa_var(res.mfa, "quanti.var", col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
col.var.sup = "violet", repel = TRUE,
geom = c("point", "text"))

# Color by cos2 values: quality on the factor map
fviz_mfa_var(res.mfa, col.var = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
col.var.sup = "violet", repel = TRUE)

Para crear un gráfico de barras de variables cos2, se escribe lo siguiente

fviz_cos2(res.mfa, choice = "quanti.var", axes = 1)

Para obtener los resultados de los individuos se escribe lo siguiente:

ind <- get_mfa_ind(res.mfa)
ind
## Multiple Factor Analysis results for individuals 
##  ===================================================
##   Name                      Description                      
## 1 "$coord"                  "Coordinates"                    
## 2 "$cos2"                   "Cos2, quality of representation"
## 3 "$contrib"                "Contributions"                  
## 4 "$coord.partiel"          "Partial coordinates"            
## 5 "$within.inertia"         "Within inertia"                 
## 6 "$within.partial.inertia" "Within partial inertia"
fviz_mfa_ind(res.mfa, col.ind = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE)

fviz_mfa_ind(res.mfa,
habillage = "Label", # color by groups
palette = c("#00AFBB", "#E7B800", "#FC4E07"),
addEllipses = TRUE, ellipse.type = "confidence",
repel = TRUE # Avoid text overlapping
)

Si se busca colorear individuos usando múltiples variables categóricas al mismo tiempo, use la función fviz_ellipses() [de hecho extra] de la siguiente manera:

fviz_ellipses(res.mfa, c("Label", "Soil"), repel = TRUE)

Para trazar los puntos parciales de todos los individuos, se realiza lo siguiente:

fviz_mfa_ind(res.mfa, partial = "all")

fviz_mfa_ind(res.mfa, partial = c("1DAM", "1VAU", "2ING"))

El gráfico de ejes parciales muestra la relación entre los ejes principales del MFA y los que se obtienen al analizar cada grupo mediante un PCA (para grupos de variables continuas) o un MCA (para variables cualitativas).

fviz_mfa_axes(res.mfa)

Capítulo 8: Agrupación jerárquica en componentes principales

La agrupación en clústeres es uno de los métodos importantes de minería de datos para descubrir conocimiento en conjuntos de datos multivariantes. El objetivo es identificar grupos (es decir, clústeres) de objetos similares dentro de un conjunto de datos de interés.

La combinación de métodos de componentes principales y métodos de agrupación en clústeres es útil en al menos tres situaciones

Caso 1: Variables continuas

En la situación en la que tiene un conjunto de datos multidimensionales que contiene varias variables continuas, el análisis de componentes principales (PCA) se puede utilizar para reducir la dimensión de los datos en pocas variables continuas que contienen la información más importante de los datos. A continuación, puede realizar un análisis de clúster en los resultados de PCA.

El paso PCA puede considerarse como un paso de eliminación de ruido que puede conducir a una agrupación más estable. Esto puede ser muy útil si tiene un conjunto de datos grande con varias variables, como en los datos de expresión génica.

Caso 2: Agrupación en datos categóricos

Para realizar el análisis de agrupamiento sobre datos categóricos, el análisis de correspondencias (CA, para analizar la tabla de contingencia) y el análisis de correspondencias múltiples (MCA, para analizar variables categóricas multidimensionales) se pueden utilizar para transformar variables categóricas en un conjunto de pocas variables continuas (los componentes principales). El análisis de conglomerados se puede aplicar a continuación en los resultados de (M)CA.

En este caso, el método (M)CA puede considerarse como pasos de preprocesamiento que permiten calcular la agrupación en clústeres en datos categóricos.

Caso 3: Agrupación en clústeres en datos mixtos

Cuando tiene datos mixtos de variables continuas y categóricas, primero puede realizar FAMD (análisis factorial de datos mixtos) o MFA (análisis factorial múltiple). A continuación, puede aplicar el análisis de clúster en las salidas FAMD/MFA.

Entonces, como en los casos anteriores se instalan los paquetes necesarios.

#install.packages(c("FactoMineR", "factoextra"))
library(factoextra)
library(FactoMineR)

Se calcula nuevamente el análisis de componentes principales (PCA). El argumento se utiliza en la función para mantener sólo los tres primeros componentes principales. A continuación, el HCPC se aplica en el resultado del PCA.

library(FactoMineR)
# Compute PCA with ncp = 3
res.pca <- PCA(USArrests, ncp = 3, graph = FALSE)
# Compute hierarchical clustering on principal components
res.hcpc <- HCPC(res.pca, graph = FALSE)

Se visualiza el dendrograma generado por el clustering jerárquico

fviz_dend(res.hcpc, 
          cex = 0.7,                     # Label size
          palette = "jco",               # Color palette see ?ggpubr::ggpar
          rect = TRUE, rect_fill = TRUE, # Add rectangle around groups
          rect_border = "jco",           # Rectangle color
          labels_track_height = 0.8      # Augment the room for labels
          )

Es posible visualizar individuos en el mapa de componentes principales y colorear individuos de acuerdo con el clúster al que pertenecen

fviz_cluster(res.hcpc,
             repel = TRUE,            # Avoid label overlapping
             show.clust.cent = TRUE, # Show cluster centers
             palette = "jco",         # Color palette see ?ggpubr::ggpar
             ggtheme = theme_minimal(),
             main = "Factor map"
             )

También puede dibujar una gráfica tridimensional combinando la agrupación jerárquica y el mapa factorial utilizando la función base R:

# Principal components + tree
plot(res.hcpc, choice = "3D.map")

Para mostrar los datos originales con asignaciones de clúster, escriba lo siguiente:

head(res.hcpc$data.clust, 10)
##             Murder Assault UrbanPop Rape clust
## Alabama       13.2     236       58 21.2     3
## Alaska        10.0     263       48 44.5     4
## Arizona        8.1     294       80 31.0     4
## Arkansas       8.8     190       50 19.5     3
## California     9.0     276       91 40.6     4
## Colorado       7.9     204       78 38.7     4
## Connecticut    3.3     110       77 11.1     2
## Delaware       5.9     238       72 15.8     2
## Florida       15.4     335       80 31.9     4
## Georgia       17.4     211       60 25.8     3

Para mostrar las variables cuantitativas que describen más cada clúster, escriba lo siguiente:

res.hcpc$desc.var$quanti
## $`1`
##             v.test Mean in category Overall mean sd in category Overall sd
## UrbanPop -3.898420         52.07692       65.540       9.691087  14.329285
## Murder   -4.030171          3.60000        7.788       2.269870   4.311735
## Rape     -4.052061         12.17692       21.232       3.130779   9.272248
## Assault  -4.638172         78.53846      170.760      24.700095  82.500075
##               p.value
## UrbanPop 9.682222e-05
## Murder   5.573624e-05
## Rape     5.076842e-05
## Assault  3.515038e-06
## 
## $`2`
##             v.test Mean in category Overall mean sd in category Overall sd
## UrbanPop  2.793185         73.87500       65.540       8.652131  14.329285
## Murder   -2.374121          5.65625        7.788       1.594902   4.311735
##              p.value
## UrbanPop 0.005219187
## Murder   0.017590794
## 
## $`3`
##             v.test Mean in category Overall mean sd in category Overall sd
## Murder    4.357187          13.9375        7.788       2.433587   4.311735
## Assault   2.698255         243.6250      170.760      46.540137  82.500075
## UrbanPop -2.513667          53.7500       65.540       7.529110  14.329285
##               p.value
## Murder   1.317449e-05
## Assault  6.970399e-03
## UrbanPop 1.194833e-02
## 
## $`4`
##            v.test Mean in category Overall mean sd in category Overall sd
## Rape     5.352124         33.19231       21.232       6.996643   9.272248
## Assault  4.356682        257.38462      170.760      41.850537  82.500075
## UrbanPop 3.028838         76.00000       65.540      10.347798  14.329285
## Murder   2.913295         10.81538        7.788       2.001863   4.311735
##               p.value
## Rape     8.692769e-08
## Assault  1.320491e-05
## UrbanPop 2.454964e-03
## Murder   3.576369e-03

Del mismo modo, para mostrar las dimensiones principales que están más asociadas con los clústeres, se escribe el código mostrado a continuación.

res.hcpc$desc.axes$quanti
## $`1`
##          v.test Mean in category  Overall mean sd in category Overall sd
## Dim.1 -5.175764        -1.964502 -5.322132e-16      0.6192556   1.574878
##            p.value
## Dim.1 2.269806e-07
## 
## $`2`
##         v.test Mean in category  Overall mean sd in category Overall sd
## Dim.2 3.585635        0.7428712 -4.949513e-16      0.6137936  0.9948694
##            p.value
## Dim.2 0.0003362596
## 
## $`3`
##          v.test Mean in category  Overall mean sd in category Overall sd
## Dim.1  2.058338        1.0610731 -5.322132e-16      0.5146613  1.5748783
## Dim.3  2.028887        0.3965588  2.161465e-17      0.3714503  0.5971291
## Dim.2 -4.536594       -1.4773302 -4.949513e-16      0.5750284  0.9948694
##            p.value
## Dim.1 3.955769e-02
## Dim.3 4.246985e-02
## Dim.2 5.717010e-06
## 
## $`4`
##         v.test Mean in category  Overall mean sd in category Overall sd
## Dim.1 4.986474         1.892656 -5.322132e-16      0.6126035   1.574878
##            p.value
## Dim.1 6.149115e-07

Finalmente, los individuos representativos de cada grupo se pueden extraer de la siguiente manera

res.hcpc$desc.ind$para
## Cluster: 1
##         Idaho  South Dakota         Maine          Iowa New Hampshire 
##     0.3674381     0.4993032     0.5012072     0.5533105     0.5891145 
## ------------------------------------------------------------ 
## Cluster: 2
##         Ohio     Oklahoma Pennsylvania       Kansas      Indiana 
##    0.2796100    0.5047549    0.5088363    0.6039091    0.7100820 
## ------------------------------------------------------------ 
## Cluster: 3
##        Alabama South Carolina        Georgia      Tennessee      Louisiana 
##      0.3553460      0.5335189      0.6136865      0.8522640      0.8780872 
## ------------------------------------------------------------ 
## Cluster: 4
##   Michigan    Arizona New Mexico   Maryland      Texas 
##  0.3246254  0.4532480  0.5176322  0.9013514  0.9239792

Caso de variables categóricas

Comenzamos, realizando un MCA en los individuos. Mantenemos los primeros 20 ejes del MCA que retienen el 87% de la información.

# Loading data
library(FactoMineR)
data(tea)
# Performing MCA
res.mca <- MCA(tea, 
               ncp = 20,            # Number of components kept
               quanti.sup = 19,     # Quantitative supplementary variables
               quali.sup = c(20:36), # Qualitative supplementary variables
               graph=FALSE)

A continuación, aplicamos la agrupación jerárquica en los resultados del MCA:

Esto se presenta de la siguiente manera

# Dendrogram
fviz_dend(res.hcpc, show_labels = FALSE)

# Individuals facor map
fviz_cluster(res.hcpc, geom = "point", main = "Factor map")

Se realiza una descripción de las variables

# Description by variables
res.hcpc$desc.var$test.chi2
## NULL

También se realiza una descripción de las variables por categorías

# Description by variable categories
res.hcpc$desc.var$category
## NULL

Descripción por componentes principales

res.hcpc$desc.axes
## 
## Link between the cluster variable and the quantitative variables
## ================================================================
##            Eta2      P-value
## Dim.1 0.8814658 2.585319e-21
## Dim.2 0.6010524 2.862247e-09
## Dim.3 0.1687608 3.522618e-02
## 
## Description of each cluster by quantitative variables
## =====================================================
## $`1`
##          v.test Mean in category  Overall mean sd in category Overall sd
## Dim.1 -5.175764        -1.964502 -5.322132e-16      0.6192556   1.574878
##            p.value
## Dim.1 2.269806e-07
## 
## $`2`
##         v.test Mean in category  Overall mean sd in category Overall sd
## Dim.2 3.585635        0.7428712 -4.949513e-16      0.6137936  0.9948694
##            p.value
## Dim.2 0.0003362596
## 
## $`3`
##          v.test Mean in category  Overall mean sd in category Overall sd
## Dim.1  2.058338        1.0610731 -5.322132e-16      0.5146613  1.5748783
## Dim.3  2.028887        0.3965588  2.161465e-17      0.3714503  0.5971291
## Dim.2 -4.536594       -1.4773302 -4.949513e-16      0.5750284  0.9948694
##            p.value
## Dim.1 3.955769e-02
## Dim.3 4.246985e-02
## Dim.2 5.717010e-06
## 
## $`4`
##         v.test Mean in category  Overall mean sd in category Overall sd
## Dim.1 4.986474         1.892656 -5.322132e-16      0.6126035   1.574878
##            p.value
## Dim.1 6.149115e-07

Descripción por individuos

res.hcpc$desc.ind$para
## Cluster: 1
##         Idaho  South Dakota         Maine          Iowa New Hampshire 
##     0.3674381     0.4993032     0.5012072     0.5533105     0.5891145 
## ------------------------------------------------------------ 
## Cluster: 2
##         Ohio     Oklahoma Pennsylvania       Kansas      Indiana 
##    0.2796100    0.5047549    0.5088363    0.6039091    0.7100820 
## ------------------------------------------------------------ 
## Cluster: 3
##        Alabama South Carolina        Georgia      Tennessee      Louisiana 
##      0.3553460      0.5335189      0.6136865      0.8522640      0.8780872 
## ------------------------------------------------------------ 
## Cluster: 4
##   Michigan    Arizona New Mexico   Maryland      Texas 
##  0.3246254  0.4532480  0.5176322  0.9013514  0.9239792