Come testare l'ipotesi che la correlazione è uguale al valore dato usando R?


10

Esiste una funzione per verificare l'ipotesi che la correlazione di due vettori sia uguale a un dato numero, diciamo 0.75? Usando cor.test posso testare cor = 0 e posso vedere se 0.75 è all'interno dell'intervallo di confidenza. Ma esiste una funzione per calcolare il valore p per cor = 0,75?

x <- rnorm(10)
y <- x+rnorm(10)
cor.test(x, y)

2
Questa domanda è più adatta a crossvalidated.com
Sacha Epskamp,

1
@sacha - controlla prima le FAQ di un sito, le faq del sito stats.se raccomandano che le domande di programmazione usando R siano pubblicate su SO.
Kev,

La domanda "esiste una funzione per calcolare il valore p per cor = 0,75?" non ha nulla a che fare con la programmazione. È una domanda statistica.
Sacha Epskamp,

Consulterò la gente delle statistiche e vedrò cosa ne pensano.
Kev,

1
@mosaic Per favore, registra il tuo account qui. In questo modo, sarai in grado di associare il tuo account SO a quello attuale.
chl

Risposte:


12

Usando la varianza che stabilizza la trasformazione atan di Fisher , puoi ottenere il valore p come

pnorm( 0.5 * log( (1+r)/(1-r) ), mean = 0.5 * log( (1+0.75)/(1-0.75) ), sd = 1/sqrt(n-3) )

o qualunque versione del valore p unilaterale / bilaterale a cui sei interessato. Ovviamente, hai bisogno della dimensione ndel campione e del coefficiente di correlazione del campione rcome input per questo.


+1 Grazie per la tua risposta - Non mi era chiaro che la trasformazione di Fisher fosse appropriata o meno in questo caso, ma la tua risposta aiuta a chiarirlo.
Gavin Simpson,

@Gavin, hai cercato di chiarire quale fosse l'intenzione del PO. Ho solo ipotizzato la situazione modale in cui sorgeva una domanda del genere, e sembra che abbia funzionato :).
StasK

4

La distribuzione di r_hat attorno a rho è data da questa funzione R adattata dal codice Matlab nella pagina web di Xu Cui . Non è così difficile trasformarlo in una stima per la probabilità che un valore osservato "r" sia improbabile dato una dimensione del campione di "n" e un ipotetico valore reale di "ro".

corrdist <- function (r, ro, n) {
        y = (n-2) * gamma(n-1) * (1-ro^2)^((n-1)/2) * (1-r^2)^((n-4)/2)
        y = y/ (sqrt(2*pi) * gamma(n-1/2) * (1-ro*r)^(n-3/2))
        y = y* (1+ 1/4*(ro*r+1)/(2*n-1) + 9/16*(ro*r+1)^2 / (2*n-1)/(2*n+1)) }

Quindi con quella funzione puoi tracciare la distribuzione di un valore rho nullo di 0,75, calcolare la probabilità che r_hat sia inferiore a 0,6 e ombreggia in quell'area sul grafico:

 plot(seq(-1,1,.01), corrdist( seq(-1,1,.01), 0.75, 10) ,type="l")
 integrate(corrdist, lower=-1, upper=0.6, ro=0.75, n=10)
# 0.1819533 with absolute error < 2e-09
 polygon(x=c(seq(-1,0.6, length=100), 0.6, 0), 
         y=c(sapply(seq(-1,0.6, length=100), 
         corrdist, ro=0.75, n=10), 0,0), col="grey")

inserisci qui la descrizione dell'immagine


4

Un altro approccio che può essere meno esatto della trasformazione di Fisher, ma penso che potrebbe essere più intuitivo (e potrebbe dare idee sul significato pratico oltre al significato statistico) è il test visivo:

 Buja, A., Cook, D. Hofmann, H., Lawrence, M. Lee, E.-K., Swayne,
 D.F and Wickham, H. (2009) Statistical Inference for exploratory
 data analysis and model diagnostics Phil. Trans. R. Soc. A 2009
 367, 4361-4383 doi: 10.1098/rsta.2009.0120

C'è un'implementazione di questo nella vis.testfunzione nel TeachingDemospacchetto per R. Un possibile modo per eseguirlo per il tuo esempio è:

vt.scattercor <- function(x,y,r,...,orig=TRUE)
{
    require('MASS')
    par(mar=c(2.5,2.5,1,1)+0.1)
    if(orig) {
        plot(x,y, xlab="", ylab="", ...)
    } else {
        mu <- c(mean(x), mean(y))
        var <- var( cbind(x,y) )
        var[ rbind( 1:2, 2:1 ) ] <- r * sqrt(var[1,1]*var[2,2])
        tmp <- mvrnorm( length(x), mu, var )
        plot( tmp[,1], tmp[,2], xlab="", ylab="", ...)
    }
}

test1 <- mvrnorm(100, c(0,0), rbind( c(1,.75), c(.75,1) ) )
test2 <- mvrnorm(100, c(0,0), rbind( c(1,.5), c(.5,1) ) )

vis.test( test1[,1], test1[,2], r=0.75, FUN=vt.scattercor )
vis.test( test2[,1], test2[,2], r=0.75, FUN=vt.scattercor )

Naturalmente se i tuoi dati reali non sono normali o la relazione non è lineare, allora sarà facilmente acquisito con il codice sopra. Se si desidera testare simultaneamente per quelli, allora il codice sopra lo farebbe, o il codice sopra potrebbe essere adattato per rappresentare meglio la natura dei dati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.