Adaptado dos materiais de aula do Rogério Barbosa.
Loops e Estruturas de controle
Loops são funções de iteração que nos permitem realizar tarefas repetidas de forma automatizada. Os loops estão presentes em qualquer linguagem de programação.
As três principais funções de loop são for
, while
e repeat
.
Loop For
A estrutura do loop for é esta:
for (contador in conjunto_de_valores){
funcao_a_executar1
funcao_a_executar2
funcao_a_executar3
}
Vamos começar. Podemos ler o comando abaixo da seguinte forma: para cada número no conjunto de números de um a 10, “imprima” o número.
for (i in 1:10){
print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
No comando acima, o “contador” e a expressao i e o “conjunto de valores” e o vetor numerico c(1,2,3,4,5,6,7,8,9,10). O numero de elementos do conjunto de valores determina quantas vezes as tarefas serao repetidas Nesse caso, esse vetor tem 10 elementos. Entao, o loop sera executado 10 vezes.
Na primeira iteracao, i assume o valor do primeiro elemento do conjunto. No caso, “1”. E entao executamos uma funcao: print(i). Com isso, o valor de i sera apresentado na tela. Na segunda iteracao, i assume o valor do segundo elemento; no caso, 2… e assim por diante.
Podemos fazer o mesmo modificando a saída para i^2
.
for (numero in 1:10){
print(numero^2)
}
## [1] 1
## [1] 4
## [1] 9
## [1] 16
## [1] 25
## [1] 36
## [1] 49
## [1] 64
## [1] 81
## [1] 100
podemos executar várias coisas dentro de um loop. Vamos pedir uma média para todas as variáveis numéricas do banco iris.
data(iris)
for (var in 1:4){
print(
mean(iris[,var])
)
}
## [1] 5.843333
## [1] 3.057333
## [1] 3.758
## [1] 1.199333
Podemos ainda fazer loops dentro de loops. Vamos preencher, com uma estrutura de loops aninhados, uma matriz. Primeiro criamos uma matriz com 10 colunas e 20 linhas. Todas as entradas sao zero:
A = matrix(0,ncol=10,nrow=20)
A
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0 0 0 0 0 0 0 0 0 0
## [2,] 0 0 0 0 0 0 0 0 0 0
## [3,] 0 0 0 0 0 0 0 0 0 0
## [4,] 0 0 0 0 0 0 0 0 0 0
## [5,] 0 0 0 0 0 0 0 0 0 0
## [6,] 0 0 0 0 0 0 0 0 0 0
## [7,] 0 0 0 0 0 0 0 0 0 0
## [8,] 0 0 0 0 0 0 0 0 0 0
## [9,] 0 0 0 0 0 0 0 0 0 0
## [10,] 0 0 0 0 0 0 0 0 0 0
## [11,] 0 0 0 0 0 0 0 0 0 0
## [12,] 0 0 0 0 0 0 0 0 0 0
## [13,] 0 0 0 0 0 0 0 0 0 0
## [14,] 0 0 0 0 0 0 0 0 0 0
## [15,] 0 0 0 0 0 0 0 0 0 0
## [16,] 0 0 0 0 0 0 0 0 0 0
## [17,] 0 0 0 0 0 0 0 0 0 0
## [18,] 0 0 0 0 0 0 0 0 0 0
## [19,] 0 0 0 0 0 0 0 0 0 0
## [20,] 0 0 0 0 0 0 0 0 0 0
Agora vamos substituir os valores de cada celula usando loops:
for(i in 1:nrow(A)){
for(j in 1:ncol(A)){
A[i,j]=i*j
}
}
A
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 1 2 3 4 5 6 7 8 9 10
## [2,] 2 4 6 8 10 12 14 16 18 20
## [3,] 3 6 9 12 15 18 21 24 27 30
## [4,] 4 8 12 16 20 24 28 32 36 40
## [5,] 5 10 15 20 25 30 35 40 45 50
## [6,] 6 12 18 24 30 36 42 48 54 60
## [7,] 7 14 21 28 35 42 49 56 63 70
## [8,] 8 16 24 32 40 48 56 64 72 80
## [9,] 9 18 27 36 45 54 63 72 81 90
## [10,] 10 20 30 40 50 60 70 80 90 100
## [11,] 11 22 33 44 55 66 77 88 99 110
## [12,] 12 24 36 48 60 72 84 96 108 120
## [13,] 13 26 39 52 65 78 91 104 117 130
## [14,] 14 28 42 56 70 84 98 112 126 140
## [15,] 15 30 45 60 75 90 105 120 135 150
## [16,] 16 32 48 64 80 96 112 128 144 160
## [17,] 17 34 51 68 85 102 119 136 153 170
## [18,] 18 36 54 72 90 108 126 144 162 180
## [19,] 19 38 57 76 95 114 133 152 171 190
## [20,] 20 40 60 80 100 120 140 160 180 200
Usando condicionais
O uso de condicionais é essencial em computação. Condicionais indicam que uma ação só será realizada se uma determinada condição for cumprida.
x = 10
y = 15
if(x == 10){x = x^2}
if(y == 20){y = y^2}
x
## [1] 100
y
## [1] 15
Podemos ler os comandos acima da seguinte maneira: uma vez que atribuímos o valor 10 ao x e 15 ao y, colocamos o condicional se x for igual a 10, x deverá receber um novo valor, x ao quadrado. Se y for igual a 20, y deverá receber um novo valor, y ao quadrado. Como apenas a primeira condicional é satisfeita, apenas o valor de x é modificado.
Podemos usar uma estrutura de loop for com condicional para classificar, por exemplo, adultos num banco de dados.
banco = data.frame(sexo=c("feminino","masculino","feminino","masculino","masculino","feminino","masculino","feminino","masculino","feminino","feminino","masculino"),
idade=c(20,21,19,19,22,23,18,25,19,21,22,26),
stringsAsFactors=FALSE)
banco$adulto = NA
for (i in 1:nrow(banco)){
if (banco$idade[i] >=21){
banco$adulto[i] = "Adulto"
}
else {
banco$adulto[i] = "Jovem"
}
}
banco
## sexo idade adulto
## 1 feminino 20 Jovem
## 2 masculino 21 Adulto
## 3 feminino 19 Jovem
## 4 masculino 19 Jovem
## 5 masculino 22 Adulto
## 6 feminino 23 Adulto
## 7 masculino 18 Jovem
## 8 feminino 25 Adulto
## 9 masculino 19 Jovem
## 10 feminino 21 Adulto
## 11 feminino 22 Adulto
## 12 masculino 26 Adulto
Aqui, criamos uma nova variável adulto e a recodificamos segundo criterio de idade ser maior ou igual a 21 anos.
Outro exemplo de recodificação com o banco de dados do Enade (que trabalhamos na aula 2). Sabemos, consultando o questionário do aluno, que as variáveis 101 até 142 (organização didático-pedagógica) tem as opções 7 e 8 codificadas respectivamente como “não sei responder” e “não se aplica”. Precisamos recodificá-las como NA’s para que nossa análise fique correta. Para fazer isso de modo bem fácil, podemos utilizar a função recode
do pacote car
. Podemos fazer:
library(readr)
enade <- read_csv2("/home/neylson/enade.csv", col_names = T)
library(descr)
freq(enade[,101], plot=F) # verificando as categorias da variável 101
## enade[, 101]
## Frequência Percentual % Válido
## 1 56 0.56 0.6444
## 2 110 1.10 1.2658
## 3 292 2.92 3.3602
## 4 1065 10.65 12.2555
## 5 2028 20.28 23.3372
## 6 4983 49.83 57.3418
## 7 97 0.97 1.1162
## 8 59 0.59 0.6789
## NA's 1310 13.10
## Total 10000 100.00 100.0000
library(plyr)
for (i in 101:142){
print(i)
enade[,i] <- mapvalues(enade[,i], from=c(7,8), to=c(NA,NA))
}
## [1] 101
## [1] 102
## [1] 103
## [1] 104
## [1] 105
## [1] 106
## [1] 107
## [1] 108
## [1] 109
## [1] 110
## [1] 111
## [1] 112
## [1] 113
## [1] 114
## [1] 115
## [1] 116
## [1] 117
## [1] 118
## [1] 119
## [1] 120
## [1] 121
## [1] 122
## [1] 123
## [1] 124
## [1] 125
## [1] 126
## [1] 127
## [1] 128
## [1] 129
## [1] 130
## [1] 131
## [1] 132
## [1] 133
## [1] 134
## [1] 135
## [1] 136
## [1] 137
## [1] 138
## [1] 139
## [1] 140
## [1] 141
## [1] 142
freq(enade[,101], plot=F) # após a recodificação
## enade[, 101]
## Frequência Percentual % Válido
## 1 56 0.56 0.6562
## 2 110 1.10 1.2890
## 3 292 2.92 3.4216
## 4 1065 10.65 12.4795
## 5 2028 20.28 23.7638
## 6 4983 49.83 58.3900
## NA's 1466 14.66
## Total 10000 100.00 100.0000
Loop While
O loop while é executado até que uma condição seja satisfeita.
x <- 10
numero_da_iteracao <- 0
while(x > -2){
print(paste("Esta é a iteração", numero_da_iteracao))
x <- rnorm(1)
numero_da_iteracao = numero_da_iteracao + 1
}
## [1] "Esta é a iteração 0"
## [1] "Esta é a iteração 1"
## [1] "Esta é a iteração 2"
## [1] "Esta é a iteração 3"
## [1] "Esta é a iteração 4"
## [1] "Esta é a iteração 5"
## [1] "Esta é a iteração 6"
## [1] "Esta é a iteração 7"
## [1] "Esta é a iteração 8"
## [1] "Esta é a iteração 9"
## [1] "Esta é a iteração 10"
## [1] "Esta é a iteração 11"
## [1] "Esta é a iteração 12"
## [1] "Esta é a iteração 13"
## [1] "Esta é a iteração 14"
## [1] "Esta é a iteração 15"
## [1] "Esta é a iteração 16"
## [1] "Esta é a iteração 17"
## [1] "Esta é a iteração 18"
## [1] "Esta é a iteração 19"
## [1] "Esta é a iteração 20"
## [1] "Esta é a iteração 21"
## [1] "Esta é a iteração 22"
## [1] "Esta é a iteração 23"
## [1] "Esta é a iteração 24"
## [1] "Esta é a iteração 25"
## [1] "Esta é a iteração 26"
## [1] "Esta é a iteração 27"
## [1] "Esta é a iteração 28"
## [1] "Esta é a iteração 29"
## [1] "Esta é a iteração 30"
## [1] "Esta é a iteração 31"
## [1] "Esta é a iteração 32"
## [1] "Esta é a iteração 33"
## [1] "Esta é a iteração 34"
## [1] "Esta é a iteração 35"
## [1] "Esta é a iteração 36"
## [1] "Esta é a iteração 37"
## [1] "Esta é a iteração 38"
## [1] "Esta é a iteração 39"
## [1] "Esta é a iteração 40"
## [1] "Esta é a iteração 41"
## [1] "Esta é a iteração 42"
## [1] "Esta é a iteração 43"
## [1] "Esta é a iteração 44"
## [1] "Esta é a iteração 45"
## [1] "Esta é a iteração 46"
## [1] "Esta é a iteração 47"
## [1] "Esta é a iteração 48"
## [1] "Esta é a iteração 49"
## [1] "Esta é a iteração 50"
## [1] "Esta é a iteração 51"
## [1] "Esta é a iteração 52"
## [1] "Esta é a iteração 53"
## [1] "Esta é a iteração 54"
## [1] "Esta é a iteração 55"
## [1] "Esta é a iteração 56"
## [1] "Esta é a iteração 57"
## [1] "Esta é a iteração 58"
## [1] "Esta é a iteração 59"
## [1] "Esta é a iteração 60"
## [1] "Esta é a iteração 61"
## [1] "Esta é a iteração 62"
## [1] "Esta é a iteração 63"
## [1] "Esta é a iteração 64"
## [1] "Esta é a iteração 65"
## [1] "Esta é a iteração 66"
## [1] "Esta é a iteração 67"
## [1] "Esta é a iteração 68"
## [1] "Esta é a iteração 69"
## [1] "Esta é a iteração 70"
## [1] "Esta é a iteração 71"
## [1] "Esta é a iteração 72"
## [1] "Esta é a iteração 73"
## [1] "Esta é a iteração 74"
## [1] "Esta é a iteração 75"
## [1] "Esta é a iteração 76"
## [1] "Esta é a iteração 77"
## [1] "Esta é a iteração 78"
Loop Repeat
O loop repeat é executado infinitamente. É bom que coloquemos uma condição para que ele pare usando a função break
.
i=0
repeat{
print(i)
i=i+1
if(i > 1000) {
break
}
}
A família APPLY (INTRO)
O R possui uma família de funções chamada apply()
para realizar loops de forma intuitiva e com muita eficiência computacional.
A família possui a função genérica apply()
e suas variações sapply()
, lapply()
, tapply()
, mapply()
, dentre outras. Hoje vamos trabalhar com lapply e sapply.
Podemos executar um comando para várias variáveis de uma só vez, por exemplo, tirar a média. Lapply recebe uma lista como argumento e retorna uma nova lista.
x <- list(Componente1=1:50, Componente2=seq(2,10,by=.2))
x
## $Componente1
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
## [24] 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
## [47] 47 48 49 50
##
## $Componente2
## [1] 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6
## [15] 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 7.2 7.4
## [29] 7.6 7.8 8.0 8.2 8.4 8.6 8.8 9.0 9.2 9.4 9.6 9.8 10.0
lapply(x,mean)
## $Componente1
## [1] 25.5
##
## $Componente2
## [1] 6
Sapply retorna os valores simplificados.
sapply(iris[,1:4], mean)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 5.843333 3.057333 3.758000 1.199333
Tapply executa uma função por grupos.
# Sem tapply
mean(iris$Petal.Width[iris$Species=="virginica"])
## [1] 2.026
mean(iris$Petal.Width[iris$Species=="setosa"])
## [1] 0.246
mean(iris$Petal.Width[iris$Species=="versicolor"])
## [1] 1.326
# Com tapply...
tapply(iris$Petal.Width, iris$Species, mean)
## setosa versicolor virginica
## 0.246 1.326 2.026