Prueba de aleatorización / permutación para vectores emparejados en R


9

No soy un experto, así que perdóname si parte de la terminología es un poco torpe. Estaremos encantados de proporcionar más información cuando sea necesario.

Tengo dos vectores de 50 valores numéricos emparejados en R. Quiero realizar una prueba de aleatorización o permutación de dos colas para determinar si sus diferencias se deben al azar o no.

Una prueba de permutación (también llamada prueba de aleatorización, prueba de aleatorización o prueba exacta) es un tipo de prueba de significación estadística en la que la distribución del estadístico de prueba bajo la hipótesis nula se obtiene calculando todos los valores posibles del estadístico de prueba bajo reordenamientos de las etiquetas en los puntos de datos observados.

Quiero hacer este tipo de prueba porque creo que las distribuciones de los valores en los vectores violan los supuestos de otras pruebas como la prueba t (por ejemplo, muchos de los valores numéricos en el vector son 0).

La permtestfunción en la biblioteca BHH2 , casi hace lo que quiero, pero funciona en todas las permutaciones , lo que tomará demasiado tiempo. En cambio, quiero estimar el valor p, muestreando un gran número de posibles permutaciones. Eché un vistazo al paquete de monedas , pero nada allí parece hacer una prueba de permutación con muestreo de vectores numéricos emparejados.250

Algunas búsquedas en Google me llevaron a este correo electrónico , lo que sugiere que la razón por la que no puedo encontrar un paquete para hacerlo es porque es una línea en R. Lamentablemente, no tengo suficiente experiencia con R para poder producir ese paquete. -transatlántico.

¿Existe algún paquete o método que realice una prueba de permutación emparejada de dos colas utilizando solo una muestra del espacio de permutación?

Si no, ¿alguien podría compartir un poco de código R para hacerlo?


3
Me parece que el paquete coin(entre varios otros) hace pruebas de aleatorización. Por ejemplo, vea la respuesta a esta pregunta (lea todo) . Si entiendo bien, los ejemplos cubren casos aproximados y exactos y cubren muestras independientes y dependientes.
Glen_b

1
Lo siento, para ser claros, por "leer todo" quiero decir "leer la respuesta superior hasta el final", aunque también es posible que desee ver la respuesta inferior.
Glen_b -Reinstale a Monica el

Casi lo único interesante de esa respuesta para las permutaciones emparejadas es oneway_test(y ~ x | pairs, distribution=approximate(B=9999))con library(coin).
Nakx

Respuestas:


12

Aunque en los comentarios apunté al uso del coinpaquete, creo que vale la pena ilustrar que una prueba de permutación / aleatorización es realmente bastante simple, así que lo he hecho.

Aquí escribo un código R para hacer una prueba de aleatorización para una prueba de ubicación de una muestra. La prueba voltea aleatoriamente los signos en las diferencias y calcula la media; esto es equivalente a asignar aleatoriamente cada par de valores a los grupos x e y. El siguiente código podría hacerse significativamente más corto (podría hacerlo en dos líneas con bastante facilidad, o incluso en una si no le importara un código más lento).

Este código tarda unos segundos en mi máquina:

# assumes the two samples are in 'x' and 'y' and x[i] and y[i] are paired
# set up:
B <- 99999
d <- x-y
m0 <- mean(d)

# perform a one-sample randomization test on d
# for the null hypothesis H0: mu_d = 0   vs H1 mu_d != 0  (i.e. two tailed)
# here the test statistic is the mean
rndmdist <- replicate(B,mean((rbinom(length(d),1,.5)*2-1)*d))

# two tailed p-value:
sum( abs(rndmdist) >= abs(m0))/length(rndmdist)

Eso es todo.

Tenga en cuenta que rbinom(length(d),1,.5)*2-1)da un signo aleatorio -1o 1... es decir, aleatorio, por lo que cuando multiplicamos por cualquier conjunto de signos d, es equivalente a asignar aleatoriamente +o -signos a las diferencias absolutas. [No importa con qué distribución de signos dcomience, ahora dtendrá signos aleatorios.]

Aquí, lo comparo con una prueba t en algunos datos inventados:

 set.seed(seed=438978)
 z=rnorm(50,10,2)
 x=z-rnorm(50,0,.5)
 y=z+.4+rnorm(50,0,.5)
 t.test(y-x) # gives p = 0.003156

 B <- 99999
 d <- x-y
 m0 <- mean(d)
 rndmdist <- replicate(B,mean((rbinom(length(d),1,.5)*2-1)*d))
 sum( abs(rndmdist) >= abs(m0))/length(rndmdist) 

Cuando la prueba t es válida, generalmente proporciona un valor p muy similar a la prueba de permutación completamente enumerada, y un valor p simulado como el anterior (cuando el número de simulaciones es suficientemente grande) convergerá a ese segundo valor p.

Al número de repeticiones utilizadas anteriormente, un valor p de permutación real (es decir, de la enumeración completa) de 0.05 se estimará dentro de 0.001 (es decir, dará un valor p de aleatorización entre 0.049 y 0.051) aproximadamente el 85% del tiempo y dentro de 0.002 más del 99.5% del tiempo.


Muy apreciado, gracias. ¿Cómo calculó la precisión del valor p?
Timothy Jones

1
Es solo la aproximación normal a una proporción binomial , usando el error estándar de una proporción ;se(pags^)=pags(1-pags)/ /norte.
Glen_b -Reinstate Monica

¿Por qué multiplicas la función rbinom por 2-1? Y luego d?

Para obtener signos aleatorios d, porque así es como funciona una prueba de permutación de la diferencia de medias para datos emparejados. Ver nuevos comentarios adicionales después de ese fragmento de código.
Glen_b -Reinstale a Monica el

1
@ Joe cuando añadimos la muestra observada Hará un número redondo
Glen_b -Reinstate Mónica

0

Aquí hay un código para realizar una prueba de permutación. Tengo datos allí, por ejemplo. x es la diferencia entre los dos vectores.

x <- c(5.1, 9.4, 7.2, 8.1, 8.8, 2.5, 4.2, 6.9, 5.5, 5.3)
m = 5
n = 5
xsum = sum(x)
asum = sum(x[1:m])
bsum = xsum - asum
truediff = asum/m - bsum/n
truediff
abstruediff = abs(truediff)
iter = 100000
difflist <- 1:iter
for(i in 1:iter) {
  s <- sample(x,m) # select a sample of size m
  pasum = sum(s)
  pbsum = sum(x) - sum(s)
  diff  = pasum/m - pbsum/n
  difflist[i] <- diff # add permutation difference to list
}
difflist  <- sort(difflist)
xquantile <- quantile(difflist,probs=c(.005, .01, .025, .05, .95, .975, .99, .995))
xquantile
pdist  <- quantile(difflist, probs=seq(0,1,1/iter))
ntail1 <- length(pdist[difflist <= -abstruediff])
tail1  <- ntail1/iter
tail1  # left-tail probability
ntail2 <- length(pdist[difflist >= abstruediff])
tail2  <- ntail2/iter
tail2  # right-tail probability
twotail = tail1 + tail2
twotail 
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.