Os Operadores que o R Oferece
Os operadores do R se dividem em quatro grupos de trabalho: aritméticos (+ - * / ^ %% %/%), de comparação (== != < <= > >=), lógicos (& | && || ! xor) e o teste de pertencimento %in%. Duas coisas os diferenciam da maioria das linguagens: quase todos são vetorizados - operam sobre vetores inteiros de uma vez, elemento a elemento - e o R tem dois operadores E e dois operadores OU que não são intercambiáveis. Esta página cobre todos eles, além das armadilhas de precedência que produzem respostas silenciosamente erradas.
Aritméticos: +, -, *, /, ^, %% e %/%
Os cinco primeiros fazem o que você espera. Os dois envoltos em porcentagem - %% (módulo, o resto) e %/% (divisão inteira, o quociente) - são os que as pessoas pesquisam:
Note que / sempre faz divisão de ponto flutuante - 17 / 5 é 3.4, nunca 3. Se você quer a parte inteira, é exatamente para isso que serve %/%.
O trabalho cotidiano de %% é a divisibilidade. Um número é par quando a divisão por 2 não deixa resto:
Essa segunda linha merece uma pausa: com um operando negativo, o %% do R retorna um resultado com o sinal do divisor (-7 %% 3 é 2, porque -7 = -3 * 3 + 2). Algumas linguagens fazem o contrário; se você está portando código, verifique.
Operadores de Comparação São Vetorizados
==, !=, <, <=, >, >= comparam elemento a elemento e retornam um vetor lógico, não uma resposta única:
Esse é o motor por trás de quase toda filtragem em R - você compara um vetor inteiro com um valor, obtém uma máscara lógica e usa a máscara para subconjuntos. Uma cautela com == em decimais: números de ponto flutuante são armazenados de forma aproximada, então 0.1 + 0.2 == 0.3 é FALSE. Para comparações decimais, prefira all.equal() ou verifique abs(x - y) < 1e-9.
Operadores Lógicos: & vs && (a Confusão Clássica)
O R tem dois operadores E e dois operadores OU, e escolher o errado é um rito de passagem.
& e | são vetorizados. Eles combinam dois vetores lógicos elemento a elemento:
Use-os sempre que estiver construindo um filtro sobre dados: df[df$age > 30 & df$city == "Lisbon", ].
&& e || são escalares e fazem curto-circuito. Eles recebem valores únicos, retornam um único TRUE/FALSE e pulam o segundo operando por completo se o primeiro já resolve a resposta:
Essa segunda linha demonstra o curto-circuito: como x < 0 é FALSE, o R nunca avalia a chamada a stop(). É exatamente por isso que && pertence às condições de if() - você pode escrever if (!is.na(x) && x > 10) e a parte x > 10 é pulada com segurança quando x é NA.
A regra prática: &/| para vetores e filtragem de dados, &&/|| para condições de if(). E desde o R 4.3 isso é imposto com rigor: entregar a && ou || um vetor de comprimento maior que 1 é um erro (versões mais antigas do R usavam silenciosamente apenas o primeiro elemento, o que escondeu bugs reais por anos).
xor(a, b) completa o conjunto - TRUE quando exatamente um dos dois é TRUE:
%in%: Teste de Pertencimento
x %in% table pergunta, para cada elemento de x, "isto aparece em algum lugar de table?" É um dos operadores mais usados em código R do mundo real:
O lado testado pode ser um vetor inteiro, o que faz de %in% a ferramenta natural para filtrar linhas por um conjunto de valores permitidos.
Ele também supera a alternativa que você escreveria em seu lugar - uma cadeia de == colada com |:
Com cinco valores permitidos, a cadeia de == vira um paredão de repetição; a versão com %in% só faz o vetor crescer. Há uma segunda vantagem, mais sutil - %in% nunca retorna NA:
NA == 1 é NA porque o R não tem como saber se um valor desconhecido é igual a 1 - um comportamento tratado em profundidade em valores ausentes. Esse NA então envenena qualquer if() que ele alcance. %in% contorna o problema inteiro respondendo sempre TRUE ou FALSE, e é por isso que é a escolha mais segura para condições sobre dados possivelmente ausentes.
Pegadinhas de Precedência
Duas armadilhas de precedência de operadores respondem por uma parcela desproporcional dos momentos "o R está quebrado". Primeiro, ^ tem precedência maior que o menos unário:
Segundo, o dois-pontos tem precedência maior que a aritmética binária:
Na dúvida, adicione parênteses. Eles não custam nada e todo leitor (incluindo o você do futuro) os interpreta da mesma forma que o interpretador.
$ e [ ]: os Operadores de Acesso
Você também verá constantemente $, [ ] e [[ ]] - tecnicamente operadores também, usados para extrair valores de estruturas em vez de computar com eles:
Eles recebem cobertura completa nas páginas sobre vetores, listas e data frames - aqui basta reconhecê-los como membros da mesma família de operadores.
O Que Você Leva Daqui
%%dá o resto,%/%o quociente inteiro;x %% 2 == 0testa se um número é par.- Comparações são vetorizadas - retornam um vetor lógico com o qual você pode filtrar.
&/|combinam vetores elemento a elemento;&&/||são para valores únicos emif()e fazem curto-circuito. Desde o R 4.3,&&com um vetor mais longo é um erro.x %in% tablesubstitui==encadeados e nunca retornaNA.-2^2é-4e1:n - 1começa em 0 - use parênteses na dúvida.
A seguir: colocando esses operadores para trabalhar dentro de if, else e ifelse() - as estruturas condicionais do R.
Perguntas frequentes
O que %% faz em R?
%% é o operador de módulo - ele retorna o resto de uma divisão. 17 %% 5 é 2. Seu companheiro %/% faz divisão inteira e retorna o quociente sem o resto: 17 %/% 5 é 3. O uso clássico de %% é testar números pares: x %% 2 == 0.
Qual é a diferença entre & e && em R?
& é vetorizado: ele compara dois vetores elemento a elemento e retorna um vetor do mesmo comprimento. && funciona apenas com valores únicos, faz curto-circuito (pula o segundo operando se o primeiro já decide o resultado) e retorna exatamente um TRUE ou FALSE. Use & ao filtrar vetores e && dentro de condições if(). Desde o R 4.3, passar um vetor com mais de 1 elemento para && ou || é um erro, não um aviso.
O que %in% faz em R?
x %in% table testa se cada elemento de x aparece em algum lugar de table, retornando TRUE ou FALSE por elemento. "mango" %in% basket substitui uma cadeia de comparações == unidas com | e, ao contrário de ==, nunca retorna NA - um valor ausente no lado testado simplesmente produz FALSE.
Por que -2^2 retorna -4 em R?
Porque ^ tem precedência maior que o menos unário, o R lê -2^2 como -(2^2), que é -4. Se você quer o quadrado de menos dois, escreva (-2)^2, que é 4. O dois-pontos tem uma armadilha parecida: 1:n - 1 significa (1:n) - 1, não 1:(n - 1).