Comment tester l'hypothèse que la corrélation est égale à une valeur donnée en utilisant R?

10

Existe-t-il une fonction pour tester l'hypothèse que la corrélation de deux vecteurs est égale à un nombre donné, disons 0,75? En utilisant cor.test, je peux tester cor = 0 et je peux voir si 0,75 est à l'intérieur de l'intervalle de confiance. Mais existe-t-il une fonction pour calculer la valeur de p pour cor = 0,75?

x <- rnorm(10)
y <- x+rnorm(10)
cor.test(x, y)
mosaïque
la source
2
Cette question est mieux adaptée pour crossvalidated.com
Sacha Epskamp
1
@sacha - veuillez d'abord consulter la FAQ d'un site, la FAQ du site stats.se recommande que les questions de programmation utilisant R soient publiées sur SO.
Kev
La question "existe-t-il une fonction pour calculer la valeur de p pour cor = 0,75?" n'a rien à voir avec la programmation. C'est une question statistique.
Sacha Epskamp
Je vais consulter les gens de stats et voir ce qu'ils en pensent.
Kev
1
@mosaic Veuillez enregistrer votre compte ici. De cette façon, vous pourrez associer votre compte SO à celui actuel.
chl

Réponses:

12

En utilisant la variance stabilisant la transformation atan de Fisher , vous pouvez obtenir la valeur de p comme

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

ou quelle que soit la version de la valeur de p unilatérale / bilatérale qui vous intéresse. Évidemment, vous avez besoin de la taille de nl'échantillon et du coefficient de corrélation d'échantillon rcomme entrées pour cela.

StasK
la source
+1 Merci pour votre réponse - Il n'était pas clair pour moi que la transformation de Fisher était appropriée ou non dans ce cas, mais votre réponse aide à clarifier cela.
Gavin Simpson
@Gavin, vous avez essayé de clarifier l'intention du PO. Je viens de supposer la situation modale dans laquelle une question comme celle-ci se poserait, et il semble que cela a fonctionné :).
StasK
4

La distribution de r_hat autour de rho est donnée par cette fonction R adaptée du code Matlab sur la page web de Xu Cui . Il n'est pas si difficile de transformer cela en une estimation de la probabilité qu'une valeur observée "r" soit improbable étant donné une taille d'échantillon de "n" et une valeur hypothétique vraie de "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)) }

Ensuite, avec cette fonction, vous pouvez tracer la distribution d'un rho nul de 0,75, calculer la probabilité que r_hat soit inférieur à 0,6 et l'ombre dans cette zone sur le tracé:

 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")

entrez la description de l'image ici

DWin
la source
4

Une autre approche qui peut être moins exacte que la transformation de Fisher, mais je pense qu'elle pourrait être plus intuitive (et pourrait donner des idées sur la signification pratique en plus de la signification statistique) est le test visuel:

 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

Il y a une implémentation de ceci dans la vis.testfonction dans le TeachingDemospackage pour R. Une façon possible de l'exécuter pour votre exemple est:

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 )

Bien sûr, si vos données réelles ne sont pas normales ou si la relation n'est pas linéaire, cela sera facilement détecté avec le code ci-dessus. Si vous souhaitez tester simultanément ceux-ci, le code ci-dessus le ferait ou le code ci-dessus pourrait être adapté pour mieux représenter la nature des données.

Greg Snow
la source