Trilhas
/
R
R
/
Programa
/
Vetores
Ve

Vetores em R

1 exercício

Sobre Vetores

Um vector (tecnicamente, um atomic vector) em R é uma coleção de valores do mesmo type: geralmente integer, numeric, character, logical; raramente complex ou raw. Eles são armazenados de forma contígua na memória, de modo semelhante a um array em C.

Se receber entradas mistas, o R as converte silenciosamente para um tipo comum, geralmente character, o que pode levar a resultados inesperados.

v <- c(2, 5.4, "txt")
v
#> [1] "2"   "5.4" "txt"
typeof(v)
#> [1] "character"

Criando vetores

Se você já tem todos os valores, use c() (abreviação de "concatenar"):

x <- 10
v <- c(4, 7, x)

A função c() é muito flexível, e as entradas podem incluir outros vetores e intervalos. c() aceita qualquer quantidade e variedade de entradas e as achata em um único vetor.

Se o vetor começa pequeno e cresce muito durante a execução (por exemplo, ao adicionar valores em um laço), pode ser bem mais rápido pré-alocar um vetor longo, que depois pode ser preenchido com dados reais:

v <- vector(length = 100) 

Isso minimiza a necessidade de copiar o objeto: uma operação lenta e que consome muita memória no caso de vetores longos.

Intervalos, sequências, repetições

Para um intervalo de valores consecutivos (crescente ou decrescente), você pode usar a notação :

v <- 1:5 # equivalent to c(1, 2, 3, 4, 5)
w <- 10:7 # c(10, 9, 8, 7)

Em R, intervalos não são um tipo separado: são apenas uma forma abreviada de construir um vetor.

A função seq() oferece um controle mais preciso:

# specify step size
seq(2, 11, by = 3) # c(2, 5, 8, 11)

# specify number of values, evenly-spaced
seq(2.5, 4, length.out = 5) # c(2.500, 2.875, 3.250, 3.625, 4.000) 

A função rep() facilita a criação de padrões repetidos:

count <- 3
rep(7, count)
#> [1] 7 7 7

rep(1:3, count)
#> [1] 1 2 3 1 2 3 1 2 3

rep(1:3, each = 2) # the "each" keyword is required in this case
#> [1] 1 1 2 2 3 3

Alguns intervalos são predefinidos como constantes internas:

letters  # LETTERS is the UPPERCASE equivalent
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"

month.name
#> [1] "January"   "February"  "March"     "April"     "May"       "June"      "July"      "August"   
#> [9] "September" "October"   "November"  "December" 

month.abb
#> [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"

Aritmética

As operações são aplicadas automaticamente elemento a elemento ao longo do vetor. Os laços, as compreensões de lista e as recursões comuns em outras linguagens não são necessários e, por questões de desempenho, devem ser evitados quando possível.

2 + 1:3     # c(3, 4, 5)
2 * 1:3     # c(2, 4, 6)
12 / 1:3    # c(12  6  4)
2 ^ (1:3)   # c(2, 4, 8) : exponentiation, operator precedence order here needs ()

Pares de vetores também funcionam, com os elementos tratados em pares:

v <- 1:3
w <- 5:7

v + w
#> [1]  6  8 10

v * w
#> [1]  5 12 21

v ^ w
#> [1]    1   64 2187

Isso é mais poderoso do que parece à primeira vista, e há mais a explorar nos próximos conceitos.

Acessando elementos de um vetor

Como em muitas linguagens, podemos usar o índice entre colchetes:

v <- 4:7
v[2]
#> [1] 5
v[2:4]
#> [1] 5 6 7

Mas atenção: o R usa indexação a partir de 1 por padrão. Isso é comum em linguagens científicas (Fortran, Matlab, Julia), mas é diferente da indexação a partir de zero do C e de muitos de seus sucessores.

Intervalos podem ser usados, como no exemplo acima, mas também na função c(), que é muito flexível:

v <- c(4, 7, 10)
w <- c(2, v[2:3], 11) # c(2, 7, 10, 11)

vectors (como a maioria das coisas em R) podem ser tratados como mutáveis, usando uma sintaxe igualmente flexível para escrever em um ou vários elementos:

v <- 1:10
v[2] <- 42
v[4:6] <- c(11, 12, 13)
v
#> [1]  1 42  3 11 12 13  7  8  9 10

Índices negativos

Programadores acostumados com outras linguagens podem achar que v[-1] é uma forma de acessar o último elemento de um vetor. Errado! Use tail() para isso.

v <- c(2, 4, 6) # defaults to last 6 entries
tail(v)
#> [1] 2 4 6
tail(v, n=1) # just the last entry
#> [1] 6

Na verdade, índices negativos são uma forma de remover um elemento:

v <- c(2, 4, 6)
v[-2]
#> [1] 2 6  # second element gone

Isso retorna uma cópia mais curta do vetor. O próprio v não muda.

Condicionais com vetores

Aplicar comparações a um vetor retorna um vetor de mesmo comprimento com valores Boolean. Isso pode ser muito conveniente em funções como all() e any():

v <- c(4, 7, 10)
v >= 6
#> [1] FALSE  TRUE  TRUE
all(v > 6)
#> [1] FALSE    # not all elements match this condition
any(v > 6)
#> [1] TRUE     # at least one element matches

Para expressões lógicas mais complicadas, é importante usar os operadores & e |, que funcionam em vetores. Os operadores de dois caracteres && e || servem apenas para comparar valores únicos, como discutido no [conceito Boolean][concept-boolean].

v <- c(4, 7, 10)
v %% 2 == 0 & v > 5
#> [1] FALSE FALSE  TRUE

Vetores estão em toda parte no R

Voltaremos a esse assunto em tópicos posteriores. Por enquanto, repare apenas no formato da saída no console:

1:20
#> [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17
#> [18] 18 19 20

As linhas começam com números em [ ] para indicar o índice do primeiro elemento (útil para vetores longos que quebram em várias linhas). Mas por que valores únicos são precedidos de [1]?

Note

Não existem valores verdadeiramente escalares em R!

O que parece ser um único número ou letra é, na verdade, um vetor de comprimento 1.

Já vimos indícios disso nos conceitos Noções Básicas e Boolean, com os tipos numéricos e lógicos.

Uma palavra sobre a notação

Os vetores descritos acima são mais formalmente conhecidos como atomic vectors. Isso porque eles só podem conter valores simples e indivisíveis (daí o termo "atômico"), como numeric, character e boolean. Estruturas mais complexas podem formar recursive vectors, que serão apresentados quando discutirmos lists.

Editar via GitHub O link abre em uma nova janela ou aba

Aprenda Vetores