Menu

Operadores em R: Aritméticos, de Comparação, Lógicos, %in% e %%

Todos os operadores de que você precisa em R - aritméticos incluindo %% e %/%, comparações vetorizadas, a diferença entre & e &&, e %in% para testar pertencimento.

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

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 == 0 testa 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 em if() e fazem curto-circuito. Desde o R 4.3, && com um vetor mais longo é um erro.
  • x %in% table substitui == encadeados e nunca retorna NA.
  • -2^2 é -4 e 1:n - 1 começ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).

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR