7.3 Operações com vetores
Como o R
é uma linguagem vetorizada, as operações são aplicadas a cada elemento do vetor automaticamente, sem a necessidade de laços (ou loopings) ao longo do vetor. Esta é uma das grandes vantagens do .
Operações aritméticas podem ser aplicadas diretamente entre vetores.
# desvios da prec em relação a média climatológica
prec - prec_clim
#> jan fev mar abr mai jun jul ago set out nov dez
#> 70 -5 50 -88 -60 -30 -28 -38 -10 -45 -190 60
# anomalia em % relativa
prec/prec_clim * 100
#> jan fev mar abr mai jun jul ago
#> 130.43478 97.56098 131.25000 12.00000 0.00000 0.00000 30.00000 36.66667
#> set out nov dez
#> 90.90909 72.72727 5.00000 127.27273
# transformação boxcox da prec com alpha = 0.335
((prec^0.335 - 1)/0.335)
#> jan fev mar abr mai jun jul ago
#> 17.188869 14.626583 14.916806 3.877403 -2.985075 -2.985075 3.877403 5.422424
#> set out nov dez
#> 10.977168 11.856532 3.470802 16.727944
# cte^intervalo
mean(prec)^(1/2:5)
#> [1] 10.271319 4.725171 3.204890 2.538929
Uma peculiaridade do é o tratamento de operações com vetores de tamanhos diferentes. O vetor menor é reciclado, de forma que seus elementos sejam repetidos em ordem até atingirem o tamanho do vetor mais longo envolvido na operação.
# velocidades em m s-1
(vel_ms <- c(1.5, 0.3, 1.4, 2.0))
#> [1] 1.5 0.3 1.4 2.0
# fator de conversão para km h-1
fator_conv <- 3.6
vel_ms * fator_conv
#> [1] 5.40 1.08 5.04 7.20
# equivalência
fator_conv <- c(3.6, 3.6, 3.6, 3.6)
vel_ms * fator_conv
#> [1] 5.40 1.08 5.04 7.20
A constante fator_conv = 3.6
nesse caso é reciclada 4 vezes (tamanho do vetor vel_ms
) e então multiplicada por cada elemento de vetor_dbl
. Por isso os resultados no código acima são idênticos. Essa funcionalidade de fazer um vetor do mesmo tamanho de outro é conhecida como reciclagem. Se o vetor mais longo não tem tamanho múltiplo do mais curto, o realiza a operação com uma mensagem de aviso.
1:10 * 1:2
#> [1] 1 4 3 8 5 12 7 16 9 20
1:10 * 1:3
#> Warning in 1:10 * 1:3: longer object length is not a multiple of shorter object
#> length
#> [1] 1 4 9 4 10 18 7 16 27 10
A reciclagem é um recurso útil, mas também perigoso. Seu código pode ficar mais elegante ou gerar resultados inesperados.
Operações aritméticas podem ser feitas com vetores lógicos, como nos exemplos abaixo:
FALSE - TRUE
#> [1] -1
prec_clim >= 100
#> [1] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE
(prec_clim >= 100) * 1:12
#> [1] 1 2 3 4 0 0 0 0 9 10 11 12
7.3.1 Comparações
Vetores lógicos resultam da comparação de números ou caracteres. A Tabela 7.1 apresenta os principais operadores lógicos para comparações.
Operador | Descrição |
---|---|
< | menor que |
<= | menor ou igual a |
> | maior que |
>= | maior ou igual |
== | idêntico |
!= | diferente |
!x | não é x (negação) |
x | y | x ou y |
x & y | x e y |
isTRUE(x) | teste se x é verdadeiro |
%in% | está contido em |
Este conjunto de operadores permite diversas comparações entre vetores, por exemplo:
- quais meses de
prec
foram abaixo do normal?
prec
#> jan fev mar abr mai jun jul ago set out nov dez
#> 300 200 210 12 0 0 12 22 100 120 10 280
prec_clim
#> [1] 230 205 160 100 60 30 40 60 110 165 200 220
prec - prec_clim < 0
#> jan fev mar abr mai jun jul ago set out nov dez
#> FALSE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
O operador %in%
serve para verificar se um vetor está contido parcial ou totalmente em outro vetor.
# operador está contido em
c(200, 150, 100) %in% prec
#> [1] TRUE FALSE TRUE
# 2:4 são elementos de x?
is.element(c(200, 150, 100), prec)
#> [1] TRUE FALSE TRUE
Nos exemplos acima, vimos como buscar os os elementos de um vetor para apenas uma condição. Entretanto, frequentemente precisamos testar mais condições, ou seja, combinar comparações. Por exemplo, para condições do tipo:
- \(0 < prec \leq 100\)
- \(prec < 50\) ou \(prec \geq 150\)
precisamos usar os operadores relacionais:
&
e&&
("e")|
e||
("ou")
# prec entre 0 e 100 mm
prec > 0 & prec <= 100
#> jan fev mar abr mai jun jul ago set out nov dez
#> FALSE FALSE FALSE TRUE FALSE FALSE TRUE TRUE TRUE FALSE TRUE FALSE
# prec abaixo de 50 e acima de 150 mm
prec < 50 | prec >= 150
#> jan fev mar abr mai jun jul ago set out nov dez
#> TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE
A ordem das operações pode ser controlada por parênteses. Os operadores &
e |
são vetorizados (retornam vetores de mesmo tamanho que os vetores testados).
A forma dupla (&&
ou ||
) compara somente um elemento de cada lado, enquanto a forma normal (&
e |
), compara cada elemento dos vetores em cada lado.
a <- c(1, 1, 0, 1)
b <- c(2, 1, 0, 1)
# forma normal verifica cada elemento de a e cada elemento de b
a == 1 & b == 1
#> [1] FALSE TRUE FALSE TRUE
# forma dupla verifica somente o primeiro elemento de a e o primeiro elemento de b
# retornando somente um resultado
a == 1 && b == 1
#> [1] FALSE
a | b | a==1 | b==1 | a == 1 & b == 1 | a == 1 && b == 1 |
---|---|---|---|---|---|
1 | 2 | TRUE | FALSE | FALSE | FALSE |
1 | 1 | TRUE | TRUE | TRUE | |
0 | 0 | FALSE | FALSE | FALSE | |
1 | 1 | TRUE | TRUE | TRUE |
Podem haver mais que duas condições a serem testadas. As condições podem ser combinadas usando múltiplos &
ou |
. As diferentes condições podem ser agrupadas por parênteses assim como feito nas operações matemáticas.
7.3.1.1 Testes de igualdade
A comparação de igualdade no pode ser meio confusa devido as forma de armazenamento diferentes dos números.
0.6 - 0.3
#> [1] 0.3
0.9 - 0.6
#> [1] 0.3
0.3 == 0.3
#> [1] TRUE
Tudo normal, mas ao comparar operações com valores decimais, você pode se surpreender:
(0.6 - 0.3) == (0.9 - 0.6)
#> [1] FALSE
Isso ocorre por imprecisão no final da parte decimal que pode ser arrendondada incorretamente. Isso não acarreta problema na maioria dos cálculos. Para evitar esse problema é melhor comparar os resultados usando a função all.equal()
.
all.equal(
target = 0.6 - 0.3,
current = 0.9 - 0.6
)
#> [1] TRUE
A all.equal()
inclui uma tolerância na comparação (\(1,5\times10^{-8}\)) fazendo com aquela imprecisão seja ignorada. Para mais detalhes consulte ?all.equal
.
7.3.2 Funções any
e all
Estas funções fornecem um único valor (vetor lógico de tamanho 1) para resumir ou descrever o resultado da condição aplicada ao vetor.
vetor <- c(0, 1, -1, -2, 3, 5, -5)
all(vetor < 0) # todas as posições são maiores que 0 ?
#> [1] FALSE
any(vetor > 0) # alguma posição é maior que 0?
#> [1] TRUE
all()
verifica se a condição avaliada é válida para todos elementos de um vetor;any()
verifica se a condição avaliada é válida para pelo menos um dos elementos de um vetor;