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 oswitch()retornarNULLde 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 umstop()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 comelse if, a primeira correspondência vence.- Em scripts, escreva
} else {na mesma linha -elseno início de uma linha é erro de sintaxe. if()precisa de exatamente umTRUE/FALSE:NAé erro, um vetor mais longo é erro (desde o R 4.2). Proteja-se com!is.na(x) &&, ou reduza comany()/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.