2 Objeto I - Vetores

2.1 Vetores e operações vetoriais I

Vetor no R é um tipo de objeto que concatena múltiplos valores de uma mesma classe. É fundamental que você entenda vetores para poder entender objetos mais complexos.

2.1.1 Criação de Vetores

A função c() é usada na criação de vetores, pois combina ou concatena elementos. Podemos concatenar números:

# um vetor de números
v1 <- c(3, 3.14, pi, 37.5, 38)
v1
## [1]  3.000000  3.140000  3.141593 37.500000 38.000000

Podemos concatenar textos:

v2 <- c("a", "banana", "maça", "pera", "jabuticaba")
v2
## [1] "a"          "banana"     "maça"       "pera"       "jabuticaba"

Podemos concatenar valores lógicos (veremos adiante como isso é importante):

v3 <- c(TRUE, TRUE, FALSE, FALSE)
v3
## [1]  TRUE  TRUE FALSE FALSE

Podemos abreviar os valores lógicos TRUE como T e FALSE como F:

# c(TRUE, TRUE, FALSE, FALSE) e o mesmo que
v4 <- c(T, T, F, F)
v4
## [1]  TRUE  TRUE FALSE FALSE

Vejamos se v3 é semelhante a v4:

v3 == v4
## [1] TRUE TRUE TRUE TRUE

Note que TRUE e FALSE são valores lógicos e essas palavras são entendidas apenas como tal quando em maiúsculas e sem aspas " pelo R. Tente executar o comando abaixo para ver o que acontece quando utilizamos esses valores em letras minúsculas:

v5 <- c(true, true, false, false) 

O R retorna a mensagem de erro Error: object 'true' not found pois ele procura pelo primeiro objeto de nosso vetor c(true, true, false, false) na área de trabalho e, ao não encontrar, ele retorna esta mensagem de erro, justamente por não compreender true como um vetor lógico, e sim como um objeto! Se nós atribuímos valores a esses objetos, então a concatenação funciona, podendo assim atribuirmos este vetor ao objeto v5 (ou com qualquer nome que desejamos):

true <- TRUE
false <- FALSE
v5 <- c(true, true, false, false)
v5
## [1]  TRUE  TRUE FALSE FALSE

Há no R valores constantes armazenados em objetos que podem ser chamados a qualquer momento por nós. São objetos que concatenam valores de texto, isto é, são vetores de texto. Vejamos abaixo alguns deles:

# essas constantes do R são vetores de texto
LETTERS # letras maiusculas
##  [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S"
## [20] "T" "U" "V" "W" "X" "Y" "Z"
letters # letras minusculuas
##  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
## [20] "t" "u" "v" "w" "x" "y" "z"
month.abb # meses abreviados
##  [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
month.name # meses por extenso
##  [1] "January"   "February"  "March"     "April"     "May"       "June"     
##  [7] "July"      "August"    "September" "October"   "November"  "December"

2.1.2 Sequências Numéricas & Repetições

É possível criar vetores numéricos usando a função seq() ou o operador :.

# usando o :
1:10 # cria uma sequencia de números inteiros 1 a 10
##  [1]  1  2  3  4  5  6  7  8  9 10
20:0 # cria uma sequencia de números inteiros 20 a 0
##  [1] 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
0:-20 # cria uma sequencia de números inteiros 0 a -20
##  [1]   0  -1  -2  -3  -4  -5  -6  -7  -8  -9 -10 -11 -12 -13 -14 -15 -16 -17 -18
## [20] -19 -20

usando a função seq() temos maior controle das sequências:

?seq # veja o help da função
seq(from = 1, to = 10, by = 0.5) # de 1 a 0 a cada 0.5
##  [1]  1.0  1.5  2.0  2.5  3.0  3.5  4.0  4.5  5.0  5.5  6.0  6.5  7.0  7.5  8.0
## [16]  8.5  9.0  9.5 10.0
seq(from = 10, to = 0, by = -0.5) # de 10 a 0 a cada 0.5
##  [1] 10.0  9.5  9.0  8.5  8.0  7.5  7.0  6.5  6.0  5.5  5.0  4.5  4.0  3.5  3.0
## [16]  2.5  2.0  1.5  1.0  0.5  0.0
seq(from = 100, to = 0, length.out = 10) # 10 valores igualmente espaçados de 100 a 0
##  [1] 100.00000  88.88889  77.77778  66.66667  55.55556  44.44444  33.33333
##  [8]  22.22222  11.11111   0.00000

É possível criar vetores repetindo valores através da função rep():

# para números
rep(5, times = 3) # cria um vetor com três elementos de valor 5
## [1] 5 5 5
rep(1:5, times = 3) # cria um vetor com três repetições da sequência de 1 a 5
##  [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
rep(1:5, each = 3) # cria um vetor repetindo três vezes cada elemento da sequência de 1 a 5
##  [1] 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5

Podemos também utilizar a função rep() com vetores de texto:

# para textos
obj <- c("banana", "maça", "pera")
rep(obj, times = 3)
## [1] "banana" "maça"   "pera"   "banana" "maça"   "pera"   "banana" "maça"  
## [9] "pera"
rep(obj, each = 3)
## [1] "banana" "banana" "banana" "maça"   "maça"   "maça"   "pera"   "pera"  
## [9] "pera"

2.2 Operações Matemáticas com Vetores

Todas as operações aplicadas a um vetor são aplicadas a cada um de seus elementos:

meuvetor <- 1:5 # uma sequencia de 1 a 5
mv2 <- meuvetor * 3 # uma sequencia onde cada valor de meuvetor foi multiplicado por 3
mv2
## [1]  3  6  9 12 15
mv2 <- meuvetor / 3 # uma sequencia onde cada valor de meuvetor foi divido por 3
mv2
## [1] 0.3333333 0.6666667 1.0000000 1.3333333 1.6666667
# se usar uma função matemática com um vetor ela afetará cada elemento indivualmente
meuvetor <- c(49, 25, 16, 4, 1)
sqrt(meuvetor) # raiz quadrada de cada elemento em meuvetor
## [1] 7 5 4 2 1

Operações com dois ou mais vetores são pareadas. Se os vetores têm o mesmo comprimento (mesmo número de elementos), então a operação é feita par a par, na ordem em que os elementos aparecem no vetor:

v1 <- c(1, 5, 10, 15)
v2 <- c(2, 4, 8, 16)
v1 + v2 # soma dos valores individuais e pareados
## [1]  3  9 18 31
v1 * v2
## [1]   2  20  80 240
v1^v2
## [1] 1.000000e+00 6.250000e+02 1.000000e+08 6.568408e+18

REGRA DA RECICLAGEM - se os vetores não têm o mesmo comprimento (mesmo número de elementos), então a operação é feita par a par, mas o vetor mais curto é reciclado, i.e. os elementos do vetor mais curto são repetidos sequencialmente até que a operação seja aplicada a todos os elementos do vetor mais longo (o R dará uma aviso quando a operação envolver vetores de tamanhos diferentes, pois às vezes não é isso que queremos).

A mais simples operação para entender a regra da reciclagem é a operação entre um vetor longo e um vetor atômico de um único valor:

v1 <- c(1, 5, 10, 15) # vetor com 4 elementos
v2 <- 2 # vetor com 1 elemento
v1 * v2 # cada elemento de v1 é multiplicado pelo único valor do vetor2
## [1]  2 10 20 30

Mas a reciclagem se aplica em todos os casos de operação entre vetores de tamanhos diferentes:

v1 <- c(1, 5, 10, 15) # vetor com 4 elementos
v2 <- c(3, 2) # vetor com 2 elemento
v1 * v2 # os valores de v1 são multiplicados par a par pelos valores de v2. Como v2 tem apenas 2 elementos, eles são repetidos 1 vez
## [1]  3 10 30 30

Quanto temos vetores de tamanhos não múltiplos entre si, como por exemplo o objeto ob de tamanho 10 e o objeto oc de tamanho 3, o R executa a operação, porém retorna uma mensagem de alerta em que diz que o vetor de tamanho maior (ob) não é múltiplo do vetor de tamanho menor (oc):

ob <- rep(c(0, 1), each = 5)
oc <- 1:3
ob * oc
## Warning in ob * oc: longer object length is not a multiple of shorter object
## length
##  [1] 0 0 0 0 0 3 1 2 3 1

2.3 Funções com Vetores

Algumas funções operam sobre todo o vetor e não sobre cada elemento individualmente. Essas funções são utilizadas constantemente no R e, portanto, devemos conhecer as principais:

  • length() e sort() - comprimento e ordenação de vetores
meuvetor <- 10:1
mv2 <- seq(30, 99, by = 3)
length(meuvetor) # quantos elementos tem meu vetor1
## [1] 10
length(mv2) # quantos elementos tem meu vetor2
## [1] 24
length(meuvetor) / length(mv2) # operação com os resultados
## [1] 0.4166667
mvord <- sort(meuvetor) # ordena os elementos em ordem crescente
mvord
##  [1]  1  2  3  4  5  6  7  8  9 10
sort(mvord, decreasing = TRUE) # ordena os elementos em ordem decrescentes
##  [1] 10  9  8  7  6  5  4  3  2  1
  • mean(), sd(), min(), sum() etc. - funções de estatística descritiva:
?mean # veja ajuda de uma dessas funções e navegue por outras
v1 <- c(2, 4, 6, 8, 4, 3, 5, 7)
sum(v1) # soma de todos os valores
## [1] 39
mean(v1) # média aritimética dos valores
## [1] 4.875
median(v1) # valor da mediana
## [1] 4.5
sd(v1) # desvio padrão
## [1] 2.03101
var(v1) # variância
## [1] 4.125
sqrt(var(v1)) # desvio padrão, pois este é a raíz quadrada da variância
## [1] 2.03101
min(v1) # valor mínimo
## [1] 2
max(v1) # valor máximo
## [1] 8
range(v1) # mínimo e máximo
## [1] 2 8
diff(v1) # intervalos (diferenças entre valores consecutivos) entre os valores do vetor
## [1]  2  2  2 -4 -1  2  2
cumsum(v1) # soma cumulativa dos valores
## [1]  2  6 12 20 24 27 32 39

2.4 Classes de vetores e fatores

Para entender os conceitos, vamos primeiro conhecer algumas funções úteis no entendimento das classes de objetos do R e algumas funções importantes: class(), is.[class]() e as.[class]().

Vetores têm classes diferentes e todos os elementos de um vetor pertencem à mesma classe.

As principais classes são:

  • numeric (=double, i.e. inclui casas decimais);

  • integer (numérico mas de valor inteiro);

  • character (texto);

  • logical (verdadeiro ou falso);

  • date (para datas).

A função class() nos permite saber a classe de um objeto do R.

?class # veja o help dessa funcao
v1 <- 1:20 # um vetor de números inteiros
class(v1)
## [1] "integer"
v2 <- seq(1, 10, by = 0.5) # um vetor de números
class(v2)
## [1] "numeric"
v3 <- rep(c("A", "B"), each = 10) # um vetor de palavras (character)
class(v3)
## [1] "character"
v4 <- c(T, T, F, F) # um vetor lógico
class(v4)
## [1] "logical"
v4 <- c(10, "A", 20, "B") # um vetor com misto de números e letras será convertido para texto
class(v4)
## [1] "character"
v4
## [1] "10" "A"  "20" "B"
# veja que em v4 os elementos 10 e 20 viraram palavras, porque vetor só aceita elementos da mesma classe e enquanto um número pode ser convertido em texto, um texto não pode ser convertido em número. Por isso tudo é convertido para texto para a informação seja perdida (i.e. vire NA)

As funções genéricas is.[class]() permitem você perguntar se um vetor é de uma determinada classe (is?). Ao utilizar essas funções, o R retornará um vetor lógico, ou seja, verdadeiro ou falso dependendo da classe do objeto:

v1 <- 1:20 # um vetor de números inteiros
is.integer(v1) # verdadeiro
## [1] TRUE
is.numeric(v1) # também verdadeiro porque números inteiros também são números
## [1] TRUE
v3 <- rep(c("A", "B"), each = 10) # um vetor de palavras
is.character(v3) # verdadeiro
## [1] TRUE
is.numeric(v3) # falso, porque o vetor contém palavras
## [1] FALSE
v4 <- c(10, "A", 20, "B") # um vetor com misto de números e letras
is.numeric(v4) # falso, porque o vetor contém apenas palavras
## [1] FALSE
v4 <- c(T, T, F, F) # um vetor lógico
is.logical(v4) # verdadeiro
## [1] TRUE
is.numeric(v4) # falso
## [1] FALSE
is.character(v4) # falso
## [1] FALSE

As funções genéricas as.[class]() (as = ‘como uma?’) permitem você converter um vetor de uma classe para outra. Em alguns casos, isso faz sentido; em outros, o retorno será de valores inexistentes (NA) ou não numéricos (NaN).

# conversão total
v1 <- 1:20 # um vetor de números inteiros
as.character(v1) # converte para texto um vetor numérico
##  [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15"
## [16] "16" "17" "18" "19" "20"
# conversão parcial
v4 <- c(10, "A", 20, "B") # um vetor com misto de números e letras
as.numeric(v4) # converte cada elemento separadamente (regra da reciclagem é aplicada), o R vai conseguir mudar os textos que são números, mas as letras serão substituídas por NA e um aviso será dado quando isso acontecer
## Warning: NAs introduced by coercion
## [1] 10 NA 20 NA
# um vetor de texto não pode virar número
v3 <- rep(c("A", "B"), each = 10) # um vetor de palavras
as.numeric(v3) # todos viram NA pois a conversão é inválida
## Warning: NAs introduced by coercion
##  [1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
# mas um vetor lógico pode virar número
v4 <- c(T, T, F, F) # um vetor lógico
as.numeric(v4) # verdadeiro vira 1 e falso vira 0 - isso é muito útil e é por isso que operações matemáticas funcionam com vetores lógicos:
## [1] 1 1 0 0
sum(v4)
## [1] 2
mean(v4)
## [1] 0.5
min(v4)
## [1] 0

O factor (=fator) na linguagem do R é um tipo especial de vetor com elementos de texto (classe character), em que os valores de texto são categorias. Isso tem algumas vantagens operacionais e sempre que o R precisa de um vetor de texto no formato de factor, ele converte automaticamente (se possível). No entanto, é muito importante que você entenda a diferença entre um vetor de classe character e um vetor de classe factor. Isso vai aparecer o tempo todo enquanto você usa o R e algumas vezes você precisará converter de um para outro. Funções importantes a serem memorizadas são:

  • levels() - para ver (ou modificar) os níveis ou categorias de um fator;

  • as.factor() e as.vector() - para converter entre fator e vetor.

# um exemplo de um vetor de palavras
mvv <- c("abacate", "banama", "mamão", "uva")
# repetindo cada fruta 3 vezes
mvv <- rep(mvv, each = 3)
# veja conteúdo
mvv
##  [1] "abacate" "abacate" "abacate" "banama"  "banama"  "banama"  "mamão"  
##  [8] "mamão"   "mamão"   "uva"     "uva"     "uva"
# qual a classe desse vetor?
class(mvv)
## [1] "character"
# vamos converter esse vetor de character para um fator
mvv2 <- as.factor(mvv)
class(mvv2) # de fato mudou para factor
## [1] "factor"
mvv2 # compare a estrutura deste objeto com mvv (apareceu a a palavra Levels:, que mostra as categorias existentes no fator)
##  [1] abacate abacate abacate banama  banama  banama  mamão   mamão   mamão  
## [10] uva     uva     uva    
## Levels: abacate banama mamão uva
# por ser um fator você pode
levels(mvv2) # você pode ver os níveis do fator, ou seja as categorias que ele contém)
## [1] "abacate" "banama"  "mamão"   "uva"
levels(mvv2) <- c("abacate", "banana", "mamão", "uva") # você pode mudar/corrigir os níveis, aqui corrigindo banama por banana
mvv2 # veja como mudaram as categorias e os valores
##  [1] abacate abacate abacate banana  banana  banana  mamão   mamão   mamão  
## [10] uva     uva     uva    
## Levels: abacate banana mamão uva
as.numeric(mvv2) # você pode converter o fator em numérico, de forma que cada categoria vire um número (muito útil isso)
##  [1] 1 1 1 2 2 2 3 3 3 4 4 4
as.numeric(mvv) # nao pode fazer a mesma coisa com um vetor de palavras
## Warning: NAs introduced by coercion
##  [1] NA NA NA NA NA NA NA NA NA NA NA NA

A função as.Date() converte um vetor de trecho em um objeto de classe date. Datas são uma classe especial, que permite operações artiméticas para calcular distâncias temporais.

# muitas vezes queremos calcular tempo entre duas observações, como por exemplo, entre duas medições consecutivas num estudo sobre crescimento de plantas

# Qual a diferença em dias entre duas datas?
data1 <- "31/03/1964"
data2 <- "17/04/2016"
# eu nao posso simplesmente subtrair esses valores
data2 - data1

O R retorna uma mensagem de erro (Error in data2 - data1 : non-numeric argument to binary operator) porque esses objetos são de classe texto, e operações matemáticas só são permitidas com números ou datas. Vejam que a classe dos objetos criados acima são do tipo “texto” (character):

class(data1)
## [1] "character"
class(data2)
## [1] "character"

Porém, se convertermos esses objetos para a classe Date, então poderemos fazer operações matemáticas com eles:

# mas o R tem um classe para datas
# entao fazemos a conversao
?as.Date # veja o help dessa função
data1 <- as.Date(data1, format = "%d/%m/%Y")
data2 <- as.Date(data2, format = "%d/%m/%Y")
# agora a classe mudou
class(data1)
## [1] "Date"
class(data2)
## [1] "Date"
# posso fazer matemática com data
data2 - data1
## Time difference of 19010 days
# note o argumento format, ele importa para o R possa entender o formato de sua data
data3 <- "2016-04-21" # formato americano
as.Date(data3, format = "%d/%m/%Y") # se eu usasse isso com o mesmo formato acima, o resultado é NA, porque está mal especificado
## [1] NA
# mas mudando a simbologia do argumento format
as.Date(data3, format = "%Y-%m-%d")
## [1] "2016-04-21"
# ele reconhece

2.5 Indexação

Já vimos que vetores são conjuntos de valores da mesma classe (seção 2). Esses valores tem uma posição dentro do vetor, ou seja, possuem um índice.
Já vimos também que podemos alterar a ordem dos valores, utilizando a função sort(), ou seja, alterar a posição dos elementos no vetor.

O índice identifica os elementos do vetor individualmente:

  • pode ser um número equivalente à posição do elemento no vetor,

  • ou pode ser um nome, quando os elementos do vetor tiverem um nome.

Entender indexação é fundamental para escrever bons códigos no R, pois isso se aplica também às matrizes e às outras classes de objetos do R.

Aqui vamos ver indexação de vetores, que é dada pelo operador [].

2.5.1 Usando índices numéricos

# um vetor simples
v1 <- 1:10
v1[1] # valor na posição/índice 1
## [1] 1
v1[8] # valor na posição/índice 8
## [1] 8
# em outra ordem
v1 <- 1:10
v1 <- sort(v1, decreasing = TRUE) # ordena decrescente
v1[1] # valor na posição/índice 1
## [1] 10
v1[8] # valor na posição/índice 8
## [1] 3

2.5.2 Usando índices de nomes

Índices de nomes são elementos essenciais na manipulação de dados reais, pois nomes de linhas (seus registros) e nomes de colunas (suas variáveis) são nomes dos elementos que compõem a sua matriz. Índice de nomes preservam o identificador dos seus objetos (registros). Podemos atribuir nomes aos elementos do vetor usando a função names(). Uma outra função útil se chama paste(), muito utilizada na manipulação de textos.

?paste # veja o help da função paste
?names # veja o help da função names
# um vetor simples
v1 <- 1:10
# criando um vetor para usar como nomes
v2 <- paste("nome", v1, sep = "") # significa = use a regra da reciclagem e cole (paste) a palavra 'nome' com cada valor do vetor v1, sem separador
v2 # é portanto um conjunto de textos
##  [1] "nome1"  "nome2"  "nome3"  "nome4"  "nome5"  "nome6"  "nome7"  "nome8" 
##  [9] "nome9"  "nome10"
# note que é muito mais rápido fazer isso do que escrever nome1, nome2 ... nome10, certo?

# agora vamos atribuir v2 como nome dos elementos de v1
# para isso é importante que v1 e v2 tenham o mesmo comprimento
length(v1)
## [1] 10
length(v2)
## [1] 10
names(v1) # deve ser nulo, pois os elementos não tem nome
## NULL
names(v1) <- v2 # atribuimos os nomes
v2 # pronto agora os elementos tem nome
##  [1] "nome1"  "nome2"  "nome3"  "nome4"  "nome5"  "nome6"  "nome7"  "nome8" 
##  [9] "nome9"  "nome10"
# posso usar o nome como índice para pegar elementos
v1["nome8"] # valor do elemento que tem nome = nome8
## nome8 
##     8
v1[8] # isso deve ser equivalente, pois criamos os nomes assim
## nome8 
##     8
# mas note a diferença quando reordenamos o vetor e mudamos os valores de posição
v3 <- sort(v1, decreasing = T)
v3[8] # o índice numérico pega outro valor
## nome3 
##     3
v3["nome8"] # o indice de nome pega o mesmo valor (PRESERVA)
## nome8 
##     8

2.6 Vetores e operadores lógicos

Para manipular dados no R, entender vetores lógicos e operadores lógicos é fundamental. Vetores lógicos são vetores de verdadeiros (TRUE ou apenas T, sempre em letras maiúsculas) ou falsos (FALSE ou F). Eles podem ser convertidos em vetores numéricos e, portanto, operados matematicamente (T = 1, e F = 0).

2.6.1 Fazendo perguntas à vetores

Vetores lógicos podem ser respostas às perguntas feitas por operadores lógicos:

  • > - é maior que?

  • < - é menor que?

  • >= - é maior igual a?

  • <= - é menor igual a?

  • == - é igual a?

  • != - é diferente de?

  • %in% - compara conteúdo de vetores

Há ainda a função duplicated() que busca valores repetidos em um vetor. O resultado desta função é um vetor contendo TRUE ou FALSE. Valores que possuam o valor TRUE são duplicados. Para checar os duplicados, devemos filtrar o resultado desta ação (veja na seção 2.6.2).

# um vetor numerico
v1 <- 1:20
# quais valores de v1 são maiores ou iguais a 10
p1 <- v1 >= 10 # vai retornar um vetor lógico
p1
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE
## [13]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
# soma dos verdadeiros responde "quantos valores de v1 são maiores ou iguais a 10, pois apenas esses valores são verdadeiros ou seja são 1)
sum(p1)
## [1] 11
# experimente os demais operadores

# a regra da reciclagem também se aplica neste conceito
v1 <- 1:20
v2 <- 1:20
p2 <- v1 == v2 # compara cada par dos vetores que são idênticos
p2 # é o vetor lógico resultando, todos os valores são verdadeiros
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [16] TRUE TRUE TRUE TRUE TRUE
# portanto, as seguintes expressões também são verdadeiras
sum(v1 == v2) == length(v1)
## [1] TRUE
# ou então
sum(v1 == v2) == length(v2)
## [1] TRUE
# valores duplicados
vv <- c(2, 2, 2, 3, 4, 5)
vv # apenas o dois é duplicado
## [1] 2 2 2 3 4 5
duplicated(vv) # note que esta função retorna TRUE apenas para dois dos três valores 2 (o primeiro não é duplicado)
## [1] FALSE  TRUE  TRUE FALSE FALSE FALSE
# comparando vetores
v1 <- c(1, 2, 3, 4)
v2 <- c(4, 4, 5, 6)
v1 %in% v2 # quantos elementos de v1 existem em v2
## [1] FALSE FALSE FALSE  TRUE
sum(v1 %in% v2) # apenas 1
## [1] 1
v2 %in% v1 # quais elementos de v2 estão em v1
## [1]  TRUE  TRUE FALSE FALSE
sum(v2 %in% v1) # os dois quatro
## [1] 2
notas.dos.alunos <- c(6.0, 5.1, 6.8, 2.8, 6.1, 9.0, 4.3, 10.4, 6.0, 7.9, 8.9, 6.8, 9.8, 4.6, 11.3, 8.0, 6.7, 4.5)
## Quantos aprovados?
sum(notas.dos.alunos >= 5)
## [1] 14
# Qual a proporção de aprovados?
prop <- sum(notas.dos.alunos >= 5) / length(notas.dos.alunos)
prop
## [1] 0.7777778
# ou em texto
paste(round(prop * 100), "%", sep = "")
## [1] "78%"

Podemos usar também vetores de texto e fatores em conjunto com operadores lógicos.

# E VETORES DE TEXTO?
v1 <- rep(c("banana", "pera", "laranja", "limão"), 10)
v1 # um vetor de palavras
##  [1] "banana"  "pera"    "laranja" "limão"   "banana"  "pera"    "laranja"
##  [8] "limão"   "banana"  "pera"    "laranja" "limão"   "banana"  "pera"   
## [15] "laranja" "limão"   "banana"  "pera"    "laranja" "limão"   "banana" 
## [22] "pera"    "laranja" "limão"   "banana"  "pera"    "laranja" "limão"  
## [29] "banana"  "pera"    "laranja" "limão"   "banana"  "pera"    "laranja"
## [36] "limão"   "banana"  "pera"    "laranja" "limão"
# quantos elementos são iguais a banana
v1 == "banana"
##  [1]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [13]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [25]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [37]  TRUE FALSE FALSE FALSE
sum(v1 == "banana")
## [1] 10
# também poderia perguntar: quantos elementos de v1 contém banana
sum(v1 %in% "banana")
## [1] 10
v1 %in% "banana"
##  [1]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [13]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [25]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [37]  TRUE FALSE FALSE FALSE
# no caso acima == e %in% funcionam igual, mas o operador %in% é util quando quisermos comparar dois vetores de character
v2 <- c("banana", "pera", "abacate")
v1 %in% v2 # quais elementos de v1 correspondem a elementos de v2
##  [1]  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE
## [13]  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE
## [25]  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE
## [37]  TRUE  TRUE FALSE FALSE
sum(v1 %in% v2) # quantos são? 10 laranjas e 10 peras
## [1] 20
v2 %in% v1 # quais elementos de v2 estão em v1
## [1]  TRUE  TRUE FALSE
sum(v2 %in% v1) # quantos são (apenas laranja e pera, abacate não está)
## [1] 2

Operadores auxiliares permitem combinar perguntas:

  • & equivale a E - essa condição E essa outra;

  • | equivale a OU - essa condição OU essa outra;

  • ! - inverte os valores da pergunta

# um vetor
v1 <- 1:20
v1
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
p1 <- v1 > 5 & v1 <= 15 # quais elementos de v1 são maiores que 5 E menores ou iguais a 15
sum(p1) # quantos são?
## [1] 10
p1 <- v1 > 5 | v1 <= 15 # quais elementos de v1 são maiores que 5 OU menores ou iguais a 15
sum(p1) # quantos são
## [1] 20
# !exclamação NEGA ou INVERTE verdadeiros e falsos
v1 <- 1:20
sum(v1 == 5) # quantos v1 são iguais a 5?
## [1] 1
sum(!v1 == 5) # quantos v1 são diferentes de 5?
## [1] 19
sum(v1 > 5) # quantos v1 são maiores que 5?
## [1] 15
sum(!v1 > 5) # quantos v1 são menores que 5?
## [1] 5
# texto
v1 <- rep(c("banana", "pera", "laranja", "limão"), 10)
v1 # um vetor de palavras
##  [1] "banana"  "pera"    "laranja" "limão"   "banana"  "pera"    "laranja"
##  [8] "limão"   "banana"  "pera"    "laranja" "limão"   "banana"  "pera"   
## [15] "laranja" "limão"   "banana"  "pera"    "laranja" "limão"   "banana" 
## [22] "pera"    "laranja" "limão"   "banana"  "pera"    "laranja" "limão"  
## [29] "banana"  "pera"    "laranja" "limão"   "banana"  "pera"    "laranja"
## [36] "limão"   "banana"  "pera"    "laranja" "limão"
vl <- v1 == "banana" & v1 == "pera" # quantos elementos de v1 sao banana E sao pera
vl
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [37] FALSE FALSE FALSE FALSE
sum(vl) # nenhum valor satisfaz as duas condicoes
## [1] 0
vl <- v1 == "banana" | v1 == "pera" # quantos elementos de v1 sao banana ou sao pera
vl
##  [1]  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE
## [13]  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE
## [25]  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE
## [37]  TRUE  TRUE FALSE FALSE
sum(vl) # tem 20 valores que satisfazem 1 das condições
## [1] 20
# isso é o mesmo que pergunta desse outro jeito:
sum(v1 %in% c("banana", "pera"))
## [1] 20

2.6.2 Filtrando dados com vetores lógicos

Vetores lógicos podem ser usados como índices (Seção 2.5) para filtrar elementos de um vetor. É através deste conceito que podemos filtrar dados de matrizes e criar subconjunto de dados.

# um vetor com sequencia de 1 a 100
v1 <- 1:100

p1 <- v1 > 15 # Pergunta 1 quantos são maiores que 15
v1[p1] # valores que satisfazem a pergunta 1
##  [1]  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34
## [20]  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53
## [39]  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72
## [58]  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91
## [77]  92  93  94  95  96  97  98  99 100
p2 <- v1 <= 20 # Pergunta 2 quantos são menores ou iguais a 20
v1[p2] # valores que satisfazem a pergunta 2
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
# quantos satisfazem as duas perguntas
p3 <- p1 & p2
v1[p2] # valores que satisfazem as duas perguntas
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

A função grep() permite a busca de uma palavra (ou pedaço dela) em um vetor de palavras. Mais de uma palavra pode ser buscada ao mesmo tempo.

?grep # veja o help dessa função e seus argumentos
# um vetor de palavras
v1 <- rep(c("banana", "pera", "laranja", "limão"), 5)
grep("an", v1) # quais elementos tem a palavra 'an' no nome?
##  [1]  1  3  5  7  9 11 13 15 17 19
# note que é case.sensitive (depende se é maiusculo ou minúsculo)
grep("An", v1) # não encontra nada
## integer(0)
grep("An", v1, ignore.case = T) # mas eu posso dizer para ele ignorar se é minusculo ou maiúsculo e ele encontra novamente
##  [1]  1  3  5  7  9 11 13 15 17 19
# quem sao esses elementos
vl <- grep("An", v1, ignore.case = T) # pega os índices desses elementos
v1[vl]
##  [1] "banana"  "laranja" "banana"  "laranja" "banana"  "laranja" "banana" 
##  [8] "laranja" "banana"  "laranja"
unique(v1[vl]) # valores únicos desse vetor
## [1] "banana"  "laranja"

2.6.3 Perguntando por valores ausentes - NA

Vimos anteriormente como o R codifica valores ausentes (seção 1.8.4): converte em uma classe lógica definida pela palavra NA em maiúsculo. E nossos dados frequentemente têm valores ausentes. Isso vai gerar avisos indesejáveis e impedir certas análises. Então, muitas vezes precisamos tirar registros com valores ausentes ou colunas com muitos valores ausentes.

Perguntar por valores ausentes no R é feito por uma função especial chamada is.na(). A resposta da função é um vetor lógico indicando quem é e quem não é NA. Há uma outra função chamada na.omit() que elimina valores NA de um vetor.

?is.na # veja o help
# um vetor com NAs
v1 <- c(NA, NA, 1, 2, 3, 4, 5, 6)
is.na(v1) # quem é NA?
## [1]  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
v2 <- v1[!is.na(v1)] # criar um vetor novo com quem não é NA (note o !)
v2
## [1] 1 2 3 4 5 6
# isso também pode ser feito com na.omit()
?na.omit # veja o help dessa função
v3 <- na.omit(v1)
v3 # a diferença é que criou um objeto de classe na.omit
## [1] 1 2 3 4 5 6
## attr(,"na.action")
## [1] 1 2
## attr(,"class")
## [1] "omit"
v3 <- as.vector(v3) # isso elimina a diferença, convertendo em vetor
v3 # agora é idêntico a v2
## [1] 1 2 3 4 5 6
# agora suponha o seguinte vetor
v4 <- c("NA", "NA", "pera", "banana", "mamão")
is.na(v4) # ops todos são falsos
## [1] FALSE FALSE FALSE FALSE FALSE
# isso porque "NA" é texto e não um objeto de classe lógica
class(NA)
## [1] "logical"
class("NA")
## [1] "character"
# mas eu poderia corrigir isso
v4[v4 == "NA"] # vejo
## [1] "NA" "NA"
v4[v4 == "NA"] <- NA # corrijo
v4
## [1] NA       NA       "pera"   "banana" "mamão"
is.na(v4) # agora dois são NAs
## [1]  TRUE  TRUE FALSE FALSE FALSE
# note que agora todos são diferentes de "NA" como texto
v4[!v4 == "NA"]
## [1] NA       NA       "pera"   "banana" "mamão"
# mas isso de mostra quem não é corretamente
v5 <- v4[!is.na(v4)]
v5
## [1] "pera"   "banana" "mamão"

2.7 Para saber mais:

Veja nossas vídeoaulas com parte do conteúdo deste capítulo:

2.8 Exercícios