Randomisierungs- / Permutationstest für gepaarte Vektoren in R.

9

Ich bin kein Experte, also vergib mir, wenn ein Teil der Terminologie etwas ungeschickt ist. Gerne stellen wir Ihnen bei Bedarf weitere Informationen zur Verfügung.

Ich habe zwei Vektoren mit 50 gepaarten numerischen Werten in R. Ich möchte einen zweiseitigen Randomisierungs- oder Permutationstest durchführen, um festzustellen, ob ihre Unterschiede zufällig sind oder nicht.

Ein Permutationstest (auch als Randomisierungstest, Re-Randomisierungstest oder exakter Test bezeichnet) ist eine Art statistischer Signifikanztest, bei dem die Verteilung der Teststatistik unter der Nullhypothese durch Berechnung aller möglichen Werte der Teststatistik erhalten wird unter Umlagerungen der Etiketten auf den beobachteten Datenpunkten.

Ich möchte diese Art von Test durchführen, weil ich glaube, dass die Verteilungen der Werte in den Vektoren die Annahmen anderer Tests wie des t-Tests verletzen (zum Beispiel sind viele der numerischen Werte im Vektor 0).

Die permtestFunktion in der BHH2-Bibliothek macht fast das, was ich will, aber sie arbeitet mit allen 250 Permutationen, was zu lange dauern wird. Stattdessen möchte ich den p-Wert schätzen, indem ich eine große Anzahl möglicher Permutationen abtaste. Ich hatte einen Blick in der Münze Paket, aber nichts scheint mit Abtasten von paarigen numerischen Vektoren eine Permutation Test zu tun.

Ein bisschen googeln hat mich zu dieser E-Mail geführt , was darauf hindeutet, dass ich kein Paket dafür finden kann, weil es ein Einzeiler in R ist. Leider habe ich nicht genug Erfahrung mit R, um dieses zu produzieren -Liner.

Gibt es ein Paket oder eine Methode, die einen zweiseitigen gepaarten Permutationstest nur mit einer Stichprobe des Permutationsraums durchführt?

Wenn nicht, könnte jemand ein kurzes Stück R-Code dafür freigeben?

Timothy Jones
quelle
3
Es sieht für mich so aus, als würde das Paket coin(unter anderem) Randomisierungstests durchführen. zB siehe die Antwort auf diese Frage (lies das Ganze) . Wenn ich richtig verstehe, decken die Beispiele sowohl ungefähre als auch genaue Fälle ab und decken sowohl unabhängige als auch abhängige Stichproben ab.
Glen_b -State Monica
1
Entschuldigung, um klar zu sein - mit "das Ganze lesen" meine ich "die obere Antwort vollständig durchlesen" - obwohl Sie vielleicht auch die untere Antwort betrachten möchten.
Glen_b -State Monica
Ziemlich das einzig Interessante an dieser Antwort für gepaarte Permutationen ist oneway_test(y ~ x | pairs, distribution=approximate(B=9999))mit library(coin).
Nakx

Antworten:

12

Obwohl ich in Kommentaren auf die Verwendung des coinPakets hingewiesen habe, denke ich, dass es sich lohnt zu veranschaulichen, dass ein Permutations- / Randomisierungstest wirklich recht einfach ist, also habe ich es getan.

Hier schreibe ich einen R-Code, um einen Randomisierungstest für einen Standorttest mit einer Stichprobe durchzuführen. Der Test dreht zufällig die Vorzeichen auf die Unterschiede und berechnet den Mittelwert; Dies entspricht der zufälligen Zuordnung jedes Wertepaars zu den x- und y-Gruppen. Der folgende Code könnte erheblich kürzer gemacht werden (ich könnte es leicht genug in zwei Zeilen machen, oder sogar in einer, wenn Ihnen langsamerer Code nichts ausmacht).

Dieser Code dauert auf meinem Computer einige Sekunden:

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

Das ist das Ganze.

Beachten Sie, dass dies rbinom(length(d),1,.5)*2-1)ein zufälliges -1oder 1... dh ein zufälliges Vorzeichen ergibt. Wenn wir also mit einem beliebigen Satz von Vorzeichen multiplizieren d, entspricht dies einer zufälligen Zuordnung +oder -Vorzeichen zu den absoluten Differenzen. [Es spielt keine Rolle, mit welcher Verteilung der Zeichen dSie beginnen, jetzt dhaben die zufälligen Zeichen.]

Hier vergleiche ich es mit einem T-Test für einige erfundene Daten:

 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) 

Wenn der t-Test gültig ist, ergibt er normalerweise einen sehr ähnlichen p-Wert wie der vollständig aufgezählte Permutationstest, und ein simulierter p-Wert wie oben (wenn die Anzahl der Simulationen ausreichend groß ist) konvergiert gegen diesen zweiten p-Wert.

Bei der Anzahl der oben verwendeten Replikationen wird ein echter Permutations-p-Wert (dh aus der vollständigen Aufzählung) von 0,05 in etwa 85% der Fälle auf 0,001 geschätzt (dh ergibt einen Randomisierungs-p-Wert zwischen 0,049 und 0,051) und innerhalb von 0,002 über 99,5% der Zeit.

Glen_b -Reinstate Monica
quelle
Sehr geschätzt, danke. Wie haben Sie die Genauigkeit des p-Wertes berechnet?
Timothy Jones
1
se(p^)=p(1- -p)/.n
Warum multiplizieren Sie die rbinom-Funktion mit 2-1? Und dann d?
Zufällige Anzeichen aktivieren d, denn so funktioniert ein Permutationstest der mittleren Differenz für gepaarte Daten. Nach diesem Code werden neue zusätzliche Kommentare angezeigt.
Glen_b -State Monica
1
@ Joe, wenn wir die beobachtete Probe hinzufügen, wird es eine runde Zahl machen
Glen_b -Reinstate Monica
0

Hier ist Code zum Durchführen eines Permutationstests. Ich habe dort zum Beispiel Daten. x ist die Differenz zwischen den beiden Vektoren.

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 
Lauren Goodwin
quelle