Scripts em R costumam seguir um esquema sequencial.
Operação 1 -> Operação 2 -> Operação 3 …
Cada operação realiza um passo na nossa receita, até conseguirmos atingir o resultado esperado no final. Por exemplo:
Carregar pacotes -> Leitura de um banco de dados -> Correção dos dados -> Criação de variáveis derivadas -> Produção de Tabelas e Gráficos -> Salvar os resultados em disco.
No entanto, também podemos precisar operações que não seguem um fluxo sequencial, tomando caminhos diferentes dependendo do resultado que procuramos atingir. Considere o seguinte exemplo, no qual temos dados em nível municipal, mas queremos classificar as pessoas segundo regiões de estudo.
Digamos que queiramos dar nomes para a nossa variável de sexo, podemos fazer o seguinte:
Outro exemplo é prevenir determinados tipos de erro. Por exemplo, podemos verificar se uma variável tem o tipo correto antes de realizar uma operação.
# Não retorna nada
if(is.character(dado$SEXO)) {
table(dado$SEXO)
}
# Retorna a frequência
if(is.character(dado$SEXO)) {
table(dado$SEXO)
} else {
table(as.character(dado$SEXO))
}##
## 1 2
## 148497 135305
Assim, podemos controlar qual “caminho” segue nosso programa utilizando algum tipo de teste lógico. Testes lógicos são tão importantes em R, que há uma família de funções is.objeto, que retorna verdadeiro/falso para praticamente todo tipo de objeto em R.
## [1] TRUE
## [1] FALSE
## [1] FALSE
with e within são funções que ajudam a gente a realizar operações dentro de um objeto sem precisar ficar digitando objeto$variavel o tempo todo. ***
O outro tipo de controle de fluxo bastante comum é o laço, ou loop. A idéia é repetir uma operação de acordo com algum critério, por ser um número finito de vezes ou segundo algum tipo de teste. Hoje vamos ver o tipo mais simples e comum, o for.
Este loop realiza uma operação um determinado número de vezes especificado pelo usuário. Um for loop tem a seguinte estrutura básica:
## Não roda
for (contador in valores_a_serem_contados) {
[operaçao_a_ser_repetida]
[resultado_da_operação]
[contador_incrementa]
}Muitas vezes em R está estrutura está escondida e nem todos estes passos aparecem. Vejamos o loop a seguir:
within(df, {
salario_acumulado <- 1000
# Realizada uma operação para cada mês
for(contador in mes) {
# A posição onde o valor será salvo muda a cada incremento
salario_acumulado[contador+1] <-
# A posição do vetor salário também vai mudando a cada passagem
salario[contador] + salario_acumulado[contador]
# O valor de contador é automaticamente incrementado no final
}
}
)## Warning in `[<-.data.frame`(`*tmp*`, nl, value = list(contador = 12L,
## salario_acumulado = c(1000, : replacement element 2 has 13 rows to
## replace 12 rows
Podemos usar esse comportamento padrão do for loop de passar pra próxima posição automaticamente para repetir operações em que não existe uma contagem propriamente dita.
df <- data.frame(estado = c("RN", "CE", "BA", "PE", "PB"),
pessoas_pistola = c(100, 200, 300, 400, 500))
for (i in df$estado) print(df[df$estado == i, ])## estado pessoas_pistola
## 1 RN 100
## estado pessoas_pistola
## 2 CE 200
## estado pessoas_pistola
## 3 BA 300
## estado pessoas_pistola
## 4 PE 400
## estado pessoas_pistola
## 5 PB 500
Vejam que mesmo não se tratando de um número, o for loop realizou uma repetição para cada valor do vetor estado.
Além do for, existe também o while, que repete enquanto um teste lógico retornar verdadeiro, mas não vamos examiná-lo hoje.
Quando utilizamos um for, estamos explicitando no nosso código que uma sequência de repetições será feita e especificamos que repetições serão. Este é um loop explícito. Por outro lado, já devemos estar familiarizados com outro tipo de loop. Veja:
## Using ',' as decimal and '.' as grouping mark. Use read_delim() for more control.
## Parsed with column specification:
## cols(
## UF = col_double(),
## MUNIC = col_character(),
## PESO = col_double(),
## SEXO = col_double(),
## IDADE = col_double(),
## MUNI05 = col_double()
## )
Note que ao pedir para multiplicar o vetor UF, ele multiplicou todas as suas posições. Funções “vetorizadas” em R são uma forma de loop implícito, porque implicam na repetição de alguma atividade.
A função rep() pode criar repetições simples em R.
## [1] 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
## [1] 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
## [1] 1 2 3 4 1 2 3 4 1 2
## [1] 1 2 3 4 1 2 3 4 1 2
## [1] 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4
Enquanto a função seq pode criar sequências de números
## [1] 1 2 3 4 5 6 7 8 9 10
## [1] 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80
## [18] 85 90 95 100
## [1] 10 20 30 40 50 60 70 80 90 100
## [1] 1 2 3 4 5 6 7 8 9 10
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
## [23] 23 24 25
Uma função bem legal pra agrupar variáveis numéricas é cut. Veja que podemos transformar a variável de idade em grupos etários facilmente.
## Using ',' as decimal and '.' as grouping mark. Use read_delim() for more control.
## Parsed with column specification:
## cols(
## UF = col_double(),
## MUNIC = col_character(),
## PESO = col_double(),
## SEXO = col_double(),
## IDADE = col_double(),
## MUNI05 = col_double()
## )
dado$GRUPO_ET <- cut(x = dado$IDADE,
breaks = seq(0, 120, 5),
right = FALSE) # Intervalo fechado à esquerda
table(dado$GRUPO_ET)##
## [0,5) [5,10) [10,15) [15,20) [20,25) [25,30) [30,35)
## 155426 167072 196616 198907 209687 211868 199774
## [35,40) [40,45) [45,50) [50,55) [55,60) [60,65) [65,70)
## 181780 173413 164254 145115 120783 96402 72893
## [70,75) [75,80) [80,85) [85,90) [90,95) [95,100) [100,105)
## 57061 40345 25757 12048 4108 1084 145
## [105,110) [110,115) [115,120)
## 17 5 1
Você vai precisar dos pacotes questionr, tidyr.
Junte as colunas de UF e MUNIC em uma só coluna chamada MUNIAT. Dica: utilize a função unite do pacote tidyr.
Modifique a coluna SEXO para que ao invés de 1 e 2, ela apresente os valores “Homens” e “Mulheres”. Dica: ifelse.
Crie uma coluna de grupo etário. Dica: utilize cut.
Crie duas colunas: uma para região atual (REGAT) e uma para região em 2005 (REG05) a partir das colunas MUNIAT e MUNI05. As colunas devem registrar as pessoas residentes em um dos municípios da Região Metropolitana de Campinas como “RMC”, as pessoas residentes em outros municípios do estado como “ESP” e em outras UFs como “BRA”.
dado$REGAT <- NAdado[<<Teste>>, "REGAT/REG05"] <- valorTabule a matriz migratória da REGIÃO ANTERIOR x REGIÃO ATUAL. Dica: wtd.table do questionr.
Crie uma coluna que separe migrantes de não migrantes. Dica: Não migrantes tem valor NA.
Compare as tabulações cruzadas de migrantes e não migrantes por idade e sexo.
Dado o vetor 1, 2, 3, 4, crie um for loop que multiplique o elemento seguinte pelo anterior e guarde o valor em outro vetor.
Copyright © 2020 Vinícius Maia. Nenhum Direito a menos.