Estrutura da linguagem

R
Programação
Estrutura da linguagem R, incluindo operações básicas, tipos de objetos (vetores, data frames, matrizes, listas) e sintaxe principal.

R é um ambiente de software livre para computação estatística e gráfica que roda em uma variedade de plataformas UNIX, Windows e MacOS (R Project). A instalação pode ser feita a partir do site oficial CRAN, seguindo as instruções para cada plataforma. O RStudio é uma Interface de Desenvolvimento Integrado (IDE) dedicada ao ambiente R, embora existam outras opções como Jupyter Notebook, Jupyter Lab, Visual Studio Code e Google Colab.

1 O R para cálculos aritméticos

Vamos iniciar nossa introdução ao R com seu uso mais simples, um ambiente para cálculos aritméticos. Como você verá, o R usa os operadores matemáticos de subtração (-), adição (+), multiplicação (*), divisão (/) e potenciação (^) do modo análogo a outros softwares.

2 + 4
[1] 6
2 * 4
[1] 8
2 - 4
[1] -2
2^4
[1] 16

Além destes, temos operadores para extrairmos a parte inteira (%%) e o resto (%/%) de uma divisão.

13%/%2
[1] 6
13%%2
[1] 1

O uso de parênteses também permite o controle das operações matemáticas seguindo as prioridades conhecidas nestas operações. Por exemplo, a expressão:

5 * (9 + 2)
[1] 55

é diferente de:

5 * 9 + 2
[1] 47

Assim como a expressão:

(3 + 4)^2
[1] 49

é diferente de:

3 + 4^2
[1] 19

Existem também funções aritméticas comuns como \(log(x)\), \(\sqrt(x)\), \(\sin(x)\), o número \(\pi\), etc.

log(100)
[1] 4.60517
log10(100)
[1] 2
log(100, base = 2)
[1] 6.643856
sqrt(36)
[1] 6
pi
[1] 3.141593
sin(0.5 * pi)
[1] 1

2 Atribuição de valores

O R se estrutura por meio de objetos. Ao atribuir um valor a uma variável, esta se torna um objeto que fica disponível na memória. Para atribuir valor \(2\) à variável x fazemos:

x <- 2
x
[1] 2

Após atribuir um valor à variável, esta fica disponível na memória da seção atual e pode ser utilizada em operações subsequentes.

y <- x + 10
y
[1] 12

Ao atribuir outro valor à mesma variável, o valor inicial é substituído:

x <- 5
y <- x + 10
y
[1] 15

O R diferencia caracteres minúsculos de MAIÚSCULOS. Portanto:

a <- sqrt(49)
A <- sqrt(81)
a
[1] 7
A
[1] 9

3 Estruturas de dados

Os objetos em R podem ser vetores (numéricos, alfanuméricos ou fatores), matrizes (numéricas ou alfanumétricas), data frames (estrutura bidimensional que pode combinar colunas de diferentes tipos como vetores numéricos, alfanuméricos ou fatores) ou listas (que pode combinar em sua estrutura, todos os objetos descritos acima). As funções em R são sequências de comandos que podem transformar objetos.

3.1 Vetores numéricos

Os objetos podem guardar mais de um único valor. A função concatenar c() pode ser utilizada para criar um vetor com múltiplos valores. Dizemos que cada valor individual é uma entrada.

x <- c(4, 3.0, 5, 9, 10)
x
[1]  4  3  5  9 10

Podemos utilizar estes vetores em nossas operações.

y <- x * 2
y
[1]  8  6 10 18 20

Note que na operação acima, cada entrada foi multiplicada por \(2\).

Podemos ainda acessar e modificar entradas individuais. Por exemplo, o objeto y criado acima tem 5 elementos. O segundo elemento pode ser acessado com o comando:

y[2]
[1] 6

E alterado com o comando:

y[2] <- 300
y
[1]   8 300  10  18  20

Se quisermos excluir o quarto elemento de y e gravar o resultado em um novo objeto z fazemos:

z <- y[-4]
z
[1]   8 300  10  20

Obs: Veja que o quarto elemento, 18, foi excluído.

Podemos obter a informação sobre o número de elementro do vetor. O vetor y tem tamanho igual a 5, enquanto o vetor z tem 4 elementos.

length(y)
[1] 5
length(z)
[1] 4

Sequências regulares e repetições

Podemos criar sequencias regulares.

2:10
[1]  2  3  4  5  6  7  8  9 10
seq(2, 10, by = 2)
[1]  2  4  6  8 10
seq(2, 10, length = 4)
[1]  2.000000  4.666667  7.333333 10.000000
seq(2, 10, length = 10)
 [1]  2.000000  2.888889  3.777778  4.666667  5.555556  6.444444  7.333333
 [8]  8.222222  9.111111 10.000000

E repetições de valores e vetores.

rep(4, times = 6)
[1] 4 4 4 4 4 4
rep(c(2, 5), times = 3)
[1] 2 5 2 5 2 5
rep(c(2, 5), each = 3)
[1] 2 2 2 5 5 5

Os resultados destas sequências podem ser guardadas em um objeto para utilização subsequente.

a <- seq(2, 10, by = 2)
a
[1]  2  4  6  8 10
b <- seq(10, 2, by = -2)
b
[1] 10  8  6  4  2
c <- a + b
c
[1] 12 12 12 12 12

3.2 Vetores alfanuméricos

São vetores em que cada entrada é um caracter alfanumerico.

especie = c("Deuterodon iguape", 
            "Characidium japuhybense", 
            "Trichomycterus zonatus")
especie
[1] "Deuterodon iguape"       "Characidium japuhybense"
[3] "Trichomycterus zonatus" 

Existe uma variedade de funções para manipulação de vetores alfanuméricos.

A função sort() por exemplo, aplicada a um vetor numérico é utilizada para ordená-lo de forma crescente:

a = c(5,2,15,12)
a
[1]  5  2 15 12
sort(a)
[1]  2  5 12 15

ou decrescente:

sort(a, decreasing = T)
[1] 15 12  5  2

Se aplicada a um vetor alfanumerico esta função ordena o vetor em ordem alfabética:

sort(especie, decreasing = FALSE)
[1] "Characidium japuhybense" "Deuterodon iguape"      
[3] "Trichomycterus zonatus" 
sort(especie, decreasing = TRUE)
[1] "Trichomycterus zonatus"  "Deuterodon iguape"      
[3] "Characidium japuhybense"

3.3 Unindo vetores: comando paste

Suponha que desejamos unir dois vetores alfanuméricos

x1 <- c("Experimento")
x2 <- c("A", "B", "C")
x3 <- paste(x1, x2, sep = "_")

O mesmo resultado pode ser obtido de forma mais concisa com o comando:

x4 <- paste("Experimento", LETTERS[1:3], sep = "_")
x4
[1] "Experimento_A" "Experimento_B" "Experimento_C"

3.4 Fatores

Fatores são como vetores alfanuméricos, porém com um atributo adicional. Fatores são compostos por diferentes níveis. Por exemplo, podemos criar o objeto dosagem com o comando:

dosagem <- c("Alta", "Alta", "Alta", 
            "Media", "Media", "Media", 
            "Baixa", "Baixa", "Baixa")
dosagem
[1] "Alta"  "Alta"  "Alta"  "Media" "Media" "Media" "Baixa" "Baixa" "Baixa"

No exemplo acima, o R não reconhece as palavras Alta, Media e Baixa como diferentes níveis. Para isto devemos transformá-lo em um fator:

dosagem <- factor(dosagem)
dosagem
[1] Alta  Alta  Alta  Media Media Media Baixa Baixa Baixa
Levels: Alta Baixa Media

O objeto dosagem agora é um fator com 3 níveis.

levels(dosagem)
[1] "Alta"  "Baixa" "Media"
nlevels(dosagem)
[1] 3
levels(dosagem)[2]
[1] "Baixa"

Note entretanto que os níveis foram reconhecidos em ordem alfabética. Se quisermos ordenar este níveis de outro modo fazemos:

dosagem <- factor(dosagem, ordered = TRUE, 
                 levels = c("Baixa", "Media", "Alta"))
dosagem
[1] Alta  Alta  Alta  Media Media Media Baixa Baixa Baixa
Levels: Baixa < Media < Alta

Como veremos a frente, esta operação facilita a visualização gráfica de fatores ordenados.

3.5 Matrizes

Matrizes são objetos compostos por linhas e colunas. No R, uma matriz pode ser construída inicialmente criando um vetor numérico:

a <- c(21,26,5,18,17,28,20,15,13,14,27,22)
a
 [1] 21 26  5 18 17 28 20 15 13 14 27 22

Em seguida o vetor pode ser organizado em uma matriz definindo-se o número de linhas e de colunas que sejam compatíveis com o tamanho do vetor. No exemplo acima o vetor tem comprimento 12 e pode ser organizado em uma matriz de \(3\) linhas e \(4\) colunas:

x <- matrix(a, nrow = 3, ncol = 4)
x
     [,1] [,2] [,3] [,4]
[1,]   21   18   20   14
[2,]   26   17   15   27
[3,]    5   28   13   22

Note que os elementos foram adicionados um por vez de coluna em coluna. Se quisermos preencher a matriz por linhas adicionamos ao comando, o argumento byrow = TRUE.

x <- matrix(a, nrow = 3, ncol = 4, byrow = TRUE)
x
     [,1] [,2] [,3] [,4]
[1,]   21   26    5   18
[2,]   17   28   20   15
[3,]   13   14   27   22

Os elementos de uma matriz podem ser acessados indicando sua posição na linha e na coluna. Por exemplo, o elemento da \(2^a\) linha e \(3^a\) coluna de x pode ser acessados pelo comando:

x[2, 3]
[1] 20

De modo análogo, a \(2^a\) linha pode ser acessada por:

x[2, ]
[1] 17 28 20 15

E a \(4^a\) coluna por:

x[, 4]
[1] 18 15 22

Valores individuais em matrizes podem ser alterados de forma similar ao que é realizasdo em vetores. Por exemplo, para alterar o elemento da \(2^a\) linha e \(3^a\) coluna de x por \(1000\) fazemos:

x[2, 3] <- 1000
x
     [,1] [,2] [,3] [,4]
[1,]   21   26    5   18
[2,]   17   28 1000   15
[3,]   13   14   27   22

Também podemos excluir linhas e colunas de uma matriz.

x[-2,]
     [,1] [,2] [,3] [,4]
[1,]   21   26    5   18
[2,]   13   14   27   22
x[,-3]
     [,1] [,2] [,3]
[1,]   21   26   18
[2,]   17   28   15
[3,]   13   14   22

Note que, acima, não salvamos os resultados da exclusão das linhas e colunas de x em nenhum objeto, de modo que x continua inalterado.

x
     [,1] [,2] [,3] [,4]
[1,]   21   26    5   18
[2,]   17   28 1000   15
[3,]   13   14   27   22

Podemos criar matrizes unindo vetores de tamanho iguais em linhas ou colunas.

x <- 3:12
y <- 12:3
rbind(x, y)
  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
x    3    4    5    6    7    8    9   10   11    12
y   12   11   10    9    8    7    6    5    4     3
cbind(x, y)
       x  y
 [1,]  3 12
 [2,]  4 11
 [3,]  5 10
 [4,]  6  9
 [5,]  7  8
 [6,]  8  7
 [7,]  9  6
 [8,] 10  5
 [9,] 11  4
[10,] 12  3

Eventualmente, se desejarmos atribuir nomes às linhas e às colunas de uma matriz, podemos fazê-lo por meio das funções rownames() e colnames() respectivamente:

x_mat <- matrix(1:12, nrow = 3, ncol = 4)
x_mat
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
rownames(x_mat) <- paste("Linha", 1:3, sep = "")
x_mat
       [,1] [,2] [,3] [,4]
Linha1    1    4    7   10
Linha2    2    5    8   11
Linha3    3    6    9   12
colnames(x_mat) <- paste("Coluna", 1:4, sep = "")
x_mat
       Coluna1 Coluna2 Coluna3 Coluna4
Linha1       1       4       7      10
Linha2       2       5       8      11
Linha3       3       6       9      12

3.6 Data frames

Assim como Matrizes, Data frames são estruturas que permitem organizar dados em formato de linhas e colunas. No R entanto, as Matrizes não podem guardar objetos de diferentes características. Por exemplo, uma matriz pode ser composta inteiramente numérica:

matrix(1:12, nrow = 4, ncol = 3)
     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6   10
[3,]    3    7   11
[4,]    4    8   12

Ou alfanumérica:

matrix(letters[1:12], nrow = 4, ncol = 3)
     [,1] [,2] [,3]
[1,] "a"  "e"  "i" 
[2,] "b"  "f"  "j" 
[3,] "c"  "g"  "k" 
[4,] "d"  "h"  "l" 

Porém, se tentarmos unir um vetor numérico a um vetor alfanumérico, toda a matriz será convertida no formato alfanumérico.

z <- LETTERS[3:12]
z
 [1] "C" "D" "E" "F" "G" "H" "I" "J" "K" "L"
cbind(x, z)
      x    z  
 [1,] "3"  "C"
 [2,] "4"  "D"
 [3,] "5"  "E"
 [4,] "6"  "F"
 [5,] "7"  "G"
 [6,] "8"  "H"
 [7,] "9"  "I"
 [8,] "10" "J"
 [9,] "11" "K"
[10,] "12" "L"

Para unir diferentes tipos de vetores devemos usar transformar a matriaz para um objeto do tipo data.frame que cria uma estrutura com colunas independentes, permitindo que estas tenham diferentes formatos. Podemos unir os objetos x e z acima em um data frame como segue:

data.frame(x, z)
    x z
1   3 C
2   4 D
3   5 E
4   6 F
5   7 G
6   8 H
7   9 I
8  10 J
9  11 K
10 12 L

Note que automaticamente, a função atribui nomes as colunas (x e z) e às linhas (\(1\) a 10). Estes nomes podem ser alterados com as funções rownames() e colnames().

Neste caso, a coluna x continua sendo numérica e a coluna z continua alfanumérica.

Podemos acessar os elementos de um data frame do mesmo modo que fizemos para matrizes.

Podemos criar um data frame diretamente:

Dados <- data.frame(Regiao = factor(c("Santos", "Santos", 
                                     "Bertioga", "Bertioga", 
                                     "Peruibe", "Peruibe")),
                   Especie_A = c(12,43,80,91,75,115), 
                   Especie_B = c(0, 59, 300, 350, 154, 200))

E acessá-lo de diferentes formas:

Dados
    Regiao Especie_A Especie_B
1   Santos        12         0
2   Santos        43        59
3 Bertioga        80       300
4 Bertioga        91       350
5  Peruibe        75       154
6  Peruibe       115       200
Dados$Regiao
[1] Santos   Santos   Bertioga Bertioga Peruibe  Peruibe 
Levels: Bertioga Peruibe Santos
Dados["Regiao"]
    Regiao
1   Santos
2   Santos
3 Bertioga
4 Bertioga
5  Peruibe
6  Peruibe
Dados[,"Regiao"]
[1] Santos   Santos   Bertioga Bertioga Peruibe  Peruibe 
Levels: Bertioga Peruibe Santos
Dados[,c("Especie_A","Especie_B")]
  Especie_A Especie_B
1        12         0
2        43        59
3        80       300
4        91       350
5        75       154
6       115       200

3.7 Listas

Combinam em um único objeto todas as estruturas anteriores. Veja o exemplo em que combinamos um vetor alfanumérico, um vetor nominal e um data frame dentro da mesma lista.

nossalista <- list(Ilha = c("Ilhabela", "Anchieta", "Cardoso"), 
                  Areaskm2 = c(347.5, 8.3, 131), 
                  Localizacao = data.frame(
                    Bioma = rep("Mata Atlantica", 3),
                  Lat = c(23, 25, 23),
                  Long = c(45, 47, 45)))
nossalista
$Ilha
[1] "Ilhabela" "Anchieta" "Cardoso" 

$Areaskm2
[1] 347.5   8.3 131.0

$Localizacao
           Bioma Lat Long
1 Mata Atlantica  23   45
2 Mata Atlantica  25   47
3 Mata Atlantica  23   45

Podemos ainda inserir listas dentro de outras listas, criando estruturas altamente complexas.

Para acessar os elementos de uma lista podemos identificar seu nome após o operador $ ou sua posição das formas que se seguem:

nossalista$Ilha
[1] "Ilhabela" "Anchieta" "Cardoso" 
nossalista[[1]]
[1] "Ilhabela" "Anchieta" "Cardoso" 
nossalista$Localizacao
           Bioma Lat Long
1 Mata Atlantica  23   45
2 Mata Atlantica  25   47
3 Mata Atlantica  23   45
nossalista[[3]]
           Bioma Lat Long
1 Mata Atlantica  23   45
2 Mata Atlantica  25   47
3 Mata Atlantica  23   45

4 Operadores relacionais

Operadores relacionais são aqueles de verificam as relações de menor que (<), maior que (>), menor ou igual (<=), maior ou igual (>=), igual a (==) ou diferente de (!=). O resultado de uma comparação retorna um objeto com o argumento verdadeiro (TRUE) ou falso (FALSE). Veja por exemplo:

3 > 5
[1] FALSE
3 > 3
[1] FALSE
3 >= 3
[1] TRUE
a <- 5
b <- 7
a == b
[1] FALSE
a != b
[1] TRUE

Se os objetos têm mais de um elemento, no caso de vetores, matrizes ou data frames, a comparação é feita elemento-a-elemento, comparando aqueles que estão na mesma posição, ou seja, os que têm o mesmo índice de posição.

a <- c(3,5,5,7,1)
b <- c(3,6,1,9,-3)
a < b
[1] FALSE  TRUE FALSE  TRUE FALSE

Os operadores TRUE e FALSE, quanto utilizados em operações aritméticas se comportam respectivamente como valores 1 e 0.

a <- 5
b <- c(3,6,1,9,-3)
y <- b > a
y
[1] FALSE  TRUE FALSE  TRUE FALSE

Somando os elementos de y temos o número de elementos que atendendem à condição acima:

sum(y)
[1] 2

E se tirarmos a média aritmética, teremos a proporção de 1’s no vetor y.

mean(y)
[1] 0.4
Nota

Lembre-se que ao compararmos vetores de tamanhos distintos, o R não retorna um erro, mas recicla os elementos do vetor menor para compensar elementos faltantes.

5 Operadores lógicos

Operadores lógicos são os de NEGAÇÃO (!), E lógico, OU lógico versão vetorizada (|) e OU exclusivo (xor()). Exemplos destes operadores são:

x <- 3:5
y <- 5:3
(x < 4)
[1]  TRUE FALSE FALSE
!(x < 4)
[1] FALSE  TRUE  TRUE
(x < 4) & (y > 4)
[1]  TRUE FALSE FALSE
(x < 4) | (y > 4)
[1]  TRUE FALSE FALSE
xor(x,y)
[1] FALSE FALSE FALSE