Wie verwende ich die switch-Anweisung in R-Funktionen?

80

Ich möchte für meine Funktion in R die Anweisung verwenden switch(), um je nach Wert des Funktionsarguments eine andere Berechnung auszulösen.

In Matlab können Sie dies beispielsweise schriftlich tun

switch(AA)        
case '1'   
...   
case '2'   
...   
case '3'  
...  
end

Ich fand diese Verwendung der post - switch () - Anweisung , die die Verwendung erklärt switch, aber für mich nicht wirklich hilfreich ist, da ich eine komplexere Berechnung (Matrixoperationen) durchführen möchte und keine einfache mean.

Simon
quelle

Antworten:

110

Nun, switchwahrscheinlich sollte das nicht so funktionieren, aber Sie können:

AA = 'foo'
switch(AA, 
foo={
  # case 'foo' here...
  print('foo')
},
bar={
  # case 'bar' here...
  print('bar')    
},
{
   print('default')
}
)

... jeder Fall ist ein Ausdruck - normalerweise nur eine einfache Sache, aber hier verwende ich einen geschweiften Block, damit Sie den gewünschten Code dort einfügen können ...

Tommy
quelle
6
Gibt es eine Möglichkeit, dies zu tun, ohne mit Zeichenfolgen zu vergleichen? das scheint weitgehend ineffizient.
Jules GM
9
Als neuer Benutzer von switch()frage ich mich, warum Sie sagen, dass es nicht so funktionieren soll. Was würden Sie sonst von einer switch-Anweisung erwarten?
eric_kernfeld
46

diese verschiedenen Arten des Wechsels ...

# by index
switch(1, "one", "two")
## [1] "one"


# by index with complex expressions
switch(2, {"one"}, {"two"})
## [1] "two"


# by index with complex named expression
switch(1, foo={"one"}, bar={"two"})
## [1] "one"


# by name with complex named expression
switch("bar", foo={"one"}, bar={"two"})
## [1] "two"
Petermeissner
quelle
41

Ich hoffe dieses Beispiel hilft. Sie können die geschweiften Klammern verwenden, um sicherzustellen, dass alles in dem Umschalter enthalten ist (leider kennen Sie den Fachbegriff nicht, aber den Begriff vor dem = -Zeichen, der ändert, was passiert). Ich stelle mir Switch als eine kontrollierte Reihe von if () {} else {}Aussagen vor.

Jedes Mal, wenn die Schaltfunktion dieselbe ist, ändert sich jedoch der von uns bereitgestellte Befehl.

do.this <- "T1"

switch(do.this,
    T1={X <- t(mtcars)
        colSums(mtcars)%*%X
    },
    T2={X <- colMeans(mtcars)
        outer(X, X)
    },
    stop("Enter something that switches me!")
)
#########################################################
do.this <- "T2"

switch(do.this,
    T1={X <- t(mtcars)
        colSums(mtcars)%*%X
    },
    T2={X <- colMeans(mtcars)
        outer(X, X)
    },
    stop("Enter something that switches me!")
)
########################################################
do.this <- "T3"

switch(do.this,
    T1={X <- t(mtcars)
        colSums(mtcars)%*%X
    },
    T2={X <- colMeans(mtcars)
        outer(X, X)
    },
    stop("Enter something that switches me!")
)

Hier ist es in einer Funktion:

FUN <- function(df, do.this){
    switch(do.this,
        T1={X <- t(df)
            P <- colSums(df)%*%X
        },
        T2={X <- colMeans(df)
            P <- outer(X, X)
        },
        stop("Enter something that switches me!")
    )
    return(P)
}

FUN(mtcars, "T1")
FUN(mtcars, "T2")
FUN(mtcars, "T3")
Tyler Rinker
quelle
1

Dies ist eine allgemeinere Antwort auf die fehlende Anweisung "Select cond1, stmt1, ... else stmtelse" in R. Es ist ein bisschen gasförmig, aber es funktioniert und ähnelt der switch-Anweisung in C.

while (TRUE) {
  if (is.na(val)) {
    val <- "NULL"
    break
  }
  if (inherits(val, "POSIXct") || inherits(val, "POSIXt")) {
    val <- paste0("#",  format(val, "%Y-%m-%d %H:%M:%S"), "#")
    break
  }
  if (inherits(val, "Date")) {
    val <- paste0("#",  format(val, "%Y-%m-%d"), "#")
    break
  }
  if (is.numeric(val)) break
  val <- paste0("'", gsub("'", "''", val), "'")
  break
}
Rolf L.
quelle