Estoy buscando replicar este gráfico de correlación, o al menos acercarme lo más posible a él.
Específicamente, quiero:
- los valores de correlación en la mitad inferior, con valores que varían en una escala de grises basada en el valor absoluto
- los círculos en la mitad superior, con diámetro variable y en la escala de colores.
- Quiero poder editar las etiquetas de escala del eje para que las descripciones completas estén en el eje y y las referencias numéricas en el eje x.
Me he acercado relativamente, pero no he logrado una replicación lo suficientemente precisa. Describo mis intentos más cercanos a continuación con código reproducible. El corrplotpaquete me ha acercado más.
# general preparation
library(car)
correlations = cor(mtcars)
library(corrplot)
corrplot.mixed(correlations,
upper = "number", #upper.col =???
lower = "circle", #lower.col =???
tl.pos = "lt", tl.col = "black", tl.cex = 0.5)
Notas:
- hay una forma de hacer los coeficientes en escala de grises, pero no la entiendo: https://rdrr.io/cran/corrplot/man/COL1.html
- Por alguna extraña razón, cuando uso mis propios datos (a diferencia de
mtcar), los colores de los coeficientes no coinciden con los valores de correlación reales. No puedo dar un ejemplo de código reproducible aquí, porque funciona bien con losmtcardatos.
source("http://www.sthda.com/upload/rquery_cormat.r")
rquery.cormat(mtcar)
library("ggcorrplot")
# circles separate
ggcorrplot(correlations, # correlation matrix
method = "circle", # circles instead of squares
type = "upper", # show only upped triangle
show.diag = F, # don't show diagonal values (1)
lab = F, # don't show cor coeffs
outline.col = "white", # no outline of circles
ggtheme = theme_bw, # theme
colors = c("#440154FF","#238A8DFF","#FDE725FF"))
# coefs separate
ggcorrplot(correlations, # correlation matrix
method = "circle", # circles instead of squares
type = "upper", # show only upped triangle
show.diag = F, # don't show diagonal values (1)
lab = T, # don't show cor coeffs
outline.col = NA, # don't show circles
ggtheme = theme_bw, # theme
colors = c("#440154FF","#238A8DFF","#FDE725FF"))
# can't combine both plots?
library(corrgram)
corrgram(correlations,
labels = indices_all,
lower.panel = "panel.fill",
upper.panel = "panel.cor")
Algunas otras notas:
- Parece que las mitades de las gráficas tienden a correr a través de la diagonal opuesta que en la gráfica de ejemplo, pero supongo que eso no es una gran preocupación.
Solución del problema
Las opciones listas para usar son rápidas y agradables. Sin embargo, cuando se trata de personalizar, en mi humilde opinión, puede valer la pena construir la trama desde cero usando ggplot2. Como primer paso, esto implica algunas disputas de datos para que su matriz de correlación tenga la forma correcta. También en este paso convierto las categorías a factors y una identificación numérica. Según los identificadores, dividí los datos en los valores diagonales superior e inferior que luego podrían trazarse por separado usando a geom_pointy a geom_text. Además de eso, es importante agregar drop=FALSEa la escala x e y para mantener todos los niveles de los factores y el orden correcto. También uso algunas funciones para obtener las etiquetas de eje deseadas:
EDITAR: siguiendo la sugerencia de @AllanCameron, agregué un coord_equaltoque "final" para obtener una apariencia agradable de matriz cuadrada. Y gracias a @RichtieSacramento, el código ahora asigna el valor absoluto en el sizeaes.
library(dplyr)
library(tidyr)
library(ggplot2)
correlations = cor(mtcars)
levels <- colnames(mtcars)
corr_long <- correlations %>%
data.frame() %>%
mutate(row = factor(rownames(.), levels = levels),
rowid = as.numeric(row)) %>%
pivot_longer(-c(row, rowid), names_to = "col") %>%
mutate(col = factor(col, levels = levels),
colid = as.numeric(col))
ggplot(corr_long, aes(col, row)) +
geom_point(aes(size = abs(value), fill = value),
data = ~filter(.x, rowid > colid), shape = 21) +
geom_text(aes(label = scales::number(value, accuracy =.01), color = abs(value)),
data = ~filter(.x, rowid < colid), size = 8 /.pt) +
scale_x_discrete(labels = ~ attr(.x, "pos"), drop = FALSE) +
scale_y_discrete(labels = ~ paste0(.x, " (", attr(.x, "pos"), ")"), drop = FALSE) +
scale_fill_viridis_c(limits = c(-1, 1)) +
scale_color_gradient(low = grey(.8), high = grey(.2)) +
coord_equal() +
guides(size = "none", color = "none") +
theme(legend.position = "bottom",
panel.grid = element_blank(),
axis.ticks = element_blank()) +
labs(x = NULL, y = NULL, fill = NULL)

No hay comentarios:
Publicar un comentario