Capítulo 5 Estrutura de Dados Básicas

Em R, temos dois tipos principais de objetos: funções e dados.

  • Funções: São objetos que executam operações específicas.

    • Exemplos de funções:

      • cos() - calcula o cosseno de um ângulo.
      • print() - imprime valores no console.
      • plot() - cria gráficos.
      • integrate() - calcula a integral de uma função.
  • Dados: São objetos que contêm informações, como números, textos ou outros tipos de dados.

    • Exemplos de dados:

      • 23 (número)
      • "Hello" (texto ou string)
      • TRUE (valor lógico)
      • c(1, 2, 3) (vetor numérico)
      • data.frame(nome = c("Alice", "Bob"), idade = c(25, 30)) (estrutura tabular)
      • list(numero = 42, nome = "Alice", flag = TRUE) (coleção de elementos de diferentes tipos)
      • factor(c("homem", "mulher", "mulher", "homem")) (dados categóricos)

5.1 Vetor

Um vetor é uma estrutura de dados básica que armazena uma sequência de elementos do mesmo tipo. Os vetores podem conter dados numéricos, caracteres, valores lógicos (TRUE/FALSE), números complexos, entre outros.

  • Todos os elementos de um vetor devem ser do mesmo tipo.
  • Os elementos de um vetor são indexados a partir de 1 (ou seja, o primeiro elemento está na posição 1).
  • Os vetores podem ser criados usando a função c() (concatenate) e são facilmente manipulados com uma variedade de funções.

5.1.1 Tipos Comuns de Vetores

# Vetor numérico
c(1.1, 2.2, 3.3)
## [1] 1.1 2.2 3.3

# Vetor de caracteres
c("a", "b", "c")
## [1] "a" "b" "c"
# ou
c('a','b','c')
## [1] "a" "b" "c"

# Vetor lógico
c(TRUE, 1==2)
## [1]  TRUE FALSE

# Não podemos misturar tipos de dados em um vetor...
c(3, 1==2, "a") # Observe que o R converteu tudo para "character"!
## [1] "3"     "FALSE" "a"

5.1.2 Construindo Vetores

# Inteiros de 1 a 10
x <- 1:10
x
##  [1]  1  2  3  4  5  6  7  8  9 10

b <- 10:1
b
##  [1]  10  9  8  7  6  5  4  3  2 1

# Sequência de 0 a 50 com incrementos de 10
a <- seq(from = 0, to = 50, by=10)
a
## [1]  0 10 20 30 40 50

# Sequência de 15 números de 0 a 1
y <- seq(0,1, length=15)
y
##  [1] 0.0000 0.0714 0.1429 0.2143 0.2857 0.3571 0.4286 0.5000 0.5714 0.6429
## [11] 0.7143 0.7857 0.8571 0.9286 1.0000

# Repetição de um vetor várias vezes
z <- rep(1:3, times=4)
z
##  [1] 1 2 3 1 2 3 1 2 3 1 2 3

# Repetição de cada elemento do vetor várias vezes
t <- rep(1:3, each=4)
t
##  [1] 1 1 1 1 2 2 2 2 3 3 3 3

# Combine números, vetores ou ambos em um novo vetor
w <- c(x,z,5)
w
##  [1]  1  2  3  4  5  6  7  8  9 10  1  2  3  1  2  3  1  2  3  1  2  3  5

5.1.3 Acesso a Elementos de um Vetor

Pode aceder a elementos específicos de um vetor utilizando colchetes [ ] e índices.

# Defina um vetor com inteiros de (-5) a 5 e extraia os números com valor absoluto menor que 3:
x <- (-5):5
x
##  [1] -5 -4 -3 -2 -1  0  1  2  3  4  5

# Acesso por índice:
x[4:8]
## [1] -2 -1  0  1  2
 
# Seleção negativa (excluindo elementos):
x[-c(1:3,9:11)]
## [1] -2 -1  0  1  2

# Todos menos o último
x[-length(x)]
## [1] -5 -4 -3 -2 -1  0  1  2  3  4

# Vetor lógico para seleção
index <- abs(x)<3
index 
##  [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE

# Utilizando o vetor lógico para extrair elementos desejados:
x[index]
## [1] -2 -1  0  1  2

# Ou de forma compacta:
x[abs(x) < 3]
## [1] -2 -1  0  1  2

# Acesso a elementos com vetores predefinidos
letters[1:3]
## [1] "a" "b" "c"

letters[c(2,4,6)]
## [1] "b" "d" "f"

LETTERS[1:3]
## [1] "A" "B" "C"

y <- 1:10
y[ (y>5) ] # Seleciona qualquer número > 5
## [1]  6  7  8  9 10

y[ (y%%2==0) ] # Números divisíveis por 2
## [1]  2  4  6  8 10

y[ (y%%2==1) ] # Números não divisíveis por 2
## [1] 1 3 5 7 9

y[5] <- NA
y[!is.na(y)] # Todos os valores de y que não são NA
## [1]  1  2  3  4  6  7  8  9 10

5.1.4 Funções Comuns para Vetores

Os vetores são uma das estruturas de dados mais utilizadas no R, e existem diversas funções para manipular e obter informações sobre eles. Abaixo estão algumas das funções mais comuns usadas com vetores numéricos:

num_vector <- c(2.2, 1.1, 3.3)

# Obtém o comprimento (número de elementos) de um vetor
length(num_vector)
## [1] 3

# Calcula o valor máximo de um vetor
max(num_vector)
## [1] 3.3

# Calcula o valor mínimo de um vetor
min(num_vector)
## [1] 1.1

# Calcula a soma dos elementos de um vetor
sum(num_vector)
## [1] 6.6

# Calcula a média (valor médio) dos elementos de um vetor
mean(num_vector)
## [1] 2.2

# Calcula a mediana dos elementos de um vetor
median(num_vector)
## [1] 2.2

# Retorna um vetor contendo o mínimo e o máximo
range(num_vector)
## [1] 1.1 3.3

# Calcula a variância amostral dos elementos de um vetor
var(num_vector)
## [1] 1.21

# Calcula os quantis dos elementos de um vetor
quantile(num_vector, type = 2)
##   0%  25%  50%  75% 100% 
## 1.1  1.1  2.2  3.3  3.3 

# Calcula a soma cumulativa dos elementos de um vetor
cumsum(num_vector)
## [1] 2.2 3.3 6.6

# Calcula o produto cumulativo dos elementos de um vetor
cumprod(num_vector)
## [1] 2.20 2.42 7.99

# Ordena os elementos de um vetor em ordem crescente
sort(num_vector)
## [1] 1.1 2.2 3.3

# Ordena os elementos de um vetor em ordem decrescente
sort(num_vector, decreasing = TRUE)
## [1] 3.3 2.2 1.1

# Remove elementos duplicados de um vetor
duplicate_vector <- c(1, 2, 2, 3, 3, 3)
unique(duplicate_vector)
## [1] 1 2 3

A função which é utilizada para encontrar os índices dos elementos de um vetor que satisfazem uma condição específica. Isto é útil quando se quer localizar a posição de certos valores dentro de um vetor.

y <- c(8, 3, 5, 7, 6, 6, 8, 9, 2, 3, 9, 4, 10, 4, 11)

# Encontrar os índices dos elementos que são maiores que 5
which(y > 5)
## [1]  1  4  5  6  7  8 11 13 15

Aqui, a função which(y > 5) retorna os índices dos elementos em y que são maiores que 5. Se quiser ver os valores em y que são maiores que 5, basta fazer:

y[y>5]
## [1]  8  7  6  6  8  9  9 10 11

5.1.5 Operações com Vetores

Os vetores no R suportam operações aritméticas e lógicas de forma elementar. Isto significa que as operações são aplicadas a cada elemento do vetor.

# Adição de 1 a cada elemento do vetor
num_vector + 1  
## [1] 3.2 2.1 4.3

# Multiplicação de cada elemento por 2
num_vector * 2  
## [1] 4.4 2.2 6.6

# Comparações: verifica se cada elemento é maior que 2
num_vector > 2  
## [1]  TRUE FALSE  TRUE

# Exponenciação de elementos
c(2, 3, 5, 7)^2
## [1]  4  9 25 49

c(2, 3, 5, 7)^c(2, 3)
## [1]   4  27  25 343

c(1, 2, 3, 4, 5, 6)^c(2, 3, 4)
## [1]    1    8   81   16  125 1296

c(2, 3, 5, 7)^c(2, 3, 4)
## [1]   4  27 625  49

Os exemplos acima ilustram a propriedade de reciclagem do R. Quando operações são realizadas entre vetores de diferentes comprimentos, o R “recicla” (ou repete) o vetor menor até que corresponda ao comprimento do vetor maior. Se o comprimento do vetor maior não for um múltiplo inteiro do comprimento do vetor menor, o R emitirá um aviso.

Por exemplo:

c(2,3,5,7)^c(2,3)
## [1]   4  27  25 343

Este comando é expandido internamente para:

c(2,3,5,7)^c(2,3,2,3)
## [1]   4  27  25 343

No entanto, se os vetores não puderem ser “reciclados” perfeitamente, o R irá gerar um aviso:

c(2,3,5,7)^c(2,3,4)
## Warning in c(2, 3, 5, 7)^c(2, 3, 4): longer object length is not a multiple of
## shorter object length
## [1]   4  27 625  49

Neste caso, c(2,3,5,7)^c(2,3,4) é expandido para:

c(2,3,5,7)^c(2,3,4,2)
## [1]   4  27 625  49

Observe que o último elemento do vetor menor foi reciclado para corresponder ao comprimento do vetor maior, mas não completamente, resultando no aviso.

5.1.6 Exercícios

1. Crie os vetores:

  1. \((1,2,3,\ldots,19,20)\)

  2. \((20,19,\ldots,2,1)\)

  3. \((1,2,3,\ldots,19,20,19,18,\ldots,2,1)\)

  4. \((10,20,30,\ldots,90,10)\)

  5. \((1,1,\ldots,1,2,2,\ldots,2,3,3,\ldots,3)\) onde existem 10 ocorrências do 1, 20 ocorrências do 2 e 30 ocorrências do 3.

2. Use a função paste() para criar o seguinte vetor de caracteres de tamanho 20:

(“nome 1”, “nome 2”, \(\ldots\), “nome 20”)

3. Crie um vetor \(x_1\) igual a “A” “A” “B” “B” “C” “C” “D” “D” “E” “E”

4. Crie um vetor \(x_2\) igual a “a” “b” “c” “d” “e” “a” “b” “c” “d” “e”

5. Crie um vetor \(x_3\) igual as palavras “uva” 10 vezes, “maçã” 9 vezes, “laranja” 6 vezes e “banana” 1 vez.

6. Crie um vetor de notas notas <- c(7, 8, 9) e atribua os nomes dos alunos “Ana”, “João” e “Pedro” aos elementos. Acesse a nota do aluno “João” usando o nome. Dica: use a função names().

7. Crie um vetor de 15 números aleatórios entre 1 e 100 (use a função sample()). Ordene esse vetor em ordem crescente e depois em ordem decrescente. Encontre o menor e o maior valor no vetor.

8. Crie um vetor de 20 números aleatórios entre 1 e 50 (use a função sample()). Calcule a soma, a média, o desvio padrão e o produto de todos os elementos do vetor.

9. Crie um vetor de 10 números aleatórios entre 1 e 100 (use a função sample()). Extraia os elementos do vetor que são maiores que 50. De seguida, substitua os valores menores que 30 por 0.

10. Crie um vetor de 10 números. Verifique quais elementos são maiores que 5 e quais são pares. Crie um novo vetor que contenha apenas os números que satisfazem ambas as condições.

11. Crie um vetor com 10 números inteiros. Multiplique os elementos nas posições 2, 4 e 6 por 2. Substitua o último elemento por 100.

12. Calcule a média dos vetores:

  1. \(x = (1,0,NA, 5,7)\)

  2. \(y = (-Inf,0,1,NA,2,7,Inf)\)

13. Crie:

  1. um vetor com valores \(e^{x} \sin(x)\) nos pontos \(x=2,2.1,2.2,\ldots,6\)

  2. um vetor com valores \(\left(3,\frac{3^2}{2},\frac{3^3}{3},\ldots,\frac{3^{30}}{30}\right)\)

14. Calcule:

  1. \[\sum_{i=1}^{1000}\frac{9}{10^{i}}\]
  2. \[\sum_{i=10}^{100}i^{3}+4i^{2}\]
  3. \[\sum_{i=1}^{25}\frac{2^{i}}{i} + \frac{3^{i}}{i^2}\]

5.2 Fatores

Em R, um fator é uma estrutura de dados usada para representar dados categóricos, ou seja, dados que podem ser classificados em categorias distintas. Os fatores são amplamente utilizados em análises estatísticas e visualizações de dados, pois permitem o tratamento eficiente e consistente de variáveis categóricas.

  • Níveis: Os fatores possuem níveis (ou levels), que representam os diferentes valores possíveis que a variável categórica pode assumir. Por exemplo, para uma variável categórica que representa tamanho de roupa, os níveis poderiam ser “Pequeno”, “Médio” e “Grande”.
  • Armazenamento Interno: Internamente, os fatores são armazenados como inteiros, onde cada inteiro corresponde a um nível específico. No entanto, quando exibidos, os fatores mostram os seus rótulos (labels) para facilitar a compreensão.
  • Fatores Ordenados e Não Ordenados: Os fatores podem ser ordenados (quando há uma ordem lógica entre os níveis, como “Baixo”, “Médio”, “Alto”) ou não ordenados (quando os níveis não têm uma ordem intrínseca).

Exemplos:

# Vetor de dados categóricos
data <- c("baixo", "medio", "alto", "medio", "baixo", "alto")

# Criar um fator não ordenado a partir dos dados categóricos
factor_data <- factor(data)

print(factor_data)
## [1] baixo    medio alto   medio baixo    alto
## Levels: alto baixo medio

Por padrão, os níveis são ordenados alfabeticamente. Podemos especificar a ordem dos níveis de acordo com a lógica desejada:

# Especificar a ordem dos níveis do fator
factor_data <- factor(data, levels = c("baixo", "medio", "alto"))
print(factor_data)
## [1] baixo    medio alto   medio baixo    alto
## Levels: baixo medio alto

Para criar um fator ordenado, onde os níveis têm uma ordem específica, usamos o argumento ordered = TRUE:

# Criar um fator ordenado
ordered_factor <- factor(data, levels = c("baixo", "medio", "alto"), ordered = TRUE)
print(ordered_factor)
## [1] baixo    medio alto   medio baixo    alto
## Levels: baixo < medio < alto

# Comparação entre categorias
ordered_factor[1] < ordered_factor[3]
## TRUE

5.2.1 Manipulação de Fatores

Podemos utilizar várias funções para verificar e modificar os níveis de um fator:

# Verificar Níveis
levels(factor_data)
## [1] "baixo"    "medio" "alto"

# Modificar Níveis
levels(factor_data) <- c("Baixo", "Medio", "Alto")
print(factor_data)
## [1] Baixo    Medio Alto   Medio Baixo    Alto
## Levels: Baixo Medio Alto

5.2.2 Gerando Fatores com gl()

A função gl() (generate levels) é usada para criar fatores de maneira eficiente, especialmente quando se deseja gerar fatores com padrões repetitivos.

# Sintaxe
gl(n, k, labels = seq_len(n), ordered = FALSE)
  • n: um inteiro que fornece o número de níveis.

  • k: um inteiro que fornece o número de replicações.

  • labels: um vetor opcional de rótulos para os níveis de fatores resultantes.

  • ordered: uma lógica que indica se o resultado deve ser ordenado ou não.

# Gerar níveis de fator com gl()
gl(n=4,k=3)
##  [1] 1 1 1 2 2 2 3 3 3 4 4 4
## Levels: 1 2 3 4

# Gerar fatores com labels personalizados
gl(n=2, k=10, labels = c("mulher", "homem"))
##  [1] mulher mulher mulher mulher mulher mulher mulher mulher mulher mulher
## [11] homem  homem  homem  homem  homem  homem  homem  homem  homem  homem 
## Levels: mulher homem

# Também podemos fazer
as.factor(c(rep("mulher", 10), rep("homem", 10)))
##  [1] mulher mulher mulher mulher mulher mulher mulher mulher mulher mulher
## [11] homem  homem  homem  homem  homem  homem  homem  homem  homem  homem 
## Levels: homem mulher

5.2.3 Exercícios

1. Crie um vetor com os seguintes valores: “pequeno”, “médio”, “grande”, “pequeno”, “grande”. Em seguida, transforme esse vetor em um factor com níveis ordenados em “pequeno”, “médio” e “grande”. Exiba os níveis do factor criado.

2. Crie um factor com os valores de um vetor categórico representando as cores de carros: “vermelho”, “azul”, “preto”, “vermelho”, “branco”, “azul”. Use a função table() para contar quantos carros existem de cada cor.

3. Crie um factor representando avaliações de produtos com os valores “bom”, “médio”, “ruim”, e modifique os níveis para “excelente”, “razoável” e “insatisfatório”. Exiba o factor modificado.

4. Crie um vetor com valores categóricos: “solteiro”, “casado”, “divorciado”. Verifique se esse vetor é um factor usando a função is.factor() e depois transforme-o em um factor.

5. Crie um factor representando níveis de escolaridade com os valores “ensino superior”, “ensino secundário”, “doutoramento”, “mestrado”, “ensino secundário”, “ensino superior”. Defina uma ordem lógica para os níveis e ordene o factor em ordem crescente.

6. Crie um factor com os valores “baixo”, “alto”, “médio”, “baixo”, “alto”, e com as categorias “baixo”, “médio” e “alto”, representando níveis de pressão. Converta este factor em um vetor numérico, onde “baixo” seja 1, “médio” seja 2, e “alto” seja 3.

7. Crie um factor com as categorias “verde”, “amarelo”, “vermelho”. Substitua o nível “amarelo” por “laranja” e exiba o factor atualizado.

5.3 Matriz e Array

Em R, uma matriz é uma estrutura de dados bidimensional que contém elementos do mesmo tipo (como numérico, lógico, etc.), organizados em linhas e colunas. Já um array é uma generalização da matriz que pode ter mais de duas dimensões.

  • nrow: número de linhas;

  • ncol: número de colunas.

5.3.1 Criando matrizes

Podemos criar uma matriz em R usando a função matrix(). Veja o exemplo abaixo:

matrix(c(1,2,3,4,5,6)+exp(1), nrow=2, ncol= 3, byrow = FALSE)
##      [,1] [,2] [,3]
## [1,] 3.72 5.72 7.72
## [2,] 4.72 6.72 8.72

Podemos também realizar operações lógicas em matrizes:

# Verifica se os elementos da matriz são maiores que 6
matrix(c(1,2,3,4,5,6)+exp(1), nrow=2, ncol=3, byrow = FALSE) > 6
##       [,1]  [,2] [,3]
## [1,] FALSE FALSE TRUE
## [2,] FALSE  TRUE TRUE

5.3.2 Criando um array

Um array pode ter mais de duas dimensões e é criado usando a função array():

# Criar um array com 4 linhas, 3 colunas, e 2 camadas
A <- array(c(1:24), dim=c(4,3,2))
A
## , , 1
## 
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
## 
## , , 2
## 
##      [,1] [,2] [,3]
## [1,]   13   17   21
## [2,]   14   18   22
## [3,]   15   19   23
## [4,]   16   20   24

5.3.3 Acessar Elementos de um array

# Acessando o elemento na posição [1, 2, 1]
A[1,2,1]
## [1] 5

# Acessar todos os elementos da linha 2 da primeira camada
A[2, ,1]
## [1]  2  6 10

# Acessar toda a primeira camada (todos os elementos onde a terceira dimensão é 1)
A[,,1]
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12

# Acessar os elementos [1, 1, 1] e [2, 2, 2]
A[c(1,2), c(1,2), c(1,2)]
## , , 1
## 
##      [,1] [,2]
## [1,]    1    5
## [2,]    2    6
## 
## , , 2
## 
##      [,1] [,2]
## [1,]   13   17
## [2,]   14   18

5.3.4 Construindo Matrizes

  • rbind() (row bind): Combina objetos por linhas, empilhando-os verticalmente.
  • cbind() (column bind): Combina objetos por colunas, empilhando-os horizontalmente.

Exemplo com Vetores

# Criar dois vetores
vector1 <- c(1, 2, 3)
vector2 <- c(4, 5, 6)

# Combinar os vetores por linhas
result <- rbind(vector1, vector2)
print(result)
##         [,1] [,2] [,3]
## vector1    1    2    3
## vector2    4    5    6

# Combinar os vetores por colunas
result <- cbind(vector1, vector2)
print(result)
##      vector1 vector2
## [1,]       1       4
## [2,]       2       5
## [3,]       3       6

Exemplo com Matrizes

# Criar duas matrizes
matrix1 <- matrix(1:6, nrow = 2, ncol = 3)
matrix2 <- matrix(7:12, nrow = 2, ncol = 3)

# Combinar as matrizes por linhas
result <- rbind(matrix1, matrix2)
print(result)
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
## [3,]    7    9   11
## [4,]    8   10   12

# Combinar as matrizes por colunas
result <- cbind(matrix1, matrix2)
print(result)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    3    5    7    9   11
## [2,]    2    4    6    8   10   12

5.3.5 Acessar Elementos de uma Matriz

Podemos aceder a elementos específicos de uma matriz utilizando índices ou expressões lógicas.

# Criar uma matriz
A <- matrix((-4):5, nrow=2, ncol=5)
A
##      [,1] [,2] [,3] [,4] [,5]
## [1,]   -4   -2    0    2    4
## [2,]   -3   -1    1    3    5

# Aceder a um elemento específico
A[1,2]
## [1] -2

# Selecionar elementos negativos
A[A<0]
## [1] -4 -3 -2 -1
 
# Atribuição condicional
A[A<0]<-0
A
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    0    0    0    2    4
## [2,]    0    0    1    3    5

# Selecionar uma linha específica
A[2,]
## [1] 0 0 1 3 5

# Selecionar colunas específicas
A[,c(2,4)]
##      [,1] [,2]
## [1,]    0    2
## [2,]    0    3

5.3.6 Nomear Linhas e Colunas de uma Matriz

# Criar uma matriz
x <- matrix(rnorm(12),nrow=4)
x
##        [,1]   [,2]    [,3]
## [1,] -0.508 -0.523 -0.0258
## [2,]  1.864  2.422  0.3408
## [3,] -0.230  0.314 -1.9076
## [4,] -0.571  0.478 -0.5948

# Nomear colunas
colnames(x) <- paste("dados",1:3,sep="")
x
##      dados1 dados2  dados3
## [1,] -0.508 -0.523 -0.0258
## [2,]  1.864  2.422  0.3408
## [3,] -0.230  0.314 -1.9076
## [4,] -0.571  0.478 -0.5948

# Nomear linhas e colunas de outra matriz
y <- matrix(rnorm(15),nrow=5)
y 
##        [,1]   [,2]   [,3]
## [1,] -0.559 -1.705  0.672
## [2,] -0.796  1.176 -0.566
## [3,]  0.855 -1.474  0.804
## [4,] -0.630 -1.786 -0.973
## [5,]  1.261  0.447  0.285

colnames(y) <- LETTERS[1:ncol(y)]

rownames(y) <- letters[1:nrow(y)]

y
##        A      B      C
## a -0.559 -1.705  0.672
## b -0.796  1.176 -0.566
## c  0.855 -1.474  0.804
## d -0.630 -1.786 -0.973
## e  1.261  0.447  0.285

5.3.7 Multiplicação de matrizes

M<-matrix(rnorm(20),nrow=4,ncol=5)
N<-matrix(rnorm(15),nrow=5,ncol=3)

# Multiplicação de matrizes
M%*%N
##          [,1]    [,2]   [,3]
## [1,] -1.67927  0.8103 -3.405
## [2,] -0.33112 -0.9712 -2.352
## [3,] -0.83679 -0.2961  0.140
## [4,] -0.00563 -0.0709 -0.113

5.3.8 Adicionar Linhas e Colunas a uma Matriz

X <- matrix(c(1,2,3,4,5,6),nrow=2)
X
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6

# Adicionar uma coluna
cbind(X, c(7,8))
##      [,1] [,2] [,3] [,4]
## [1,]    1    3    5    7
## [2,]    2    4    6    8

# Adicionar uma coluna no meio
cbind(X[,1:2],c(7,8),X[,3])
##      [,1] [,2] [,3] [,4]
## [1,]    1    3    7    5
## [2,]    2    4    8    6

# Adicionar uma linha
rbind(X, c(7,8,9))
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
## [3,]    7    8    9

5.3.9 Algumas outras funções

Seja \(M\) uma matriz quadrada.

  • dimensão de uma matriz \(\to\) dim(M)

  • transposta de uma matriz \(\to\) t(M)

  • diagonal principal de uma matriz \(\to\) diag(M)

  • determinante de uma matriz \(\to\) det(M)

  • inversa de uma matriz \(\to\) solve(M)

  • autovalores e autovetores \(\to\) eigen(M)

  • soma dos elementos de uma matriz \(\to\) sum(M)

  • média dos elementos de uma matriz \(\to\) mean(M)

  • aplicar uma função a cada linha ou coluna \(\to\) apply(M,1, sum) # soma de cada linha

  • aplicar uma função a cada linha ou coluna \(\to\) apply(M,2, mean) # média de cada coluna

5.3.10 Exercícios

1. Crie uma matriz \(3 \times 4\) com os números de 1 a 12, preenchendo a matriz por colunas. Exiba a matriz e determine a soma dos elementos da segunda coluna.

2. Crie duas matrizes \(2 \times 3\) chamadas \(A\) e \(B\), cada uma preenchida com números aleatórios inteiros de 1 a 10. Em seguida, some as duas matrizes e multiplique-as elemento por elemento.

3. Crie uma matriz \(3 \times 3\) chamada \(M\) com números aleatórios entre 1 e 9. Crie também um vetor de comprimento 3 chamado \(v\). Realize a multiplicação entre a matriz \(M\) e o vetor \(v\) (ou seja, \(M \times v\)). Faça agora a multiplicação \(v \times M\).

4. Crie uma matriz \(4 \times 2\) chamada \(N\) com números sequenciais de 1 a 8. Transponha a matriz e calcule a soma dos elementos de cada linha da matriz transposta. Calcule agora a soma da primeira e segunda linha da matriz transposta.

5. Crie uma matriz \(3 \times 3\) chamada \(P\) com valores de sua escolha. Calcule o determinante da matriz \(P\). Caso o determinante seja diferente de zero, calcule também a matriz inversa de \(P\).

6. Crie uma matriz \(5 \times 5\) chamada \(Q\) com números aleatórios de 1 a 25. Extraia a submatriz composta pelas 2ª, 3ª e 4ª linhas e colunas.

7. Crie uma matriz \(3 \times 3\) com valores sequenciais de 1 a 9. Calcule a soma de todos os elementos da primeira linha e a soma de todos os elementos da terceira coluna.

8. Considere a matriz \[A = \left[ \begin{matrix} 1 & 1 & 3 \\ 5 & 2 & 6 \\ -2 & -1 & -3 \end{matrix} \right]\]

  1. Verifique que \(A^3=0\).

  2. Troque a terceira coluna pela soma da coluna 1 e coluna 3.

  3. Considere a matriz \[ M = \left[ \begin{matrix} 20 & 22 & 23 \\ 34 & 55 & 57 \\ 99 & 97 & 71 \\ 12 & 16 & 19 \\ 10 & 53 & 24 \\ 14 & 21 & 28 \end{matrix} \right], \] e troque os números pares por 0.

9. Crie uma matriz \(3\times 3\) e verifique se ela é simétrica (ou seja, se a matriz é igual à sua transposta). Teste com a matriz \[A = \left[ \begin{matrix} 1 & 2 & 3 \\ 2 & 4 & 5 \\ 3 & 5 & 6 \end{matrix}\right]\] Dica: use a função all().

10. Crie uma matriz \(4\times 4\) e calcule o traço da matriz (a soma dos elementos da diagonal principal).

11. Crie uma matriz \(5\times 5\) com valores de 1 a 25. Em seguida, extraia as colunas de índice par (colunas 2 e 4) da matriz.

12. Crie um array de dimensão 3x3x3 com valores de 1 a 27. Em seguida:

  • Acesse o elemento localizado na posição [2, 3, 1] do array.
  • Acesse a segunda “camada” (a segunda matriz) do array.
  • Todos os elementos da terceira linha da segunda camada.

13. Crie dois arrays de dimensão 2x2x2 com valores aleatórios entre 1 e 10. Realize as seguintes operações:

  • Some os dois arrays.
  • Multiplique elemento por elemento os dois arrays.
  • Calcule a média dos valores resultantes da soma dos dois arrays.
  • Multiplique a primeira matriz do primeiro array pela segunda matriz do segundo array.

5.4 Data Frame

Um data frame em R é uma estrutura de dados bidimensional usada para armazenar dados tabulares. Cada coluna num data frame pode conter valores de diferentes tipos (como numéricos, caracteres, fatores, etc.), mas todos os elementos dentro de uma coluna devem ser do mesmo tipo. Um data frame é semelhante a uma tabela em um banco de dados ou uma folha de cálculo em programas como o Excel. Os data frames podem ser criados a partir de ficheiros de dados ou convertendo vetores usando a função as.data.frame().

5.4.1 Criar um Data Frame

Para criar um data frame, pode usar a função data.frame(), especificando os nomes das colunas e os dados correspondentes:

df <- data.frame(
id = 1:4,
nome = c("Ana", "Bruno", "Carlos", "Diana"),
idade = c(23, 35, 31, 28),
salario = c(5000, 6000, 7000, 8000))
df
##   id   nome idade salario
## 1  1    Ana    23    5000
## 2  2  Bruno    35    6000
## 3  3 Carlos    31    7000
## 4  4  Diana    28    8000

Um data frame pode parecer semelhante a uma matriz, mas há diferenças importantes. Veja o exemplo de uma matriz criada com os mesmos dados:

# Comparando com uma matriz
cbind(id = 1:4,
nome = c("Ana", "Bruno", "Carlos", "Diana"),
idade = c(23, 35, 31, 28),
salario = c(5000, 6000, 7000, 8000))
##      id  nome     idade salario
## [1,] "1" "Ana"    "23"  "5000" 
## [2,] "2" "Bruno"  "35"  "6000" 
## [3,] "3" "Carlos" "31"  "7000" 
## [4,] "4" "Diana"  "28"  "8000"

Observe que na matriz, todos os dados são convertidos para o tipo character, enquanto em um data frame, cada coluna mantém seu próprio tipo de dados.

5.4.2 Aceder a Linhas e Colunas

Existem várias maneiras de acedeer a linhas e colunas num data frame:

# Aceder à coluna 'id' usando índice
df[,1]
## [1] 1 2 3 4

# Aceder à coluna 'id' usando o nome da coluna
df$id
## [1] 1 2 3 4

# Aceder à coluna 'id' usando double brackets
df[["id"]]
## [1] 1 2 3 4

# Aceder à primeira linha
df[1, ] 
##   id nome idade salario
## 1  1  Ana    23    5000

# Aceder à segunda coluna
df[, 2] 
## [1] "Ana"    "Bruno"  "Carlos" "Diana"

# Aceder ao elemento na primeira linha, segunda coluna
df[1, 2] 
## [1] "Ana"

# Subconjunto das primeiras duas linhas e colunas
df[1:2, 1:2]
##   id  nome
## 1  1   Ana
## 2  2 Bruno

# Aceder a uma entrada por nome de coluna
df[1, "nome"] 
## [1] "Ana"

# Aceder a múltiplas colunas por nome
df[c("nome", "idade")]
##     nome idade
## 1    Ana    23
## 2  Bruno    35
## 3 Carlos    31
## 4  Diana    28

5.4.3 Adicionar e Remover Colunas

Adicionar e remover colunas de um data frame é simples e direto:

# Adicionar uma nova coluna calculada
df$novo_salario <- df$salario * 1.1 
df
##   id   nome idade salario novo_salario
## 1  1    Ana    23    5000         5500
## 2  2  Bruno    35    6000         6600
## 3  3 Carlos    31    7000         7700
## 4  4  Diana    28    8000         8800

# ou 
df[["novo_salario"]] <- df$salario * 1.1 

# ou
df <- cbind(df, novo_salario = df$salario * 1.1)

# Remover uma coluna existente
df$id <- NULL
df
##     nome idade salario novo_salario
## 1    Ana    23    5000         5500
## 2  Bruno    35    6000         6600
## 3 Carlos    31    7000         7700
## 4  Diana    28    8000         8800

5.4.4 Fundir Data Frames

Data frames podem ser combinados ou fundidos usando a função merge().

# Criar dois data frames
df1 <- data.frame(curso = c("PE", "LE", "CAL"), horas = c(60, 75, 90))
df2 <- data.frame(curso = c("CAL", "PE", "LE"), creditos = c(8, 6, 7))

# Fundir data frames pela variável 'curso'
df12 <- merge(df1, df2, by = "curso")
df12
##   curso horas creditos
## 1   CAL    90        8
## 2    LE    75        7
## 3    PE    60        6

5.4.5 Explorar o Data Frame

Funções úteis para explorar e entender a estrutura de um data frame:

df <- iris

# Nomes das colunas
names(df)
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"

# Classe dos dados de uma coluna
class(df$Sepal.Length)
## [1] "numeric"

class(df$Species)
## [1] "factor"

# Dimensão do data frame
dim(df)
## [1] 150   5

# Número de linhas
nrow(df)
## [1] 150

# Número de colunas
ncol(df)
## [1] 5

# Estrutura do data frame
str(df)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

# Visualização das primeiras linhas
head(df, 3)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa

# Visualização das últimas linhas
tail(df, 5)
##     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
## 146          6.7         3.0          5.2         2.3 virginica
## 147          6.3         2.5          5.0         1.9 virginica
## 148          6.5         3.0          5.2         2.0 virginica
## 149          6.2         3.4          5.4         2.3 virginica
## 150          5.9         3.0          5.1         1.8 virginica

5.4.6 A função subset()

A função subset() em R é usada para criar subconjuntos de um data frame com base em condições lógicas. É particularmente útil quando se deseja filtrar linhas que satisfaçam certos critérios e selecionar colunas específicas ao mesmo tempo.

# Carregar o conjunto de dados 'iris'
df <- iris

# Criar um subconjunto com Sepal.Width maior que 3, selecionando apenas as colunas Petal.Width e Species
df1 <- df[df$Sepal.Width > 3, c("Petal.Width","Species")]
head(df1)
##   Petal.Width Species
## 1         0.2  setosa
## 3         0.2  setosa
## 4         0.2  setosa
## 5         0.2  setosa
## 6         0.4  setosa
## 7         0.3  setosa

# Utilizando a função subset() para o mesmo subconjunto  
(df2 <- subset(df, Sepal.Width > 3, select = c(Petal.Width, Species)))
##     Petal.Width    Species
## 1           0.2     setosa
## 3           0.2     setosa
## 4           0.2     setosa
## 5           0.2     setosa
## 6           0.4     setosa
## 7           0.3     setosa
## 8           0.2     setosa
## 10          0.1     setosa
## 11          0.2     setosa
## 12          0.2     setosa
## 15          0.2     setosa
## 16          0.4     setosa
## 17          0.4     setosa
## 18          0.3     setosa
## 19          0.3     setosa
## 20          0.3     setosa
## 21          0.2     setosa
## 22          0.4     setosa
## 23          0.2     setosa
## 24          0.5     setosa
## 25          0.2     setosa
## 27          0.4     setosa
## 28          0.2     setosa
## 29          0.2     setosa
## 30          0.2     setosa
## 31          0.2     setosa
## 32          0.4     setosa
## 33          0.1     setosa
## 34          0.2     setosa
## 35          0.2     setosa
## 36          0.2     setosa
## 37          0.2     setosa
## 38          0.1     setosa
## 40          0.2     setosa
## 41          0.3     setosa
## 43          0.2     setosa
## 44          0.6     setosa
## 45          0.4     setosa
## 47          0.2     setosa
## 48          0.2     setosa
## 49          0.2     setosa
## 50          0.2     setosa
## 51          1.4 versicolor
## 52          1.5 versicolor
## 53          1.5 versicolor
## 57          1.6 versicolor
## 66          1.4 versicolor
## 71          1.8 versicolor
## 86          1.6 versicolor
## 87          1.5 versicolor
## 101         2.5  virginica
## 110         2.5  virginica
## 111         2.0  virginica
## 116         2.3  virginica
## 118         2.2  virginica
## 121         2.3  virginica
## 125         2.1  virginica
## 126         1.8  virginica
## 132         2.0  virginica
## 137         2.4  virginica
## 138         1.8  virginica
## 140         2.1  virginica
## 141         2.4  virginica
## 142         2.3  virginica
## 144         2.3  virginica
## 145         2.5  virginica
## 149         2.3  virginica

No exemplo acima, ambas as abordagens (indexação direta e subset()) produzem o mesmo resultado, mas subset() é geralmente mais legível e conveniente quando se trata de filtragem condicional.

# Criar um subconjunto com Petal.Width igual a 0.3, excluindo a coluna Sepal.Width
(df3 <- subset(df, Petal.Width == 0.3, select = -Sepal.Width))
##    Sepal.Length Petal.Length Petal.Width Species
## 7           4.6          1.4         0.3  setosa
## 18          5.1          1.4         0.3  setosa
## 19          5.7          1.7         0.3  setosa
## 20          5.1          1.5         0.3  setosa
## 41          5.0          1.3         0.3  setosa
## 42          4.5          1.3         0.3  setosa
## 46          4.8          1.4         0.3  setosa

Neste exemplo, a função subset() é utilizada para filtrar linhas em que Petal.Width é exatamente 0.3, ao mesmo tempo que exclui a coluna Sepal.Width.

# Criar um subconjunto selecionando as colunas de Sepal.Width a Petal.Width
(df4 <- subset(df, select = Sepal.Width:Petal.Width))
##     Sepal.Width Petal.Length Petal.Width
## 1           3.5          1.4         0.2
## 2           3.0          1.4         0.2
## 3           3.2          1.3         0.2
## 4           3.1          1.5         0.2
## 5           3.6          1.4         0.2
## 6           3.9          1.7         0.4
## 7           3.4          1.4         0.3
## 8           3.4          1.5         0.2
## 9           2.9          1.4         0.2
## 10          3.1          1.5         0.1
## 11          3.7          1.5         0.2
## 12          3.4          1.6         0.2
## 13          3.0          1.4         0.1
## 14          3.0          1.1         0.1
## 15          4.0          1.2         0.2
## 16          4.4          1.5         0.4
## 17          3.9          1.3         0.4
## 18          3.5          1.4         0.3
## 19          3.8          1.7         0.3
## 20          3.8          1.5         0.3
## 21          3.4          1.7         0.2
## 22          3.7          1.5         0.4
## 23          3.6          1.0         0.2
## 24          3.3          1.7         0.5
## 25          3.4          1.9         0.2
## 26          3.0          1.6         0.2
## 27          3.4          1.6         0.4
## 28          3.5          1.5         0.2
## 29          3.4          1.4         0.2
## 30          3.2          1.6         0.2
## 31          3.1          1.6         0.2
## 32          3.4          1.5         0.4
## 33          4.1          1.5         0.1
## 34          4.2          1.4         0.2
## 35          3.1          1.5         0.2
## 36          3.2          1.2         0.2
## 37          3.5          1.3         0.2
## 38          3.6          1.4         0.1
## 39          3.0          1.3         0.2
## 40          3.4          1.5         0.2
## 41          3.5          1.3         0.3
## 42          2.3          1.3         0.3
## 43          3.2          1.3         0.2
## 44          3.5          1.6         0.6
## 45          3.8          1.9         0.4
## 46          3.0          1.4         0.3
## 47          3.8          1.6         0.2
## 48          3.2          1.4         0.2
## 49          3.7          1.5         0.2
## 50          3.3          1.4         0.2
## 51          3.2          4.7         1.4
## 52          3.2          4.5         1.5
## 53          3.1          4.9         1.5
## 54          2.3          4.0         1.3
## 55          2.8          4.6         1.5
## 56          2.8          4.5         1.3
## 57          3.3          4.7         1.6
## 58          2.4          3.3         1.0
## 59          2.9          4.6         1.3
## 60          2.7          3.9         1.4
## 61          2.0          3.5         1.0
## 62          3.0          4.2         1.5
## 63          2.2          4.0         1.0
## 64          2.9          4.7         1.4
## 65          2.9          3.6         1.3
## 66          3.1          4.4         1.4
## 67          3.0          4.5         1.5
## 68          2.7          4.1         1.0
## 69          2.2          4.5         1.5
## 70          2.5          3.9         1.1
## 71          3.2          4.8         1.8
## 72          2.8          4.0         1.3
## 73          2.5          4.9         1.5
## 74          2.8          4.7         1.2
## 75          2.9          4.3         1.3
## 76          3.0          4.4         1.4
## 77          2.8          4.8         1.4
## 78          3.0          5.0         1.7
## 79          2.9          4.5         1.5
## 80          2.6          3.5         1.0
## 81          2.4          3.8         1.1
## 82          2.4          3.7         1.0
## 83          2.7          3.9         1.2
## 84          2.7          5.1         1.6
## 85          3.0          4.5         1.5
## 86          3.4          4.5         1.6
## 87          3.1          4.7         1.5
## 88          2.3          4.4         1.3
## 89          3.0          4.1         1.3
## 90          2.5          4.0         1.3
## 91          2.6          4.4         1.2
## 92          3.0          4.6         1.4
## 93          2.6          4.0         1.2
## 94          2.3          3.3         1.0
## 95          2.7          4.2         1.3
## 96          3.0          4.2         1.2
## 97          2.9          4.2         1.3
## 98          2.9          4.3         1.3
## 99          2.5          3.0         1.1
## 100         2.8          4.1         1.3
## 101         3.3          6.0         2.5
## 102         2.7          5.1         1.9
## 103         3.0          5.9         2.1
## 104         2.9          5.6         1.8
## 105         3.0          5.8         2.2
## 106         3.0          6.6         2.1
## 107         2.5          4.5         1.7
## 108         2.9          6.3         1.8
## 109         2.5          5.8         1.8
## 110         3.6          6.1         2.5
## 111         3.2          5.1         2.0
## 112         2.7          5.3         1.9
## 113         3.0          5.5         2.1
## 114         2.5          5.0         2.0
## 115         2.8          5.1         2.4
## 116         3.2          5.3         2.3
## 117         3.0          5.5         1.8
## 118         3.8          6.7         2.2
## 119         2.6          6.9         2.3
## 120         2.2          5.0         1.5
## 121         3.2          5.7         2.3
## 122         2.8          4.9         2.0
## 123         2.8          6.7         2.0
## 124         2.7          4.9         1.8
## 125         3.3          5.7         2.1
## 126         3.2          6.0         1.8
## 127         2.8          4.8         1.8
## 128         3.0          4.9         1.8
## 129         2.8          5.6         2.1
## 130         3.0          5.8         1.6
## 131         2.8          6.1         1.9
## 132         3.8          6.4         2.0
## 133         2.8          5.6         2.2
## 134         2.8          5.1         1.5
## 135         2.6          5.6         1.4
## 136         3.0          6.1         2.3
## 137         3.4          5.6         2.4
## 138         3.1          5.5         1.8
## 139         3.0          4.8         1.8
## 140         3.1          5.4         2.1
## 141         3.1          5.6         2.4
## 142         3.1          5.1         2.3
## 143         2.7          5.1         1.9
## 144         3.2          5.9         2.3
## 145         3.3          5.7         2.5
## 146         3.0          5.2         2.3
## 147         2.5          5.0         1.9
## 148         3.0          5.2         2.0
## 149         3.4          5.4         2.3
## 150         3.0          5.1         1.8

Aqui, subset() é usado para selecionar todas as colunas desde Sepal.Width até Petal.Width.

5.4.7 A Função summary()

A função summary() é amplamente usada em R para fornecer resumos estatísticos dos dados. O comportamento de summary() varia conforme o tipo de objeto ao qual é aplicado.

# Aplicando summary() a um vetor numérico
x <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
summary(x)  
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1.00    3.25    5.50    5.50    7.75   10.00

# Aplicando summary() a uma coluna numérica de um data frame
summary(iris$Sepal.Length)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    4.30    5.10    5.80    5.84    6.40    7.90

# Aplicando summary() a um data frame completo
summary(iris) 
##   Sepal.Length   Sepal.Width    Petal.Length   Petal.Width        Species  
##  Min.   :4.30   Min.   :2.00   Min.   :1.00   Min.   :0.1   setosa    :50  
##  1st Qu.:5.10   1st Qu.:2.80   1st Qu.:1.60   1st Qu.:0.3   versicolor:50  
##  Median :5.80   Median :3.00   Median :4.35   Median :1.3   virginica :50  
##  Mean   :5.84   Mean   :3.06   Mean   :3.76   Mean   :1.2                  
##  3rd Qu.:6.40   3rd Qu.:3.30   3rd Qu.:5.10   3rd Qu.:1.8                  
##  Max.   :7.90   Max.   :4.40   Max.   :6.90   Max.   :2.5

Aplicar summary() ao data frame iris inteiro fornece resumos estatísticos para todas as colunas, incluindo estatísticas descritivas para variáveis numéricas e uma contagem de frequências para variáveis categóricas (fatores).

5.4.8 Valores ausentes

colMeans(airquality)
##   Ozone Solar.R    Wind    Temp   Month     Day 
##      NA      NA   9.958  77.882   6.993  15.804

Para eliminarmos os NAs em uma coluna podemos usar

sem_na <- subset(airquality, !is.na(Ozone))
colMeans(sem_na)
##   Ozone Solar.R    Wind    Temp   Month     Day 
##  42.129      NA   9.862  77.871   7.198  15.534

Note que o argumento na.rm=TRUE pode ser passado para a maioria das funções sumárias por exemplo, sum(), mean():

mean(airquality$Ozone, na.rm = TRUE)
## [1] 42.12931
# ou
colMeans(airquality, na.rm = TRUE)
##      Ozone    Solar.R       Wind       Temp      Month        Day 
##  42.129310 185.931507   9.957516  77.882353   6.993464  15.803922

5.4.9 Exercícios

1. Crie um data frame chamado estudantes com as colunas: Nome (caracteres), Idade (números inteiros), Curso (caracteres) e Nota (números decimais). Adicione os dados de cinco estudantes fictícios e exiba o data frame.

2. Utilize o data frame estudantes criado no exercício anterior. Aceda à coluna Nota e aumente todas as notas em 0.5. Substitua o valor da coluna Curso para “Estatística” para todos os estudantes com nota superior a 8.0.

3. Dado o data frame mtcars embutido no R, filtre as linhas onde o número de cilindros (cyl) é igual a 6 e a potência (hp) é maior que 100. Crie um novo data frame com essas informações.

4. Adicione uma nova coluna ao data frame mtcars chamada Peso_KG que converta o peso dos carros (wt) de mil libras para quilogramas (multiplicando por 453.592).

5. Utilizando o data frame mtcars, calcule a média, o mínimo e o máximo da potência (hp) para cada número diferente de cilindros (cyl). Utilize a função aggregate() para realizar esta operação.

6. Utilizando o data frame mtcars, aplique a função sapply() para calcular o desvio padrão de todas as colunas numéricas.

7. Transforme a coluna am do data frame mtcars num fator com rótulos significativos: “Automático” para 0 e “Manual” para 1. Depois, conte quantos carros existem para cada tipo de transmissão.

8. Ordene o data frame mtcars pela coluna mpg em ordem decrescente. Mostre os 5 carros mais económicos e os 5 menos económicos. Dica: use a função order().

9. Utilize o data frame mtcars, disponível no R, para criar dois novos data frames chamados carros1 e carros2. Primeiro, adicione ao data frame mtcars uma nova coluna chamada car, que conterá os nomes dos carros (os nomes das linhas do data frame original).

O data frame carros1 deve conter as colunas car, mpg e cyl, enquanto o data frame carros2 deve conter as colunas car, hp e wt.

Em seguida, utilize a função merge() para combinar os dois data frames criados (carros1 e carros2) com base na coluna car, que contém os nomes dos carros.

10. Carregue o dataset airquality e exiba as primeiras 6 linhas e as últimas 6 linhas da tabela.

11. Verifique quantos valores ausentes (NA) existem em cada coluna do dataset airquality. Dica: use a função colSums().

12. Calcule a média dos valores da coluna Solar.R no dataset airquality, ignorando os valores ausentes (NA).

13. Crie um subconjunto do dataset airquality onde a velocidade do vento (Wind) é maior que 10 e a temperatura (Temp) é maior que 80. Exiba as primeiras 6 linhas do resultado.

14. Adicione uma nova coluna ao dataset airquality chamada Temp_Wind_Sum, que seja a soma dos valores das colunas Temp e Wind. Exiba as primeiras 6 linhas da tabela modificada.

15. Carregue o dataset iris e verifique sua estrutura. Filtre as observações que pertencem à espécie “setosa”.

Crie uma nova coluna chamada Petal.Area, que representa a área das pétalas (comprimento * largura).

Filtre apenas as linhas onde a área da pétala (Petal.Area) é maior que 0.2.

Ordene o data frame resultante de acordo com o comprimento da pétala (Petal.Length) em ordem decrescente.

16. Carregue o dataset airquality e remova todas as linhas que contenham valores ausentes (NA). Use a função na.omit().

Adicione uma nova coluna chamada Temp.Celsius, que converte a temperatura em Fahrenheit (Temp) para Celsius usando a fórmula: \(Temp.Celsius = \frac{(Temp - 32)}{1.8}\)

Agrupe o data frame pelo mês (Month) e calcule a média da coluna Ozone para cada mês. Use a função aggregate().

Crie um gráfico de dispersão (plot()) para a relação entre Ozone e a nova coluna Temp.Celsius, colorindo os pontos de acordo com o mês (Month).

5.5 Listas

Em R, uma lista é uma estrutura de dados versátil que pode armazenar elementos de diferentes tipos, como vetores, matrizes, data frames, funções e até outras listas. Esta flexibilidade torna as listas uma poderosa ferramenta para manipulação de dados complexos, permitindo armazenar uma coleção heterogénea de elementos em um único objeto.

  • Flexibilidade: Ao contrário dos vetores, que são homogéneos e podem conter apenas elementos de um único tipo, as listas podem conter elementos de diferentes tipos e tamanhos.
  • Indexação: Os elementos de uma lista podem ser acedidos de várias maneiras:
  • Colchetes duplos [[ ]]: Usados para aceder elementos específicos de uma lista.
  • Operador $: Usado para aceder elementos nomeados.
  • Colchetes simples [ ]: Retornam uma sublista contendo os elementos especificados.

5.5.1 Criar e Manipular Listas

Vamos criar uma lista que contém diferentes tipos de elementos, incluindo um vetor, um vetor de caracteres, uma matriz e uma função:

# Criar uma lista com diferentes tipos de elementos
minha_lista <- list(
  nome = "Estudante",
  idade = 21,
  notas = c(85, 90, 92),
  disciplinas = c("Matemática", "Estatística", "Computação"),
  matriz_exemplo = matrix(1:9, nrow = 3, byrow = TRUE),
  media= function(x) mean(x)
)

# Visualizar a lista
print(minha_lista)
## $nome
## [1] "Estudante"
## 
## $idade
## [1] 21
## 
## $notas
## [1] 85 90 92
## 
## $disciplinas
## [1] "Matemática"  "Estatística" "Computação" 
## 
## $matriz_exemplo
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
## 
## $media
## function(x) mean(x)

# Aceder a um elemento pelo nome usando $
print(minha_lista$nome)
## [1] "Estudante"

# Aceder a um elemento pelo índice
print(minha_lista[[1]])
## [1] "Estudante"

# Aceder a uma sublista contendo os dois primeiros elementos
print(minha_lista[1:2])
## $nome
## [1] "Estudante"
## 
## $idade
## [1] 21

# Aceder à segunda nota do vetor "notas" dentro da lista
print(minha_lista$notas[2])
## [1] 90

5.5.2 Por que usar listas?

Listas são extremamente úteis em R para:

  • Armazenar resultados de diferentes tipos: Em análises estatísticas complexas, os resultados muitas vezes consistem em diferentes tipos de dados (como números, tabelas, gráficos e modelos estatísticos).
  • Agrupar dados heterogéneos: Quando se precisa manipular um conjunto de dados que inclui diversos tipos de informação (por exemplo, dados brutos, estatísticas resumidas, e resultados de modelos).
  • Passar múltiplos argumentos para funções: As listas são usadas para agrupar múltiplos parâmetros para funções, tornando-as uma ferramenta poderosa para programação funcional.

5.5.3 Exercícios

1. Crie uma lista em R chamada dados_estudante que contenha as seguintes informações sobre um estudante:

  • Nome: “João”
  • Idade: 21
  • Notas: Um vetor com as notas em Estatística (85), Matemática (90), e Computação (95).

Depois de criar a lista, aceda e imprima:

  1. O nome do estudante.
  2. A idade do estudante.
  3. A nota em Computação.

2. Considere a lista dados_estudante criada no exercício anterior. Adicione um novo elemento à lista que contenha o status de aprovação do estudante, com valor “Aprovado”. Em seguida, substitua a nota de Estatística para 88. Por fim, imprima a lista completa.

3. Crie duas listas chamadas estudante1 e estudante2 com as mesmas estruturas da lista dados_estudante. Em estudante1, use os valores:

  • Nome: “Maria”
  • Idade: 22
  • Notas: 78, 85, 90
  • Status: “Aprovado”

Em estudante2, use os valores:

  • Nome: “Carlos”
  • Idade: 23
  • Notas: 70, 75, 80
  • Status: “Aprovado”

Agora, combine estudante1 e estudante2 numa nova lista chamada turma, e imprima a lista turma.

4. Utilizando a lista turma criada no exercício anterior, faça as seguintes operações:

  1. Extraia e imprima o nome do segundo estudante.
  2. Calcule a média das notas do primeiro estudante.
  3. Altere o status do segundo estudante para “Reprovado” e imprima a lista atualizada.

5. Crie uma lista chamada estatistica_aplicada que contenha duas listas internas: turma1 e turma2. Cada uma dessas listas internas deve conter as informações de dois estudantes (com as mesmas estruturas utilizadas anteriormente). Por exemplo:

  • turma1: Contendo estudante1 e estudante2.
  • turma2: Contendo dois novos estudantes de sua escolha.

Aceda e imprima:

  1. O nome do primeiro estudante da turma2.
  2. A média das notas do segundo estudante da turma1.
  3. A lista completa estatistica_aplicada.

6. Uma fábrica produz 4 diferentes produtos e coleta informações de produção mensal. Crie uma lista chamada produtos_fabrica que contenha informações sobre 4 produtos:

  • Nome do Produto

  • Quantidade Produzida Mensalmente (em unidades)

  • Custo de Produção Unitário (em euros)

  • Preço de Venda Unitário (em euros)

  1. Calcule e adicione à lista a margem de lucro mensal de cada produto (subtraia o custo de produção do preço de venda e multiplique pela quantidade produzida). Imprima a margem de lucro mensal de cada produto.

  2. Encontre e imprima o produto que gera a maior margem de lucro mensal.

  3. Atualize o preço de venda do segundo produto, aumentando-o em 5%, e imprima a nova margem de lucro mensal desse produto.

  4. Crie uma lista com os produtos mais lucrativos, considerando aqueles cuja margem de lucro mensal é superior a 10% do custo de produção mensal.