Warum können die ifelse-statementen von R nicht Vektoren zurückgeben?

Ich habe festgestellt, dass Rs iffelse-Statements von Zeit zu Zeit ziemlich praktisch sind. Beispielsweise:

ifelse(TRUE,1,2) # [1] 1 ifelse(FALSE,1,2) # [1] 2 

Aber ich bin etwas verwirrt durch das folgende Verhalten.

 ifelse(TRUE,c(1,2),c(3,4)) # [1] 1 ifelse(FALSE,c(1,2),c(3,4)) # [1] 3 

Ist das eine Design-Wahl, die über meinem Paygrade liegt?

   

Die Dokumentation für ifelse besagt:

ifelse gibt einen Wert mit der gleichen Form wie test der mit Elementen gefüllt ist, die entweder mit yes oder no abhängig davon, ob das Element des test TRUE oder FALSE .

Da Sie Testwerte der Länge 1 übergeben, erhalten Sie Ergebnisse der Länge 1. Wenn Sie längere Testvektoren übergeben, erhalten Sie längere Ergebnisse:

 > ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4)) [1] 1 4 

Also ist ifelse für den speziellen Zweck bestimmt, einen Vektor von booleschen Werten zu testen und einen Vektor gleicher Länge zurückzugeben, der mit Elementen gefüllt ist, die aus den (Vektor-) yes und no Argumenten stammen.

Es ist eine häufige Verwirrung, wegen des Namens der function, dies zu verwenden, wenn Sie wirklich nur eine normale if () {} else {} Konstruktion wünschen.

Ich wette, Sie wollen eine einfache if statement anstelle von ifelse – in R, if es sich nicht nur um eine Kontrollfluss-Struktur handelt, kann es einen Wert zurückgeben:

 > if(TRUE) c(1,2) else c(3,4) [1] 1 2 > if(FALSE) c(1,2) else c(3,4) [1] 3 4 

Ja, ich denke, ifelse () ist wirklich dafür gedacht, wenn Sie einen großen langen Vektor von Tests haben und jede auf eine von zwei Optionen abbilden wollen. Zum Beispiel mache ich auf diese Weise oft colors für plot ():

 plot(x,y, col = ifelse(x>2, 'red', 'blue')) 

Wenn Sie einen großen langen Vektor von Tests hatten, aber Paare für Ausgaben wollten, könnten Sie vielleicht sapply() oder plyr llply() oder etwas llply() .

Beachten Sie, dass Sie das Problem umgehen können, wenn Sie das Ergebnis innerhalb des ifelse zuweisen:

 ifelse(TRUE, a < - c(1,2), a <- c(3,4)) a # [1] 1 2 ifelse(FALSE, a <- c(1,2), a <- c(3,4)) a # [1] 3 4 

Manchmal benötigt der Benutzer nur eine switch statement anstelle eines ifelse . In diesem Fall:

 condition < - TRUE switch(2-condition, c(1, 2), c(3, 4)) #### [1] 1 2 

(Das ist eine andere Syntaxoption von Ken Williams 'Antwort)

Hier ist ein ähnlicher Ansatz wie bei Cath, aber er kann mit bereits zugewiesenen Vektoren arbeiten

Es basiert auf der Verwendung von get() wie folgt:

 a < - c(1,2) b <- c(3,4) get(ifelse(TRUE, "a", "b")) # [1] 1 2