2010-08-26 14 views
40

Tengo un marco de datos y me gustaría calcular el correlation (con Spearman, los datos son categóricos y clasificados) pero solo para un subconjunto de columnas. Intenté con todo, pero la función de R cor() solo acepta datos numéricos (x debe ser numérico, dice el mensaje de error), incluso si se usa Spearman.Calcular correlación - cor() - para solo un subconjunto de columnas

Un enfoque bruto consiste en eliminar las columnas no numéricas del marco de datos. Esto no es tan elegante, para la velocidad Todavía no quiero calcular las correlaciones entre todas las columnas.

Espero que haya una manera de decir simplemente "calcular correlaciones para las columnas x, y, z". Las referencias de columna pueden ser por número o por nombre. Supongo que la forma flexible de proporcionarlos sería a través de un vector.

Cualquier sugerencia es apreciada.

Respuesta

55

si tiene una trama de datos en algunas columnas son numéricos y algunos son otra (carácter o factor) y sólo quiere hacer las correlaciones para las columnas numéricas, se puede hacer lo siguiente:

set.seed(10) 

x = as.data.frame(matrix(rnorm(100), ncol = 10)) 
x$L1 = letters[1:10] 
x$L2 = letters[11:20] 

cor(x) 

Error in cor(x) : 'x' must be numeric 

pero

cor(x[sapply(x, is.numeric)]) 

      V1   V2   V3   V4   V5   V6   V7 
V1 1.00000000 0.3025766 -0.22473884 -0.72468776 0.18890578 0.14466161 0.05325308 
V2 0.30257657 1.0000000 -0.27871430 -0.29075170 0.16095258 0.10538468 -0.15008158 
V3 -0.22473884 -0.2787143 1.00000000 -0.22644156 0.07276013 -0.35725182 -0.05859479 
V4 -0.72468776 -0.2907517 -0.22644156 1.00000000 -0.19305921 0.16948333 -0.01025698 
V5 0.18890578 0.1609526 0.07276013 -0.19305921 1.00000000 0.07339531 -0.31837954 
V6 0.14466161 0.1053847 -0.35725182 0.16948333 0.07339531 1.00000000 0.02514081 
V7 0.05325308 -0.1500816 -0.05859479 -0.01025698 -0.31837954 0.02514081 1.00000000 
V8 0.44705527 0.1698571 0.39970105 -0.42461411 0.63951574 0.23065830 -0.28967977 
V9 0.21006372 -0.4418132 -0.18623823 -0.25272860 0.15921890 0.36182579 -0.18437981 
V10 0.02326108 0.4618036 -0.25205899 -0.05117037 0.02408278 0.47630138 -0.38592733 
       V8   V9   V10 
V1 0.447055266 0.210063724 0.02326108 
V2 0.169857120 -0.441813231 0.46180357 
V3 0.399701054 -0.186238233 -0.25205899 
V4 -0.424614107 -0.252728595 -0.05117037 
V5 0.639515737 0.159218895 0.02408278 
V6 0.230658298 0.361825786 0.47630138 
V7 -0.289679766 -0.184379813 -0.38592733 
V8 1.000000000 0.001023392 0.11436143 
V9 0.001023392 1.000000000 0.15301699 
V10 0.114361431 0.153016985 1.00000000 
+6

si realmente sólo quiere hacer la correlación en las columnas 1, 3 y 10, siempre se puede hacer 'COR (x [c (1, 3, 10)])' – Greg

+1

Lo sentimos, esto es para datos numéricos, no no numéricos. Lo dejo por si acaso. – Greg

+1

contento de que lo dejaste, Greg. Ya ayudaste a alguien, ya me ayudó a buscar sapply de otra manera creativa :) –

13

Para los datos numéricos, usted tiene la solución. Pero es información categórica, dijiste. Entonces la vida se vuelve un poco más complicada ...

Bueno, primero: la cantidad de asociación entre dos variables categóricas no se mide con una correlación de rango Spearman, pero con una prueba Chi-cuadrado, por ejemplo. Que es la lógica en realidad. Clasificación significa que hay algún orden en sus datos. Ahora dime, ¿cuál es más grande, amarillo o rojo? Lo sé, a veces R realiza una correlación de rango de Spearman en datos categóricos. Si codigo amarillo 1 y rojo 2, R consideraría rojo más grande que amarillo.

Así que olvídate de Spearman para obtener datos categóricos. Demostraré el chisq-test y cómo elegir columnas usando combn(). Pero usted se beneficiaría de un poco más de tiempo con el libro de Agresti: http://www.amazon.com/Categorical-Analysis-Wiley-Probability-Statistics/dp/0471360937

set.seed(1234) 
X <- rep(c("A","B"),20) 
Y <- sample(c("C","D"),40,replace=T) 

table(X,Y) 
chisq.test(table(X,Y),correct=F) 
# I don't use Yates continuity correction 

#Let's make a matrix with tons of columns 

Data <- as.data.frame(
      matrix(
      sample(letters[1:3],2000,replace=T), 
      ncol=25 
     ) 
     ) 

# You want to select which columns to use 
columns <- c(3,7,11,24) 
vars <- names(Data)[columns] 

# say you need to know which ones are associated with each other. 
out <- apply(combn(columns,2),2,function(x){ 
      chisq.test(table(Data[,x[1]],Data[,x[2]]),correct=F)$p.value 
     }) 

out <- cbind(as.data.frame(t(combn(vars,2))),out) 

entonces usted debe conseguir:

> out 
    V1 V2  out 
1 V3 V7 0.8116733 
2 V3 V11 0.1096903 
3 V3 V24 0.1653670 
4 V7 V11 0.3629871 
5 V7 V24 0.4947797 
6 V11 V24 0.7259321 

Donde V1 y V2 indican entre las variables que se va, y "fuera" da el valor de p para la asociación. Aquí todas las variables son independientes. Lo que cabría esperar, ya que creé los datos al azar.

+0

Lo siento, tengo la tendencia a anidar funciones bastante a menudo para evitar demasiadas variables inactivas en mi área de trabajo. Si no puede encontrarle sentido al código, solo pregunte y le explicaré lo que hace. –

+0

gracias. De hecho, olvidé mencionar en la pregunta que los datos son categóricos pero clasificados (el nivel de aprobación con algo). Sin embargo, recibirá un voto para el código (del cual aprenderé cosas de todos modos) y para la referencia del libro. – wishihadabettername

+0

ah, OK. Eso explica :-) Perdón por la conferencia, no fue un daño. Definitivamente puedo recomendar Agresti de todos modos. Es el estándar cuando se trata de análisis de datos categóricos. –

1

Encontré una forma más fácil al mirar el script R generado por Rattle. Parece que a continuación:

correlations <- cor(mydata[,c(1,3,5:87,89:90,94:98)], use="pairwise", method="spearman") 
+0

Esto es casi exactamente lo que [Greg escribió en un comentario para su respuesta] (http://stackoverflow.com/questions/3571909/r-how-to-calculate-correlation-cor-for-only-a-subset-of -columns/3572115 # 3572115). – Marek

+1

Ah, OK, me desvió del uso de sapply(). – wishihadabettername

Cuestiones relacionadas