3.3 Filtrando e ordenando matrizes e data.frames
3.3.1 Filtragem de dados
Já vimos como fazer perguntas sobre vetores (Seção 2.6.1) e obter vetores lógicos ou valores de índices que nos permitem extrair ou filtrar de vetores os dados que satisfazem às condições das perguntas feitas.
Aqui vamos estender isso para objetos de classe matrix
e data.frame
, porque é através de vetores lógicos ou de matrizes lógicas que podemos filtrar dados de objetos bidimensionais.
## [1] "data.frame"
## '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 ...
## [1] setosa versicolor virginica
## Levels: setosa versicolor virginica
## [1] "setosa" "versicolor" "virginica"
sp1 <- levels(iris$Species)[1]
# quais linhas correspondem a essa especie
vl <- iris$Species == sp1
sum(vl) # numero de linhas que satisfazem a pergunta
## [1] 50
## [1] 150
# filtrando os dados eu simplesmente uso o vetor lógico como índice de linha. O novo objeto criado terá apenas as linhas em que vl é verdadeiro
iris.sp1 <- iris[vl, ]
nrow(iris.sp1) == sum(vl) # entao esta condição é verdadeira
## [1] TRUE
# filtrar segundo duas colunas
vl <- iris$Species == sp1 # seja da especie em sp1
sum(vl) # quantas sao?
## [1] 50
## [1] 32
## [1] 28
## [1] "data.frame"
## [1] TRUE
3.3.1.1 Dados com valores ausentes
As funçõesis.na()
e na.omit()
vistas anteriormente (Seção 2.6.3) permitem eliminar linhas e colunas que tenham valores ausentes.
A presença de valores às vezes impede certas análises de serem executadas.
# vamos fazer uma cópia do objeto iris e modificar ele acrescentando alguns NAs
dd <- iris
# tem algum NA originalmente?
sum(is.na(dd)) # não tem
## [1] 0
## [1] 150 5
# pega 10 valores aletórios entre 1:150 (linhas)
v1 <- sample(1:nrow(dd), size = 10, replace = F)
# nessas linhas acrescenta NAs na coluna 2
dd[v1, 2] <- NA
# pega outros 10 valores aletórios entre 1:150 (linhas)
v1 <- sample(1:nrow(dd), size = 10, replace = F)
# nessas linhas acrescenta NAs na coluna 3
dd[v1, 3] <- NA
# pronto agora temos um data.frame com NAs
sum(is.na(dd)) # tem 20 NAs na tabela
## [1] 20
# quais linhas tem NA
vl <- is.na(dd[, 2]) | is.na(dd[, 3]) # ou é NA em 2 ou em 3 que foi onde mudei
dd[vl, ]
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species | |
---|---|---|---|---|---|
12 | 4.8 | 3.4 | NA | 0.2 | setosa |
23 | 4.6 | 3.6 | NA | 0.2 | setosa |
33 | 5.2 | 4.1 | NA | 0.1 | setosa |
35 | 4.9 | NA | 1.5 | 0.2 | setosa |
36 | 5.0 | NA | 1.2 | 0.2 | setosa |
40 | 5.1 | NA | 1.5 | 0.2 | setosa |
42 | 4.5 | NA | 1.3 | 0.3 | setosa |
53 | 6.9 | NA | NA | 1.5 | versicolor |
64 | 6.1 | 2.9 | NA | 1.4 | versicolor |
77 | 6.8 | 2.8 | NA | 1.4 | versicolor |
78 | 6.7 | NA | 5.0 | 1.7 | versicolor |
86 | 6.0 | 3.4 | NA | 1.6 | versicolor |
87 | 6.7 | NA | 4.7 | 1.5 | versicolor |
103 | 7.1 | NA | 5.9 | 2.1 | virginica |
114 | 5.7 | NA | 5.0 | 2.0 | virginica |
116 | 6.4 | 3.2 | NA | 2.3 | virginica |
130 | 7.2 | 3.0 | NA | 1.6 | virginica |
144 | 6.8 | NA | 5.9 | 2.3 | virginica |
149 | 6.2 | 3.4 | NA | 2.3 | virginica |
# use na.omit() para eliminar todas as linhas que NA em alguma coluna
sum(is.na(dd)) # tem 20 valores
## [1] 20
## [1] 0
3.3.2 Ordenação de dados
Para ordenar matrizes e data.frames
, é preciso entender a diferença entre duas funções:
sort()
ordena um vetor e retorna os valores ordenados;order()
ordena um vetor e retorna os índices dos valores ordenados. É isso que deve ser utilizado para ordenar matrizes edata.frames
.
## '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 ...
# funcao SORT()
o1 <- sort(iris$Sepal.Length) # pega os valores ordenados da coluna comprimento de sépala
o1 # sao valores de sepalas do menor para o maior
## [1] 4.3 4.4 4.4 4.4 4.5 4.6 4.6 4.6 4.6 4.7 4.7 4.8 4.8 4.8 4.8 4.8 4.9 4.9
## [19] 4.9 4.9 4.9 4.9 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.1 5.1 5.1 5.1
## [37] 5.1 5.1 5.1 5.1 5.1 5.2 5.2 5.2 5.2 5.3 5.4 5.4 5.4 5.4 5.4 5.4 5.5 5.5
## [55] 5.5 5.5 5.5 5.5 5.5 5.6 5.6 5.6 5.6 5.6 5.6 5.7 5.7 5.7 5.7 5.7 5.7 5.7
## [73] 5.7 5.8 5.8 5.8 5.8 5.8 5.8 5.8 5.9 5.9 5.9 6.0 6.0 6.0 6.0 6.0 6.0 6.1
## [91] 6.1 6.1 6.1 6.1 6.1 6.2 6.2 6.2 6.2 6.3 6.3 6.3 6.3 6.3 6.3 6.3 6.3 6.3
## [109] 6.4 6.4 6.4 6.4 6.4 6.4 6.4 6.5 6.5 6.5 6.5 6.5 6.6 6.6 6.7 6.7 6.7 6.7
## [127] 6.7 6.7 6.7 6.7 6.8 6.8 6.8 6.9 6.9 6.9 6.9 7.0 7.1 7.2 7.2 7.2 7.3 7.4
## [145] 7.6 7.7 7.7 7.7 7.7 7.9
# em ordem decrescente
o2 <- sort(iris$Sepal.Length, decreasing = T)
o2 # sao valores de sepalas do maior para o menor
## [1] 7.9 7.7 7.7 7.7 7.7 7.6 7.4 7.3 7.2 7.2 7.2 7.1 7.0 6.9 6.9 6.9 6.9 6.8
## [19] 6.8 6.8 6.7 6.7 6.7 6.7 6.7 6.7 6.7 6.7 6.6 6.6 6.5 6.5 6.5 6.5 6.5 6.4
## [37] 6.4 6.4 6.4 6.4 6.4 6.4 6.3 6.3 6.3 6.3 6.3 6.3 6.3 6.3 6.3 6.2 6.2 6.2
## [55] 6.2 6.1 6.1 6.1 6.1 6.1 6.1 6.0 6.0 6.0 6.0 6.0 6.0 5.9 5.9 5.9 5.8 5.8
## [73] 5.8 5.8 5.8 5.8 5.8 5.7 5.7 5.7 5.7 5.7 5.7 5.7 5.7 5.6 5.6 5.6 5.6 5.6
## [91] 5.6 5.5 5.5 5.5 5.5 5.5 5.5 5.5 5.4 5.4 5.4 5.4 5.4 5.4 5.3 5.2 5.2 5.2
## [109] 5.2 5.1 5.1 5.1 5.1 5.1 5.1 5.1 5.1 5.1 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0
## [127] 5.0 5.0 4.9 4.9 4.9 4.9 4.9 4.9 4.8 4.8 4.8 4.8 4.8 4.7 4.7 4.6 4.6 4.6
## [145] 4.6 4.5 4.4 4.4 4.4 4.3
# FUNCAO order()
# qual o indice dos valores ordenados em ordem crescente?
o3 <- order(iris$Sepal.Length)
o3 # esses valores correspondem aos INDICES dos valores ordenados
## [1] 14 9 39 43 42 4 7 23 48 3 30 12 13 25 31 46 2 10
## [19] 35 38 58 107 5 8 26 27 36 41 44 50 61 94 1 18 20 22
## [37] 24 40 45 47 99 28 29 33 60 49 6 11 17 21 32 85 34 37
## [55] 54 81 82 90 91 65 67 70 89 95 122 16 19 56 80 96 97 100
## [73] 114 15 68 83 93 102 115 143 62 71 150 63 79 84 86 120 139 64
## [91] 72 74 92 128 135 69 98 127 149 57 73 88 101 104 124 134 137 147
## [109] 52 75 112 116 129 133 138 55 105 111 117 148 59 76 66 78 87 109
## [127] 125 141 145 146 77 113 144 53 121 140 142 51 103 110 126 130 108 131
## [145] 106 118 119 123 136 132
## [1] 4.3 4.4 4.4 4.4 4.5 4.6 4.6 4.6 4.6 4.7 4.7 4.8 4.8 4.8 4.8 4.8 4.9 4.9
## [19] 4.9 4.9 4.9 4.9 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.1 5.1 5.1 5.1
## [37] 5.1 5.1 5.1 5.1 5.1 5.2 5.2 5.2 5.2 5.3 5.4 5.4 5.4 5.4 5.4 5.4 5.5 5.5
## [55] 5.5 5.5 5.5 5.5 5.5 5.6 5.6 5.6 5.6 5.6 5.6 5.7 5.7 5.7 5.7 5.7 5.7 5.7
## [73] 5.7 5.8 5.8 5.8 5.8 5.8 5.8 5.8 5.9 5.9 5.9 6.0 6.0 6.0 6.0 6.0 6.0 6.1
## [91] 6.1 6.1 6.1 6.1 6.1 6.2 6.2 6.2 6.2 6.3 6.3 6.3 6.3 6.3 6.3 6.3 6.3 6.3
## [109] 6.4 6.4 6.4 6.4 6.4 6.4 6.4 6.5 6.5 6.5 6.5 6.5 6.6 6.6 6.7 6.7 6.7 6.7
## [127] 6.7 6.7 6.7 6.7 6.8 6.8 6.8 6.9 6.9 6.9 6.9 7.0 7.1 7.2 7.2 7.2 7.3 7.4
## [145] 7.6 7.7 7.7 7.7 7.7 7.9
# então isso deve ser totalmente verdadeiro:
iris$Sepal.Length[o3] == sort(iris$Sepal.Length) # as comparações para a par são identicas
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [16] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [31] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [46] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [61] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [76] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [91] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [106] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [121] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [136] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
# então esta expressão também é verdadeira:
sum(iris$Sepal.Length[o3] == sort(iris$Sepal.Length)) == nrow(iris)
## [1] TRUE
# portanto a função sort ordena os valores e funcao order mostra apenas os indices dos valores ordenados. Assim, posso usar a funcao order() para ordenar data.frames, matrizes e vetores
idx <- order(iris$Sepal.Length) # indice das linhas ordenadas segundo o comprimento das sepalas
# compara com o original:
sum(iris$Sepal.Length[idx] == iris$Sepal.Length) == nrow(iris) # é FALSO porque em iris as linhas não estão originalmente ordenadas segundo o comprimento.
## [1] FALSE
# vamos mudar isso
novo.iris <- iris[idx, ] # pego o vetor de indices dos valores ordenados e uso na indexacao para ordenar o objeto original segunda a coluna escolhida
idx2 <- order(novo.iris$Sepal.Length) # indice das linhas ordenadas segundo o comprimento das sepalas
# note que agora essa expressão é verdadeira, porque o original já está ordenado segundo essa coluna
sum(novo.iris$Sepal.Length[idx2] == novo.iris$Sepal.Length) == nrow(novo.iris) # é VERDADEIRO
## [1] TRUE
# AGORA ORDENANDO POR MULTIPLAS COLUNAS
idx <- order(iris$Species, iris$Sepal.Length, decreasing = TRUE) # por especie e por sepala em ordem decrescente
# ordena segundo essas duas colunas
novo.iris <- iris[idx, ]
novo.iris[, c("Species", "Sepal.Length")]
Species | Sepal.Length | |
---|---|---|
132 | virginica | 7.9 |
118 | virginica | 7.7 |
119 | virginica | 7.7 |
123 | virginica | 7.7 |
136 | virginica | 7.7 |
106 | virginica | 7.6 |
131 | virginica | 7.4 |
108 | virginica | 7.3 |
110 | virginica | 7.2 |
126 | virginica | 7.2 |
130 | virginica | 7.2 |
103 | virginica | 7.1 |
121 | virginica | 6.9 |
140 | virginica | 6.9 |
142 | virginica | 6.9 |
113 | virginica | 6.8 |
144 | virginica | 6.8 |
109 | virginica | 6.7 |
125 | virginica | 6.7 |
141 | virginica | 6.7 |
145 | virginica | 6.7 |
146 | virginica | 6.7 |
105 | virginica | 6.5 |
111 | virginica | 6.5 |
117 | virginica | 6.5 |
148 | virginica | 6.5 |
112 | virginica | 6.4 |
116 | virginica | 6.4 |
129 | virginica | 6.4 |
133 | virginica | 6.4 |
138 | virginica | 6.4 |
101 | virginica | 6.3 |
104 | virginica | 6.3 |
124 | virginica | 6.3 |
134 | virginica | 6.3 |
137 | virginica | 6.3 |
147 | virginica | 6.3 |
127 | virginica | 6.2 |
149 | virginica | 6.2 |
128 | virginica | 6.1 |
135 | virginica | 6.1 |
120 | virginica | 6.0 |
139 | virginica | 6.0 |
150 | virginica | 5.9 |
102 | virginica | 5.8 |
115 | virginica | 5.8 |
143 | virginica | 5.8 |
114 | virginica | 5.7 |
122 | virginica | 5.6 |
107 | virginica | 4.9 |
51 | versicolor | 7.0 |
53 | versicolor | 6.9 |
77 | versicolor | 6.8 |
66 | versicolor | 6.7 |
78 | versicolor | 6.7 |
87 | versicolor | 6.7 |
59 | versicolor | 6.6 |
76 | versicolor | 6.6 |
55 | versicolor | 6.5 |
52 | versicolor | 6.4 |
75 | versicolor | 6.4 |
57 | versicolor | 6.3 |
73 | versicolor | 6.3 |
88 | versicolor | 6.3 |
69 | versicolor | 6.2 |
98 | versicolor | 6.2 |
64 | versicolor | 6.1 |
72 | versicolor | 6.1 |
74 | versicolor | 6.1 |
92 | versicolor | 6.1 |
63 | versicolor | 6.0 |
79 | versicolor | 6.0 |
84 | versicolor | 6.0 |
86 | versicolor | 6.0 |
62 | versicolor | 5.9 |
71 | versicolor | 5.9 |
68 | versicolor | 5.8 |
83 | versicolor | 5.8 |
93 | versicolor | 5.8 |
56 | versicolor | 5.7 |
80 | versicolor | 5.7 |
96 | versicolor | 5.7 |
97 | versicolor | 5.7 |
100 | versicolor | 5.7 |
65 | versicolor | 5.6 |
67 | versicolor | 5.6 |
70 | versicolor | 5.6 |
89 | versicolor | 5.6 |
95 | versicolor | 5.6 |
54 | versicolor | 5.5 |
81 | versicolor | 5.5 |
82 | versicolor | 5.5 |
90 | versicolor | 5.5 |
91 | versicolor | 5.5 |
85 | versicolor | 5.4 |
60 | versicolor | 5.2 |
99 | versicolor | 5.1 |
61 | versicolor | 5.0 |
94 | versicolor | 5.0 |
58 | versicolor | 4.9 |
15 | setosa | 5.8 |
16 | setosa | 5.7 |
19 | setosa | 5.7 |
34 | setosa | 5.5 |
37 | setosa | 5.5 |
6 | setosa | 5.4 |
11 | setosa | 5.4 |
17 | setosa | 5.4 |
21 | setosa | 5.4 |
32 | setosa | 5.4 |
49 | setosa | 5.3 |
28 | setosa | 5.2 |
29 | setosa | 5.2 |
33 | setosa | 5.2 |
1 | setosa | 5.1 |
18 | setosa | 5.1 |
20 | setosa | 5.1 |
22 | setosa | 5.1 |
24 | setosa | 5.1 |
40 | setosa | 5.1 |
45 | setosa | 5.1 |
47 | setosa | 5.1 |
5 | setosa | 5.0 |
8 | setosa | 5.0 |
26 | setosa | 5.0 |
27 | setosa | 5.0 |
36 | setosa | 5.0 |
41 | setosa | 5.0 |
44 | setosa | 5.0 |
50 | setosa | 5.0 |
2 | setosa | 4.9 |
10 | setosa | 4.9 |
35 | setosa | 4.9 |
38 | setosa | 4.9 |
12 | setosa | 4.8 |
13 | setosa | 4.8 |
25 | setosa | 4.8 |
31 | setosa | 4.8 |
46 | setosa | 4.8 |
3 | setosa | 4.7 |
30 | setosa | 4.7 |
4 | setosa | 4.6 |
7 | setosa | 4.6 |
23 | setosa | 4.6 |
48 | setosa | 4.6 |
42 | setosa | 4.5 |
9 | setosa | 4.4 |
39 | setosa | 4.4 |
43 | setosa | 4.4 |
14 | setosa | 4.3 |
# para cada especie esta ordenado por sepala:
novo.iris[novo.iris$Species == "versicolor", ]$Sepal.Length
## [1] 7.0 6.9 6.8 6.7 6.7 6.7 6.6 6.6 6.5 6.4 6.4 6.3 6.3 6.3 6.2 6.2 6.1 6.1 6.1
## [20] 6.1 6.0 6.0 6.0 6.0 5.9 5.9 5.8 5.8 5.8 5.7 5.7 5.7 5.7 5.7 5.6 5.6 5.6 5.6
## [39] 5.6 5.5 5.5 5.5 5.5 5.5 5.4 5.2 5.1 5.0 5.0 4.9
## [1] 7.9 7.7 7.7 7.7 7.7 7.6 7.4 7.3 7.2 7.2 7.2 7.1 6.9 6.9 6.9 6.8 6.8 6.7 6.7
## [20] 6.7 6.7 6.7 6.5 6.5 6.5 6.5 6.4 6.4 6.4 6.4 6.4 6.3 6.3 6.3 6.3 6.3 6.3 6.2
## [39] 6.2 6.1 6.1 6.0 6.0 5.9 5.8 5.8 5.8 5.7 5.6 4.9