Cálculo de valor p desconocido

9

Recientemente estaba depurando un script R y encontré algo muy extraño, el autor definió su propia función de valor p

pval <- function(x, y){
    if (x+y<20) { # x + y is small, requires R.basic
        p1<- nChooseK(x+y,x) * 2^-(x+y+1);
        p2<- nChooseK(x+y,y) * 2^-(x+y+1);
        pvalue = max(p1, p2)
    }
    else { # if x+y is large, use approximation
        log_p1 <- (x+y)*log(x+y) - x*log(x) - y*log(y) - (x+y+1)*log(2);
        pvalue<-exp(log_p1);
    }
    return(pvalue)
}

Donde X e Y son valores valores positivos mayores que 0. El caso <20 parece ser un cálculo para algún tipo de distribución hipergeométrica (¿algo similar a la prueba de Fisher?) ¿Alguien sabe cuál es el otro cálculo? Como nota al margen, estoy tratando de optimizar este código para tratar de descubrir la función R adecuada para llamar y reemplazar esto.

Editar: la fórmula que detalla el papel para el cálculo del valor p se puede encontrar aquí (debe hacer clic en pdf para ver las fórmulas) Los métodos comienzan en la página 8 del pdf y la fórmula en cuestión se puede encontrar en la página 9 en (1). La distribución que suponen es un Poisson.

yingw
fuente

Respuestas:

15

Parece que lo segundo es una aproximación al cálculo que se usa para el x+y < 20caso, pero basado en la aproximación de Stirling .

Normalmente, cuando se usa para este tipo de aproximación, las personas usarían al menos el siguiente término adicional (el factor de en la aproximación paran! ), lo que mejoraría la aproximación relativa sustancialmente paranpequeño.2πnn!n

Por ejemplo, si e y son ambos 10, el primer cálculo da aproximadamente 0.088 mientras que la aproximación cuando el factor de xy está incluido en todos los términos es aproximadamente 0.089, lo suficientemente cerca para la mayoría de los propósitos ... pero omitir ese término en la aproximación da 0.5, ¡lo cual realmente no es lo suficientemente cerca! El autor de esa función claramente no se ha molestado en verificar la precisión de su aproximación en el caso límite.2πn

Para este propósito, el autor probablemente debería simplemente haber llamado a la lgammafunción incorporada, específicamente, al usar esto en lugar de lo que tiene para log_p1:

log_p1 <- lgamma(x+y+1)-lgamma(x+1)-lgamma(y+1)-(x+y+1)*log(2)

lgamma(x+1)log(x!)

Del mismo modo, no estoy seguro de por qué el autor no usa la choosefunción incorporada en la primera parte, una función que viene en la distribución estándar de R. De hecho, la función de distribución relevante probablemente también esté incorporada.

lgammachoosechoose(1000,500)lgammaxy

Con más información, debería ser posible identificar la fuente de la prueba. Supongo que el escritor lo ha tomado de alguna parte, por lo que debería ser posible rastrearlo. ¿Tienes algún contexto para esto?

Cuando dice 'optimizar', ¿quiere decir que sea más rápido, más corto, más fácil de mantener o algo más?


Edite después de leer rápidamente sobre el periódico:

Los autores parecen estar equivocados en varios puntos. La prueba exacta de Fisher no asume que los márgenes son fijos, simplemente los condiciona , lo cual no es lo mismo, como se discute, por ejemplo, aquí , con referencias. De hecho, parecen ignorar por completo el debate sobre el condicionamiento en los márgenes y por qué se hace. Los enlaces allí valen la pena leer.

[Proceden de 'La prueba de Fisher siempre es más conservadora que la nuestra' a la afirmación de que la prueba de Fisher es demasiado conservadora ... lo que no necesariamente sigue a menos que sea incorrecto condicionar . Tendrían que establecer eso, pero dado que es algo sobre lo que los estadísticos han estado discutiendo durante aproximadamente 80 años, y estos autores parecen no saber por qué se realiza el acondicionamiento, no creo que estos muchachos hayan llegado al fondo de ese problema. .]

Los autores del artículo al menos parecen entender que las probabilidades que dan deben acumularse para dar valores p; por ejemplo, cerca de la mitad de la primera columna de la página 5 (énfasis mío):

La significancia estadística según la prueba exacta de Fisher para tal resultado es 4.6% (valor P de dos colas, es decir, la probabilidad de que tal tabla ocurra en la hipótesis de que las frecuencias de actina EST son independientes de las bibliotecas de ADNc). En comparación, el valor P calculado a partir de la forma acumulativa (Ecuación 9, ver Métodos) de la Ecuación 2 (es decir, para que la frecuencia relativa de las EST de actina sea la misma en ambas bibliotecas, dado que se observan al menos 11 EST relacionadas en la biblioteca del hígado después de que se observaron dos en la biblioteca del cerebro) es 1.6%.

(aunque no estoy seguro de estar de acuerdo con su cálculo del valor allí; tendría que verificarlo cuidadosamente para ver qué están haciendo realmente con la otra cola).

No creo que el programa haga eso.

xx+y

Ni siquiera estoy convencido de que la suma de sus probabilidades sea 1 en este punto.

Hay mucho más que decir aquí, pero la pregunta no es sobre el documento, sino sobre la implementación en el programa.

-

De todos modos, el resultado es que, al menos, el documento identifica correctamente que los valores p consisten en una suma de probabilidades como las de la ecuación 2, pero el programa no . (Consulte las ecuaciones 9a y 9b en la sección Métodos del documento).

El código simplemente está mal en eso.

[Podría usar pbinom, como implicaría el comentario de @ whuber, para calcular las probabilidades individuales (pero no la cola, ya que no es una prueba binomial ya que la estructuran), pero luego hay un factor adicional de 1/2 en su ecuación 2, por lo que si desea replicar los resultados en el documento, debe modificarlos.]

Puede obtenerlo, con un poco de tocar el violín, desde pnbinom-

kthkth

(k+r-1k)(1-pag)rpagk,

pag=norte1/ /(norte1+norte2)k=Xr=y+1

y

Eso sería malo.

Glen_b -Reinstate a Monica
fuente
1
+1 Buena explicación. Hay algunos problemas adicionales con este código. No es necesario calcular p2en absoluto; el menor de p1y p2corresponde al menor de xy y, respectivamente, eso es una ineficiencia. Un posible error es que la segunda rama del condicional no se puede calcular p2y solo se usa p1. También sospecho que el código podría ser completamente erróneo, porque no parece calcular un valor p: es solo la mitad de una probabilidad binomial y tal vez debería ser una probabilidad de cola . ¿Por qué no solo usar pbinom/ dbinomy terminar con esto?
whuber
Gracias por la excelente respuesta, pude localizar la fuente de la fórmula: genome.cshlp.org/content/7/10/986.short . Quería cambiarla para que fuera más rápida y fácil de mantener / leer.
yingw
Gracias por el papel; fue útil para descubrir qué estaba pasando en el código. Qué boba.
Glen_b -Reinstate Monica
1
+1. ¡Esta es una publicación que no debería ser wiki comunitaria! Creo que se debe a las 14 revoluciones, pero en este caso son todas tuyas. Su diligencia ha sido castigada!
Darren Cook
Gracias por el voto de confianza. Sí, seguí volviendo y haciendo mejoras a medida que leía el documento, pero supongo que es mi culpa en parte por no lograr el resultado final de manera más eficiente.
Glen_b -Reinstale a Monica el