2010-08-26 2 views
40

Ho un dataframe e vorrei calcolare il correlation (con Spearman, i dati sono categoriali e ordinati) ma solo per un sottoinsieme di colonne. Ho provato con tutti, ma la funzione R cor() accetta solo dati numerici (x deve essere numerico, dice il messaggio di errore), anche se Spearman è usato.Calcola correlazione - cor() - solo per un sottoinsieme di colonne

Un approccio brutale consiste nell'eliminare le colonne non numeriche dal dataframe. Non è così elegante, per la velocità non voglio ancora calcolare le correlazioni tra tutte le colonne.

Spero ci sia un modo per dire semplicemente "calcolare le correlazioni per le colonne x, y, z". I riferimenti delle colonne potevano essere numerati o per nome. Suppongo che il modo flessibile per fornirli sia attraverso un vettore.

Qualsiasi suggerimento è gradito.

risposta

55

se si dispone di un dataframe in cui alcune colonne sono numerici e alcuni sono altro (personaggio o fattore) e si desidera solo fare le correlazioni per le colonne numeriche, si potrebbe procedere come segue:

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 

ma

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

se è davvero solo vuole fare la correlazione su colonne 1, 3, e 10, si può sempre fare 'COR (x [c (1, 3, 10)])' – Greg

+1

Siamo spiacenti, questo è per i dati numerici, non non numerici. Lo lascerò per ogni evenienza. – Greg

+1

felice che tu l'abbia lasciato, Greg. Hai già aiutato qualcuno - già mi ha aiutato a capire in modo creativo in altri modi :) –

13

Per i dati numerici si ha la soluzione. Ma sono dati categoriali, hai detto. Poi la vita diventa un po 'più complicata ...

Bene, innanzitutto: la quantità di associazione tra due variabili categoriali non è misurata con una correlazione di rango di Spearman, ma con un test di Chi quadrato ad esempio. Qual è la logica in realtà. Classifica significa che c'è un ordine nei tuoi dati. Ora dimmi quale è più grande, giallo o rosso? Lo so, a volte R esegue una correlazione di rango spearman su dati categoriali. Se codice giallo 1 e rosso 2, R considererebbe il rosso più grande del giallo.

Quindi, dimentica Spearman per dati categoriali. Mostrerò il test di chisq e come scegliere le colonne usando combn(). Ma si potrebbe beneficiare di un po 'più di tempo con il libro di 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) 

allora si dovrebbe ottenere:

> 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 

Dove V1 e V2 indicano tra le quali le variabili va, e "out" dà il valore p per l'associazione. Qui tutte le variabili sono indipendenti. Che ti aspetteresti, dato che ho creato i dati a caso.

+0

Scusa, ho la tendenza a nidificare le funzioni abbastanza spesso per evitare troppe variabili di inattività nel mio spazio di lavoro. Se non riesci a dare un senso al codice, chiedi e ti spiegherò che cosa fa. –

+0

grazie. In realtà ho dimenticato di menzionare nella domanda che i dati sono categorici ma classificati (il livello di approvazione con qualcosa). Si ottiene comunque un voto per il codice (dal quale imparerò comunque le cose) e per il riferimento del libro. – wishihadabettername

+0

ah, OK. Questo spiega :-) Scusate per la conferenza, quindi nessun danno significava. Posso assolutamente raccomandare Agresti comunque. È lo standard quando si tratta di analisi dei dati categoriali. –

1

Ho trovato un modo più semplice guardando lo script R generato da Rattle. Sembra che qui di seguito:

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

Questo è quasi esattamente ciò che [Greg ha scritto in un commento per la sua risposta] (http://stackoverflow.com/questions/3571909/r-how-to-calculate-correlation-cor-for-only-a-subset-of -colonne/3572115 # 3572115). – Marek

+1

Ah, OK, sono stato sviato dall'uso di sapply(). – wishihadabettername