2016-05-28 6 views
1

Gelman und Hill erklären Simulation in R. Auf Seite 139 sagen sie:R: Wie funktioniert vektorisierte ifelse im Zusammenhang mit mehrwertigen Ja/Nein-Parametern?

52% der Erwachsenen in den Vereinigten Staaten sind Frauen und 48% sind Männer. Die Höhen der Männer sind ungefähr normal verteilt mit mittleren 69,1 Zoll und Standard Abweichung 2,9 Zoll; Frauen mit Mittelwert 63,7 und Standardabweichung 2,7. Angenommen, wir wählen zufällig 10 Erwachsene. Was können wir über ihre durchschnittliche Höhe sagen?

sex <- rbinom (10, 1, .52) R code 
height <- ifelse (sex==0, rnorm (***10***, 69.1, 2.9), rnorm (***10***, 64.5, 2.7))  #"***"s added for emphasis. 
avg.height <- mean (height) 
print (avg.height) 

Ich verstehe nicht, was die beiden 10 tun in der Funktion rnorm.

Sex ist ein 10-Vektor. Wenn Geschlecht [1] 0 ist, wählt ifelse zehn Werte für die Höhe aus der Normalverteilung mit Mittelwert 69.1 ..., wenn Geschlecht [2] 1 ist, wählt iffelse 10 Werte für die Höhe von normal mit Mittelwert 64.5 und so weiter und nur Wert von Sex [10] wird bestimmen, was schließlich der Höhe zugeordnet wird.

Offensichtlich ist mein Verständnis falsch und es wählt die zehn Werte aus der richtigen Verteilung aus. Ich habe den Mittelwert der ersten Normalverteilung auf 669.1 geändert, um zu verstehen, wie er der Höhe einen Wert zuweist, und der obige Code tut, was er tun soll. Ich verstehe immer noch nicht, was die beiden 10 in den rnorm-Funktionen tun. Als ich die zwei 10 zu zwei 1 geändert habe, funktioniert alles wie es sollte. Kann mir bitte jemand erklären, wie zehn Werte für die Höhe im obigen Code zugewiesen sind.

+0

Es läuft 'rnorm' unter verschiedenen Parametern, abhängig vom Ergebnis von' sex == 0'. 'ifelse()' gibt einen Vektor mit der Länge seiner ersten Eingabe (10) zurück, also muss das Ergebnis die Länge 10 haben. –

+0

Das Ergebnis muss die Länge 10 haben, aber nicht die Werte 'ja' und' nein'. Ich denke, das ist die Verwirrung. – joemienko

+0

Sie können 'ifelse' einfach so in die Konsole eingeben, um seinen Code zu sehen. Es läuft auf 'ans <- Test hinaus; ans [Test] <- ja [Test]; ans [! test] <- nein [! test]; return (ans) ' – Frank

Antwort

2

Tatsächlich gibt es einen Unterschied bei der Definition der richtigen Anzahl von Beobachtungen. Das liegt daran, dass die Funktion ifelse zunächst die Daten für beide Optionen wie ein dat.frame "abschließt" und dann die if-Auswahl für jede Zeile anwendet. Da sex ein 10-Element-Vektor ist, sind die 10s in der rnorm-Funktion notwendig, um die richtige Antwort zu erhalten. Sie können sehen, dass die 10s durch 1s ersetzt werden, indem ein Vektor mit einem oder zehn Elementen an ifelse übergeben wird und das seed für jede zufällige Generation zurückgesetzt wird. Siehe unten:

> set.seed(12345) 
> sex <- rbinom (10, 1, .52) 
> 
> set.seed(12345) 
> ifelse (sex[1]==0, rnorm (1, 69.1, 2.9), rnorm (1, 64.5, 2.7)) #correct 
[1] 70.79803 
> set.seed(12345) 
> ifelse (sex[1]==0, rnorm (10, 69.1, 2.9), rnorm (10, 64.5, 2.7)) #almost true 
[1] 70.79803 
> set.seed(12345) 
> ifelse (sex==0, rnorm (1, 69.1, 2.9), rnorm (1, 64.5, 2.7)) #wrong 
[1] 70.79803 70.79803 70.79803 70.79803 66.41556 66.41556 66.41556 66.41556 70.79803 
[10] 70.79803 
> set.seed(12345) 
> ifelse (sex==0, rnorm (10, 69.1, 2.9), rnorm (10, 64.5, 2.7)) #correct 
[1] 70.79803 71.15745 68.78302 67.78486 62.47356 66.70563 62.10683 63.60474 68.27594 
[10] 66.43397 
> # is this what ifelse is doing? 
> set.seed(12345) 
> da=data.frame(sex, M=rnorm (10, 69.1, 2.9), W=rnorm (10, 64.5, 2.7)) 
> da$res <- apply(da,1,function(sx)ifelse(sx[1]==0,sx[2],sx[3])) 
> da$res 
[1] 70.79803 71.15745 68.78302 67.78486 62.47356 66.70563 62.10683 63.60474 68.27594 
[10] 66.43397 
+1

* löschte meine vorherige Antwort, um Verwirrung zu vermeiden, da ich jetzt denke, dass sie falsch war. @ Roberts Antwort ergibt mehr Sinn für mich. – joemienko

Verwandte Themen