Menu

If Else em R: if, else if, ifelse() e switch()

Lógica condicional em R - a sintaxe de if/else if/else, a armadilha das chaves que quebra scripts, o ifelse() vetorizado para vetores inteiros e switch() para escolhas múltiplas.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

A Instrução if

Uma instrução if em R executa um bloco de código apenas quando uma condição é TRUE. A condição vai entre parênteses, o código entre chaves, e um else opcional fornece o que acontece caso contrário:

A condição score >= 60 avalia para um único TRUE, então o primeiro ramo executa. Os operadores de comparação e lógicos - ==, >=, &&, %in% e companhia - são o material com que você constrói essas condições.

Para mais de dois desfechos, encadeie verificações com else if. O R percorre a cadeia da primeira condição para baixo e executa o primeiro ramo cuja condição é TRUE, pulando o resto:

A ordem importa: como 85 >= 80 é verificado antes de 85 >= 70, a nota é "B". Se você ordenasse as verificações ao contrário, toda pontuação acima de 70 receberia um "C".

A Armadilha das Chaves: Onde o else Deve Ficar

Este é o erro que morde o primeiro script em R de quase todo mundo. Em um script (ou qualquer coisa executada com Rscript), o else deve aparecer na mesma linha que a chave de fechamento do ramo anterior. Isto falha:

if (score >= 60) {
  print("You passed")
}
else {              # Error: unexpected 'else'
  print("Try again")
}

O porquê: o R interpreta instrução por instrução. Quando chega ao } no início de uma linha, a instrução if está sintaticamente completa, e o R a avalia ali mesmo. O else na linha seguinte chega como o início de uma nova instrução - e uma instrução não pode começar com else. A correção é o padrão usado ao longo desta página:

if (score >= 60) {
  print("You passed")
} else {            # brace and else on the same line
  print("Try again")
}

Dentro do corpo de uma função ou de qualquer conjunto externo de chaves a regra estrita relaxa (o R continua lendo até a chave externa fechar), mas não conte com isso - o estilo } else { funciona em todo lugar e é o que os guias de estilo de R prescrevem.

A Condição Deve Ser Um Único TRUE ou FALSE

if() exige exatamente um valor lógico. Duas coisas violam isso, e ambas são erros:

if (NA) print("hi")
# Error: missing value where TRUE/FALSE needed

if (c(TRUE, FALSE)) print("hi")
# Error: the condition has length > 1

O caso do NA importa na prática porque comparações com dados ausentes produzem NA: se x é NA, então x > 10 é NA, e um if alimentado com essa condição para o seu script. O padrão defensivo usa o && com curto-circuito:

Como !is.na(x) é FALSE, a parte x > 10 nunca é avaliada e nenhum NA chega à condição. Como o NA se propaga pelas comparações é assunto de valores ausentes.

O erro de comprimento maior que 1 (imposto desde o R 4.2; antes disso o R usava silenciosamente o primeiro elemento) geralmente significa que você queria uma destas alternativas: any(v > 5) se uma correspondência basta, all(v > 5) se todos os elementos devem passar, ou ifelse() se você queria uma resposta por elemento - que é a próxima seção.

ifelse(): If Else Vetorizado

if decide uma vez. ifelse(test, yes, no) decide para cada elemento de um vetor e retorna um vetor do mesmo comprimento:

Cada elemento de temps é testado de forma independente: "hot" "mild" "mild" "hot" "mild". Esta é a ferramenta para derivar um novo vetor ou coluna de data frame a partir de um existente - sem precisar de laço.

Ao contrário do if, o ifelse() lida com valores ausentes com elegância: um NA no teste produz um NA no resultado, em vez de um erro:

Você pode aninhar chamadas de ifelse() para divisões em três faixas, e nessa profundidade ainda é legível:

Mas pare por aí. Três ou mais ifelse() aninhados viram um quebra-cabeça de fechar parênteses; nesse ponto recorra a cut() (para faixas numéricas) ou a dplyr::case_when(), que coloca cada condição em sua própria linha.

switch() para Escolhas Múltiplas

Quando você está comparando um valor com uma lista de nomes conhecidos - não testando faixas - uma longa cadeia de else if é a ferramenta desajeitada. switch() diz isso diretamente:

Três comportamentos para conhecer:

  • Correspondência: switch() compara o valor de texto com os nomes dos argumentos e retorna o resultado correspondente.
  • Queda (fall-through): um nome com o lado direito vazio (sat = ,) cai para o resultado do próximo caso - é assim que "sat" e "sun" compartilham "weekend" sem repetição.
  • Padrão: o argumento final sem nome ("weekday") é retornado quando nada corresponde. Sem um padrão, um valor sem correspondência faz o switch() retornar NULL de forma invisível - sua função silenciosamente não retorna nada, o que é um bug confuso. Sempre forneça um padrão (ou torne-o um stop() explícito).

switch() brilha dentro de funções que despacham com base em um argumento de modo ou método; para qualquer coisa baseada em limiares numéricos, fique com else if ou cut().

O Que Você Leva Daqui

  • if (condição) { } else { } - condição entre parênteses, um ramo executa; encadeie com else if, a primeira correspondência vence.
  • Em scripts, escreva } else { na mesma linha - else no início de uma linha é erro de sintaxe.
  • if() precisa de exatamente um TRUE/FALSE: NA é erro, um vetor mais longo é erro (desde o R 4.2). Proteja-se com !is.na(x) &&, ou reduza com any()/all().
  • ifelse(test, yes, no) é a versão vetorizada - use-o para computar novos vetores, e não o aninhe mais de duas vezes.
  • switch() cuida do despacho múltiplo por nomes, com queda via casos vazios - sempre dê a ele um padrão.

A seguir: fazendo algo mais de uma vez - laços for, e quando um laço é (e não é) a ferramenta certa.

Perguntas frequentes

Como escrever um if else em R?

if (condição) { ... } else { ... } - a condição vai entre parênteses e cada ramo entre chaves. Encadeie verificações adicionais com else if (condição). Em um script, o else deve ficar na mesma linha que a chave de fechamento do ramo anterior (} else {), ou o R reporta unexpected 'else'.

Qual é a diferença entre if e ifelse() em R?

if é uma instrução de controle de fluxo que testa exatamente um valor TRUE/FALSE e executa um ramo de código. ifelse(test, yes, no) é uma função vetorizada: testa todos os elementos de um vetor de uma vez e retorna um vetor de resultados. Use if para decidir o que seu programa faz; use ifelse() para computar uma nova coluna ou vetor a partir de um existente.

Por que o R diz 'the condition has length > 1'?

Você passou um vetor inteiro para if(), que precisa de um único TRUE ou FALSE. Desde o R 4.2 isso é um erro, em vez do uso silencioso do primeiro elemento. Corrija reduzindo o vetor a um único valor - any(x > 5), all(x > 5) - ou trocando para o ifelse() vetorizado se você queria um resultado por elemento.

Como funciona o switch() em R?

switch(valor, nome1 = resultado1, nome2 = resultado2, padrão) compara um valor de texto com os nomes dos argumentos e retorna o resultado correspondente. Um nome com o lado direito vazio cai para o próximo resultado, então vários casos podem compartilhar um mesmo desfecho. O último argumento sem nome atua como padrão; sem ele, um valor sem correspondência retorna NULL de forma invisível.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR