Jak używać instrukcji switch w funkcjach języka R?


81

Chciałbym użyć dla mojej funkcji w R instrukcji, switch()aby wyzwolić różne obliczenia w zależności od wartości argumentu funkcji.

Na przykład w Matlabie możesz to zrobić pisząc

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

Znalazłem to post - użycie instrukcji switch () - które wyjaśniają, jak używać switch, ale nie są dla mnie pomocne, ponieważ chcę wykonywać bardziej wyrafinowane obliczenia (operacje na macierzach), a nie proste mean.

Odpowiedzi:


112

Cóż, switchprawdopodobnie tak naprawdę nie było przeznaczone do pracy w ten sposób, ale możesz:

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

... każdy przypadek jest wyrażeniem - zwykle jest to po prostu prosta rzecz, ale tutaj używam kręconego bloku, abyś mógł włożyć tam dowolny kod, który chcesz ...


6
czy istnieje sposób na zrobienie tego bez porównywania ze stringami? wydaje się to bardzo nieefektywne.
— Jules GM

10
Jako nowy użytkownik switch(), zastanawiam się, dlaczego mówisz, że nie ma tak działać. Czego jeszcze można by się spodziewać po instrukcji switch?
— eric_kernfeld

46

te różne sposoby przełączania ...

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

42

Mam nadzieję, że ten przykład pomoże. Możesz użyć nawiasów klamrowych, aby upewnić się, że masz wszystko zawarte w kolesiu zmieniacza przełączników (przepraszam, nie znam terminu technicznego, ale termin poprzedzający znak =, który zmienia to, co się dzieje). Myślę o przełączniku jako o bardziej kontrolowanej grupie if () {} else {}instrukcji.

Za każdym razem funkcja przełącznika jest taka sama, ale polecenie, które dostarczamy, zmienia się.

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!")
)

Tutaj znajduje się wewnątrz funkcji:

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

0

To jest bardziej ogólna odpowiedź na brakującą konstrukcję „Select cond1, stmt1, ... else stmtelse” w R. Jest trochę gazowa, ale działa i przypomina instrukcję switch obecną w 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
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.