domenica 16 novembre 2008

Test di Wilcoxon dei ranghi con segno

Confronto delle medie tra 2 gruppi di campioni appaiati, metodo non parametrico.

Il sindaco di una città vuole verificare se i livelli di inquinamento si riducono chiudendo le strade del centro al traffico. A tal fine viene misurato il tasso di inquinamento ogni 60 minuti (dalle 8 alle 22: totale di 15 rilevazioni) in una giornata in cui il traffico è aperto, e in una giornata di chiusura al traffico. Ecco di seguito i valori di inquinamento atmosferico:

Con traffico: 214, 159, 169, 202, 103, 119, 200, 109, 132, 142, 194, 104, 219, 119, 234
Senza traffico: 159, 135, 141, 101, 102, 168, 62, 167, 174, 159, 66, 118, 181, 171, 112


Siamo di fronte a dati appaiati, perché esiste un vincolo tra le rilevazioni, consistente nel fatto che stiamo considerando la stessa città (con le sue peculiarità atmosferiche, ventilazione, etc.) seppure in due differenti giorni. Non potendo supporre una distribuzione gaussiana per i valori rilevati, dobbiamo procedere con un test non parametrico, il test di Wilcoxon dei ranghi con segno.

> a = c(214, 159, 169, 202, 103, 119, 200, 109, 132, 142, 194, 104, 219, 119, 234)
> b = c(159, 135, 141, 101, 102, 168, 62, 167, 174, 159, 66, 118, 181, 171, 112)
>
> wilcox.test(a,b, paired=TRUE)

Wilcoxon signed rank test

data: a and b
V = 80, p-value = 0.2769
alternative hypothesis: true location shift is not equal to 0


Essendo il p-value maggiore di 0.05, significa che le medie delle rilevazioni sono sostanzialmente rimaste inalterate (accettiamo l’ipotesi H0), quindi bloccare il traffico per un solo giorno non ha portato a nessun miglioramento per quanto riguarda l’inquinamento della città.
Il valore V = 80 corrisponde alla somma dei ranghi assegnati alle differenze con segno positivo. Con qualche acrobatismo matematico, possiamo calcolare manualmente la somma dei ranghi assegnati alle differenze con segno positivo, e la somma dei ranghi assegnati alle differenze con segno negativo, per confrontare questo intervallo con l’intervallo tabulato sulle tavole di Wilcoxon per campioni appaiati, e confermare la nostra decisione statistica. Ecco come fare per calcolare le due somme.

> a = c(214, 159, 169, 202, 103, 119, 200, 109, 132, 142, 194, 104, 219, 119, 234)
> b = c(159, 135, 141, 101, 102, 168, 62, 167, 174, 159, 66, 118, 181, 171, 112)
>
> diff = c(a - b)
#calcolo il vettore contenente le differenze tra tutti i valori di a e i valori di b
> diff.rank = rank(abs(diff)) #assegno i ranghi alle differenze calcolate prima, prese in valore assoluto; la funzione abs(x) dà in output il valore di x senza segno
> diff.rank.sign = diff.rank * sign(diff) #do il segno ai ranghi, richiamando i segni dei valori delle differenze
> ranghi.pos = sum(diff.rank.sign[diff.rank.sign > 0]) #calcolo la somma dei ranghi assegnati alle differenze con segno positivo, ossia maggiori di zero
> ranghi.neg = -sum(diff.rank.sign[diff.rank.sign < 0]) #calcolo la somma dei ranghi assegnati alle differenze con segno negativo, ossia minori di zero, cambiando di segno il risultato, che sarebbe logicamente negativo
> ranghi.pos #chiamo il risultato: esso corrisponde al valore V calcolato con il wilcox.test
[1] 80
> ranghi.neg #chiamo il risultato
[1] 40


L’intervallo calcolato è (40, 80). L’intervallo tabulato sulle tavole di Wilcoxon per campioni appaiati, con 15 differenze è (25, 95). Poiché l’intervallo calcolato è contenuto nell’intervallo tabulato, accettiamo l’ipotesi H0 di uguaglianza delle medie. Come preannunciato dal p-value, la chiusura delle strade al traffico non ha apportato alcun miglioramento in termini di tasso d’inquinamento.

NOTA.
Il test di Wilcoxon dei ranghi con segno prevede la NON assegnazione del rango a quelle differenze pari a zero. Pertanto con il metodo illustrato, si avrebbero risultati falsati, in quanto anche a differenze pari a zero, viene assegnato un rango. Si consiglia pertanto di verificare sempre i contenuti dei vari vettori che vengono calcolati. Se qualcuno ha tempo, può provare a costruire una funzione con le sequenza di calcoli da me utilizzata, aggiungendo la condizione di eliminare dall'assegnazione dei ranghi quelle differenze pari a zero. Io per ora non ho tempo, ma magari in futuro scriverò una funzione completamente automatizzata.

EDIT.
La risposta al dubbio espresso nella nota è molto più semplice di quanto avessi previsto! Per eliminare le differenze pari a zero dal calcolo, è sufficiente aggiungere la seguente istruzione:
diff <- diff[ diff != 0 ]
e il gioco è fatto!

2 commenti:

  1. Grazie mille, mi dava un errore e ora seguirò il tuo metodo!

    RispondiElimina
  2. posso chiedere? quando facciamo i ranghi con segno, elimino dal conteggio gli zeri. ma poi in tabella ritorno a cercare i range per n=totale o elimino anche in questa fase le coppie =a zero?
    grazie

    RispondiElimina