Calcule correlation-cor () - para solo un subconjunto de columnas


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

Un enfoque bruto es eliminar las columnas no numéricas del dataframe. 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.

Author: cengel, 2010-08-26

3 answers

Si tiene un dataframe donde algunas columnas son numéricas y otras son otras (carácter o factor) y solo desea hacer las correlaciones para las columnas numéricas, podría 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
 57
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-26 04:44:50

Para los datos numéricos tienes la solución. Pero son datos categóricos, dijo. 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 de Spearman, sino con una prueba de Chi-cuadrado, por ejemplo. Lo cual es lógico en realidad. Ranking 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 categórica datos. Si codifico amarillo 1 y rojo 2, R consideraría rojo más grande que amarillo.

Entonces, 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 qué variables va, y " out" da el valor p para asociación. Aquí todas las variables son independientes. Lo cual es de esperar, ya que creé los datos al azar.

 13
Author: Joris Meys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-26 08:17:45

Encontré una manera más fácil mirando el script R generado por Rattle. Se ve como a continuación:

correlations <- cor(mydata[,c(1,3,5:87,89:90,94:98)], use="pairwise", method="spearman")
 1
Author: wishihadabettername,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-27 15:40:27