web-dev-qa-db-fra.com

Une version matricielle de cor.test ()

Cor.test() prend des vecteurs x et y comme arguments, mais j'ai une matrice entière de données que je veux tester, par paire. Cor() prend très bien cette matrice en argument, et j'espère trouver un moyen de faire de même pour cor.test().

Le conseil commun des autres semble être d'utiliser cor.prob():

https://stat.ethz.ch/pipermail/r-help/2001-November/016201.html

Mais ces valeurs p ne sont pas les mêmes que celles générées par cor.test() !!! Cor.test() semble également mieux équipé pour gérer la suppression par paire (il me manque un peu de données dans mon ensemble de données) que cor.prob().

Quelqu'un at-il des alternatives à cor.prob()? Si la solution implique des boucles imbriquées, qu'il en soit ainsi (je suis assez nouveau pour R pour que cela me pose problème).

26
Atticus29

corr.test Dans le package psych est conçu pour cela:

library("psych")
data(sat.act)
corr.test(sat.act)

Comme indiqué dans les commentaires, pour reproduire les valeurs p - de la fonction de base cor.test() sur toute la matrice, vous devez désactiver le réglage de la p - valeurs pour les comparaisons multiples (la valeur par défaut est d'utiliser la méthode d'ajustement de Holm):

 corr.test(sat.act, adjust = "none")

38
Sacha Epskamp

Si vous êtes strictement après les valeurs p dans un format matriciel de cor.test voici une solution sans vergogne volée à Vincent ( LIEN ):

cor.test.p <- function(x){
    FUN <- function(x, y) cor.test(x, y)[["p.value"]]
    z <- outer(
      colnames(x), 
      colnames(x), 
      Vectorize(function(i,j) FUN(x[,i], x[,j]))
    )
    dimnames(z) <- list(colnames(x), colnames(x))
    z
}

cor.test.p(mtcars)

Remarque: Tommy fournit également une solution plus rapide mais moins facile à mettre en œuvre. Oh et non pour les boucles :)

Edit J'ai une fonction v_outer dans mon package qdapTools ce qui rend cette tâche assez simple:

library(qdapTools)
(out <- v_outer(mtcars, function(x, y) cor.test(x, y)[["p.value"]]))
print(out, digits=4)  # for more digits
13
Tyler Rinker

La façon la plus simple est probablement d'utiliser la fonction rcorr() de Hmisc. Cela ne prendra qu'une matrice, utilisez donc rcorr(as.matrix(x)) si vos données sont dans un data.frame. Il vous renverra une liste avec: 1) matrice de r par paire, 2) matrice de n par paire, 3) matrice de valeurs p pour les r. Il ignore automatiquement les données manquantes.

Idéalement, une fonction de ce type devrait également prendre data.frames et également produire des intervalles de confiance en ligne avec le ' New Statistics '.

5
Deleet

La solution acceptée (fonction corr.test dans le package psych) fonctionne, mais est extrêmement lente pour les grandes matrices. Je travaillais avec une matrice d'expression génique (~ 20 000 par ~ 1 000) corrélée à une matrice de sensibilité aux médicaments (~ 1 000 par ~ 500) et j'ai dû l'arrêter car cela prenait une éternité.

J'ai pris du code dans le paquet psych et j'ai utilisé la fonction cor () directement à la place et j'ai obtenu de bien meilleurs résultats:

# find (pairwise complete) correlation matrix between two matrices x and y
# compare to corr.test(x, y, adjust = "none")
n <- t(!is.na(x)) %*% (!is.na(y)) # same as count.pairwise(x,y) from psych package
r <- cor(x, y, use = "pairwise.complete.obs") # MUCH MUCH faster than corr.test()
cor2pvalue = function(r, n) {
  t <- (r*sqrt(n-2))/sqrt(1-r^2)
  p <- 2*(1 - pt(abs(t),(n-2)))
  se <- sqrt((1-r*r)/(n-2))
  out <- list(r, n, t, p, se)
  names(out) <- c("r", "n", "t", "p", "se")
  return(out)
}
# get a list with matrices of correlation, pvalues, standard error, etc.
result = cor2pvalue(r,n)

Même avec deux matrices 100 x 200, la différence était stupéfiante. Une seconde ou deux contre 45 secondes.

> system.time(test_func(x,y))
   user  system elapsed 
  0.308   2.452   0.130 
> system.time(corr.test(x,y, adjust = "none"))
   user  system elapsed 
 45.004   3.276  45.814 
3
Nick Clark