Sw

Switch em R

1 exercício

Sobre Switch

A função switch() pode ser um substituto conciso para uma longa série de testes if ... else if. A variável sobre a qual se faz o switch é, na maioria dos casos, uma string e, nesse caso, podes omitir as aspas do seletor.

star <- function(type) {
  switch(type,
    M = , # will "fall through" if no value given
    K = "red dwarf",
    G = "Earth-like",
    "bigger star" # only correct for O,B,A,F
  )
}

> star("M")
[1] "red dwarf"

Repara que as opções só avançam se o valor for deixado em branco, como acontece com M no exemplo acima. Não é preciso incluir instruções break, ao contrário do que acontece noutras linguagens.

O valor final pode ser um valor por omissão, como aqui, ou um stop() para lançar um erro, caso se pretenda que as condições sejam exaustivas. Fazer switch sobre um número inteiro é um pouco diferente: nesses casos, o valor por omissão é sempre NULL (que será abordado no conceito Nada).

Funções no dplyr

O switch do R base é bastante limitado: só faz uma correspondência exata a um único valor de entrada. Isto parecia razoável quando o R foi lançado, em 1993, mas precisa de ser melhorado para o uso moderno.

Note

Como referimos no conceito Conditionals, a coleção de pacotes tidyverse foi concebida para complementar (e, por vezes, substituir) a funcionalidade do R base sem afetar a compatibilidade com versões anteriores.

Os pacotes do tidyverse também têm documentação excelente e moderna, por isso seguir as ligações abaixo dar-te-á mais detalhes.

Podes trazer o pacote dplyr para o âmbito adicionando library(dplyr) (para o pacote individual) ou library(tidyverse) (para a coleção completa) ao topo do teu código.

A biblioteca dplyr disponibiliza duas funções extra relacionadas com o switch.

As funções recode_values e replace_values

Estas duas funções relacionadas permitem um mapeamento vetorizado, semelhante a um switch, de valores antigos para valores novos.

A principal diferença entre elas é que recode_values() cria um vetor totalmente novo, enquanto replace_values() permite atualizações parciais de um vetor existente.

A correspondência continua a ser exata, mas:

  • As opções à esquerda podem ser vetores, e o valor de entrada corresponde se qualquer elemento corresponder.
  • As opções à esquerda e os resultados à direita são ligados com um til ~ em vez de =.
  • Os valores em falta NA podem ser correspondidos explicitamente (isto será abordado no conceito Nada).
  • Pode especificar-se um valor por omissão em todos os casos.
library(dplyr)

x <- c("a", "b", "a", "d", "b", NA, "c", "e", "z")
recode_values(
  x,
  "a" ~ 1,
  "b" ~ 2,
  "c" ~ 3,
  c("d", "e") ~ 4, # either "d' or "e" will match
  NA ~ 0,          # matches missing values
  default = 100   # note the different syntax for the default
)
#> [1]   1   2   1   4   2   0   3   4 100
Note

Podes encontrar conselhos online sobre usar a função case_match() como um switch vetorizado.

Esta função foi descontinuada na versão 1.2.0 do dplyr (fevereiro de 2026). Tentativas de a usar vão agora produzir uma mensagem de aviso, a aconselhar o uso de recode_values() em vez dela.

A função case_when

case_when leva a sintaxe de case_match mais longe, ao permitir qualquer expressão lógica à esquerda do ~.

O vetor de entrada (x no exemplo abaixo) não é fornecido como argumento, só precisa de estar já definido.

x <- 1:10
case_when(
  x < 3 ~ "low",
  between(x, 3, 5) ~ "mid",
  between(x, 6, 8) ~ "high",
  .default = "what?"
)
#>  [1] "low"   "low"   "mid"   "mid"   "mid"   "high"  "high"  "high"  "what?" "what?"

A função between() também faz parte do dplyr.

As funções de string já foram abordadas e as expressões regulares serão o tema de um conceito posterior. Estas combinam muito bem com case_when.

library(stringr)

tracks <- "R C Python C# Elixir C++ Odin" |> str_split_1(" ")
tracks
#> [1] "R"      "C"      "Python" "C#"     "Elixir" "C++"    "Odin"  

case_when(
  str_starts(tracks, "C") ~ "C-like",
  str_starts(tracks, "[AEIOU]") ~ "vowel",
  .default = "other"
)
#> [1] "other"  "C-like" "other"  "C-like" "vowel"  "C-like" "vowel"
Editar via GitHub A ligação abre numa nova janela ou separador

Aprende Switch