Matriz plana en R a cuatro columnas (índices y triángulos superior/inferior)
Frecuentes
Visto 4,237 veces
3
Estoy usando la función cor.prob() que se ha publicado varias veces en la lista de correo para obtener una matriz de correlaciones (diagonal inferior) y valores p (diagonales superiores):
cor.prob <- function (X, dfr = nrow(X) - 2) {
R <- cor(X)
above <- row(R) < col(R)
r2 <- R[above]^2
Fstat <- r2 * dfr/(1 - r2)
R[above] <- 1 - pf(Fstat, 1, dfr)
R[row(R) == col(R)] <- NA
R
}
d <- data.frame(x=1:5, y=c(10,16,8,60,80), z=c(10,9,12,2,1))
cor.prob(d)
> cor.prob(d)
x y z
x NA 0.04856042 0.107654038
y 0.8807155 NA 0.003523594
z -0.7953560 -0.97945703 NA
¿Cómo colapsaría la matriz de correlación anterior (con las correlaciones en la mitad inferior, los valores p en la mitad superior) en una matriz de cuatro columnas: dos índices, la correlación y el valor p? P.ej:
i j cor pval
x y .88 .048
x z -.79 .107
y z -.97 0.0035
He visto la respuesta a la pregunta anterior así, pero solo me dará una matriz de 3 columnas, no una matriz de cuatro columnas con columnas separadas para el valor p y la correlación.
Cualquier ayuda es apreciada!
2 Respuestas
13
bueno, no es una matriz, porque no puedes mezclar caracteres y números. Pero:
este es mi primer intento (antes de su cambio de etiqueta):
m <- cor.prob(d)
ut <- upper.tri(m)
lt <- lower.tri(m)
d <- data.frame(i=rep(row.names(m),ncol(m))[as.vector(ut)],
j=rep(colnames(m),each=nrow(m))[as.vector(ut)],
cor=m[ut],
p=m[lt])
ahora aplique la corrección que sugerí a continuación y obtendrá
d <- data.frame(i=rep(row.names(m),ncol(m))[as.vector(ut)],
j=rep(colnames(m),each=nrow(m))[as.vector(ut)],
cor=m[ut],
p=t(m)[ut])
finalmente su intercambio de etiquetas, use fila()/col(), y escríbalo como una función:
f1 <- function(m) {
ut <- upper.tri(m)
data.frame(i = rownames(m)[row(m)[ut]],
j = rownames(m)[col(m)[ut]],
cor=t(m)[ut],
p=tm[ut])
}
luego
m<-matrix(1:25,5,dimnames=list(letters[1:5],letters[1:5])
> m
a b c d e
a 1 6 11 16 21
b 2 7 12 17 22
c 3 8 13 18 23
d 4 9 14 19 24
e 5 10 15 20 25
> f1(m)
i j cor p
1 a b 6 2
2 a c 11 3
3 b c 12 8
4 a d 16 4
5 b d 17 9
6 c d 18 14
7 a e 21 5
8 b e 22 10
9 c e 23 15
10 d e 24 20
¿Puedes explicar qué esperabas si no fuera esto?
Respondido 25 ago 12, 07:08
Sí bien hecho. Excepto cambiar ut/lt en cor/p (la correlación es el triángulo inferior, p es el triángulo superior). editaré - Stephen Turner
@StephenTurner Por favor, obtenga una vista previa del comentario de ChrisW: "la última línea debería haber sido p=t(m)[ut]
o no se generalizará a > 3 filas/columnas". Aparentemente no puede comentar. - hhh
Parece haber funcionado bien sin esa edición. Lo pondré en una nueva respuesta. Tendrá que ser una nueva respuesta, demasiado larga para comentar. - Stephen Turner
Sí, tengo problemas para aplicarlo a los datos de mtcars. - Stephen Turner
¿que tipo de problema? Vea la respuesta editada arriba, demasiado grande para comentar. - CrisW
4
cd <- cor.prob(d)
dcd <- as.data.frame( which( row(cd) < col(cd), arr.ind=TRUE) )
dcd$pval <- cd[row(cd) < col(cd)]
dcd$cor <- cd[row(cd) > col(cd)]
dcd[[2]] <-dimnames(cd)[[2]][dcd$col]
dcd[[1]] <-dimnames(cd)[[2]][dcd$row]
dcd
#--------------------
row col pval cor
1 x y 0.048560420 0.8807155
2 x z 0.107654038 -0.7953560
3 y z 0.003523594 -0.9794570
Respondido 25 ago 12, 07:08
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas r matrix or haz tu propia pregunta.
Acabo de editar para mayor claridad. Quiero colapsar la salida de cor.prob() a una tabla de cuatro columnas con dos columnas para los índices, una columna para las correlaciones (que estaban en la diagonal inferior de la matriz original) y una columna para el p- (que estaban en la mitad superior de la matriz original). - Stephen Turner