Código
library(dplyr)
bumpus %>%
group_by(sex, sobreviv) %>%
select(-ID) %>%
summarise(across(where(is.numeric), ~ mean(.x, na.rm = TRUE)))Los datos siguientes provienen del famoso estudio del Dr. Herman Bumpus (1899) sobre la morfometría del gorrión Passer domesticus (figura 13.1 (a)). Bumpus analizó 9 medidas corporales de una muestra de gorriones (hembras, machos y juveniles) que fueron encontrados helándose en Providence (USA) (figura 13.1 (b)) durante un invierno particularmente fuerte. Del total de 136 gorriones medidos, 72 sobrevivieron y 64 murieron eventualmente de frío y el Dr. Bumpus aprovechó este experimento natural para explorar si gorriones de ciertas características sucumbían más fácilmente al frío que otros. También exploró las diferencias morfométricas entre los sexos. Los datos se encuentran en el archivo ‘bumpus.csv’.
Las medidas que Bumpus registró fueron:
Total Length (TL) en mm
Length of beak and head (BHL) en mm
Alar Extent (AE) en mm
Length of Keel of Sternum (SKL) en pulgadas
Length of Humerus (HL) en pulgadas
Length of Femur (FL) en pulgadas
Width of Skull (WS) en pulgadas
Length of Tibio-Tarsus (LTT) en pulgadas
Total Weight (WS) en gramos
Considerando la hipotesis de Bumpus, ¿cuáles son las correlaciones que te interesa analizar: aquellas entre variables (columnas) para identificar grupos de observaciones (filas), o entre observaciones para identificar grupos de variables?
Explora los datos utilizando herramientas gráficas y numéricas apropiadas. Recuerda que puedes usar subsetting para seleccionar solo las columnas o filas de la tabla que contengan las variables que te interesan. (PISTA: recuerda funciones como summary, plot y cor)
library(dplyr)
bumpus %>%
group_by(sex, sobreviv) %>%
select(-ID) %>%
summarise(across(where(is.numeric), ~ mean(.x, na.rm = TRUE)))Y <- bumpus %>%
select(AE:SKL) %>%
as.matrix()Y mediante la función cov y llámala C. ¿Qué dimensiones tiene la matriz C?cov.#Obtención de un vector vertical unitario
ones <- matrix(1, nrow = nrow(Y), ncol = 1)
dim(ones)
#Cálculo del número de filas (número de observaciones)
numFilas <- t(ones) %*% ones
numFilas
#Obtención del inverso de esa matriz de un único elemento
invnumFilas <- solve(t(ones) %*% ones)
invnumFilas
#Obtención de la sumatoria de elementos por columnas
sumaCol <- t(ones) %*% Y
sumaCol
#Mutiplica la sumaCol por el inverso del numFilas (divide la sumatoria entre n filas).
invnumFilas %*% sumaCol
#El vector de medias también se puede obtener así.
colMeans(Y)
#Multiplica el vector horizontal de medias por el vector vertical unitario para obtener
#una matriz de medias.
Y.bar <- ones %*% invnumFilas %*% sumaCol
dim(Y.bar)
#Sustraer la matriz de datos de la matriz de medias.
Z <- Y - Y.bar
#Esto también se logra obteniendo los residuales de una regresion lineal contra solo un
#intercepto de valor 1.
Z <- resid(lm(Y ~ 1))
#Obtención de la matriz de suma de cuadrados y cross-products (SSCP matrix) (elevar al
# cuadrado la matriz Z)
S <- t(Z) %*% Z
S
#SSCP es una matriz triangular con la SS en la diagonal y los CP en los elementos fuera
#de la diagonal.
dim(S)
#Obtener la matriz de varianza covarianza: Dividir SSCP (suma de cuadrados y productos
#cruzados) entre n-1 (g.l.)
Cmano <- 1 / (nrow(Y) - 1) * S
Cmano
C cor sobre la matriz Y, llama R al objeto generado e identifica cuál es el resultado de esta operación.#Sustraer la matriz de datos de la matriz de medias para calcular la variación
#total: Y-Y.bar
Z <- resid(lm(Y ~ 1))
#Obtiene la matriz diagonal W, cuyos elementos (en la diagonal) son el inverso de
#la desviación estándar de cada una de las variables medidas
W <- diag(sqrt(1 / apply(Y, 2, var)))
#Obtiene una medida ponderada de Z usando el inverso de la desviación
#estandar W: (Y-Y.bar)* W
Zp <- Z %*% W
#Eleva al cuadrado y suma las distancias ponderadas Zp
Sr <- t(Zp) %*% Zp
#Divide los valores de la matriz Sr entre g.l.=n-1
Rmano <- Sr / (nrow(Y) - 1)
Rmano Una forma de obtener un vector con los elementos diagonales de una matriz es la función apply. El valor 2 es para indicar que var debe aplicarse a las columnas de la matriz Y (si es 1 se aplicaría a las filas).
apply(Y, 2, var) C para obtener los eigenvectores y eigenvalores de un PCA (de covarianza) de Y. Usa la función eigen.prcomp sobre la matriz Y, usando el siguiente código. Compara con el PCA a mano.pca.cov <- prcomp(Y,
retx = T,
center = TRUE,
scale. = FALSE)names aplicada a un objeto que es producto de ciertos procedimiento (p.e. clase anova, clase prcomp), proporciona el nombre de las listas con los resultados del procedimiento. Usa la función names sobre pca.cov para explorar los distintos resultados que ofrece prcomp. Intenta identificar que contiene cada uno de ellos.prcomp sobre la matriz Y, pero adiciona el argumento scale.=T y guarda el objeto como pca.cor. Compara la salida con la eigenanálisis hecho a mano sobre la matriz R.pca.cor <- prcomp(Y,
retx = T,
center = TRUE,
scale. = TRUE)prcomp calcula automáticamente las proyecciones de los eigenvectores sobre los ejes principales para poder visualizarlas. Estas proyecciones (o scores) las encuentras en la lista del objeto bajo el nombre $x del objeto clase prcomp. Para obtener las proyecciones a mano se requiere del siguiente código:#Ajudica el nombre E.cov a una matriz con los eigenvectores de un PCA de covarianza
E.cov <- eigen(C)$vectors
#Obtiene las proyecciones como el producto matricial de Z (matriz de residuales Y-Y.barra)
#y la matriz E.cov
P.cov <- Z %*% E.cov
#Dimensiones igual a la matriz original Y.
dim(P.cov)
#Ajudica el nombre E.cor a una matriz con los eigenvectores de un PCA de correlación
E.cor <- eigen(Rmano)$vectors
#Obtiene las proyecciones como el producto matricial de Z
#(matriz de residuales Y-Y.barra)* W, y la matriz E.cor
P.cor <- Z %*% W %*% E.cor
#Recuerda que W es una matriz diagonal con el inverso de la desviación estándar de
#las variables de Y.
#Dimensiones igual a la matriz original Y.
dim(P.cor)$x de la lista. (PISTA: para comparar matrices usa la función head te permite ver sólo las primeras 6 líneas de una matriz.plot(P.cor[,2]~P.cor[,1],asp=1,cex=1, xlab = "PC1", ylab = "PC2" )plot(
P.cor[, 2] ~ P.cor[, 1],
asp = 1,
cex = 1,
xlab = "PC1",
ylab = "PC2"
)
points(P.cor[bumpus$sobreviv == 'T', ],
cex = 1.5,
pch = 21,
bg = 'green')
points(P.cor[bumpus$sobreviv == 'F', ],
cex = 1.5,
pch = 21,
bg = 'black')
text(P.cor[, 1],
P.cor[, 2],
as.character(bumpus$sex),
pos = 1,
cex = 1)biplot de correlación (o sea, la escala para elevar lambda es 0) de acuerdo con el código siguiente:biplot(
princomp(Y, cor = T),
choices = 1:2,
scale = 0,
var.axes = T,
arrow.len = 0.1,
col = c("black", "red"),
cex = 0.7,
asp = 1,
main = "Biplot (alfa=0)",
xlab = "PC1",
ylab = "PC2"
)screeplot(pca.cor, type = "lines", main = "Scree-plot")
L.cor <- eigen(R)$values
scree.porcent <- L.cor / sum(L.cor) * 100
plot(
scree.porcent ~ c(1:6),
type = "l",
main = "Scree-plot",
xlab = "PC",
ylab = "Variación (%)"
)ggfortify y genere ordenaciones basados en PCA visualmente amenos.