12  Controles de Fluxo

Status 🟨🟨🟨

12.1 Introdução

Assim como outras linguagens de programação R oferece uma série de operadores para controle de fluxo de código.

Nota

Controles de fluxo são declarações usadas na linguagem, mas não são funções.

12.2 If

O controle if é a estrutura de controle mais básica que tomada de decisão e “direcionamento” de código. Em caso negativo do teste lógico nenhuma operação é executada.

x <- 5

# Códigos equivalentes
if(x > 4) print('x é maior do que quatro')
[1] "x é maior do que quatro"
if(x > 4) { print('x é maior do que quatro')}
[1] "x é maior do que quatro"
if(x > 4) {
  print('x é maior do que quatro') }
[1] "x é maior do que quatro"
if(x > 4) { print('x é maior do que quatro')
}
[1] "x é maior do que quatro"
if(x > 4) {
  print('x é maior do que quatro')
} # o mais organizado
[1] "x é maior do que quatro"

Note que se o teste não retornar TRUE ou FALSE o R reportará erro.

x <- NA

if (x > 4) print('x é maior do que quatro')
Error in if (x > 4) print("x é maior do que quatro"): valor ausente onde TRUE/FALSE necessário

12.3 Ifelse

R possui a função ifelse, que apesar de não ser para controle de fluxo, possui lógica de uso muito semelhante ao if e por este motivo será tratada neste capítulo. Esta função efetua teste em valor de entrada e define um valor a ser retornado caso verdadeiro e outro caso falso.

O retorno de ifelse possui o mesmo formato da estrutura informada no argumento test. Esta função pode ser usada para atribuição em data frames de forma mais sucinta.

Vejamos um exemplo:

df_mtcars6 <-
  mtcars |> 
  subset(select = c('hp', 'mpg', 'cyl')) |> 
  head()

df_mtcars6                 
                   hp  mpg cyl
Mazda RX4         110 21.0   6
Mazda RX4 Wag     110 21.0   6
Datsun 710         93 22.8   4
Hornet 4 Drive    110 21.4   6
Hornet Sportabout 175 18.7   8
Valiant           105 18.1   6
df_mtcars6[df_mtcars6$hp > 100, 'RESULTADO'] <-
  df_mtcars6[df_mtcars6$hp > 100, ]$mpg

df_mtcars6[df_mtcars6$hp <= 100, 'RESULTADO'] <-
  df_mtcars6[df_mtcars6$hp <= 100,]$cyl

df_mtcars6
                   hp  mpg cyl RESULTADO
Mazda RX4         110 21.0   6      21.0
Mazda RX4 Wag     110 21.0   6      21.0
Datsun 710         93 22.8   4       4.0
Hornet 4 Drive    110 21.4   6      21.4
Hornet Sportabout 175 18.7   8      18.7
Valiant           105 18.1   6      18.1
# com ifelse
df_mtcars6$RESULTADO2 <- 
  ifelse(df_mtcars6$hp > 100, 
         df_mtcars6$mpg, 
         df_mtcars6$cyl)

df_mtcars6
                   hp  mpg cyl RESULTADO RESULTADO2
Mazda RX4         110 21.0   6      21.0       21.0
Mazda RX4 Wag     110 21.0   6      21.0       21.0
Datsun 710         93 22.8   4       4.0        4.0
Hornet 4 Drive    110 21.4   6      21.4       21.4
Hornet Sportabout 175 18.7   8      18.7       18.7
Valiant           105 18.1   6      18.1       18.1

12.4 If Else

O if else pode ser usado para inserir uma ação após o retorno negativo do teste feito pelo if.

x <- 3
if(x > 4) {
  print('x é maior do que quatro')
} else {
   print('x não é maior do que quatro')
}
[1] "x não é maior do que quatro"

Veja que podem ser usadas muitas declaração else em sequência.

x <- 3
if(x > 3) {
  print('x é maior do que três')
} else if (x < 3){
  print('x é menor do que três')
} else if (x == 3){
  print('x é igual a três')
}
[1] "x é igual a três"

12.5 Laço For

Um laço for é uma estrutura que efetua uma determinada quantidade de passos de acordo com a sequência informada. a declaração deve ser feita no formato: for(x in seq), sendo x a variável que será atualizada a cada iteração iniciando no ´rimeiro valor informado em seq e ecerrando no último. Um exemplo:

for(x in 1:5){
  print(paste('Iteração:', x))
}
[1] "Iteração: 1"
[1] "Iteração: 2"
[1] "Iteração: 3"
[1] "Iteração: 4"
[1] "Iteração: 5"

Caso se deseje mudar o incremento a cada passo pode ser usada a função seq. Também é possível usar um passo decrescente.

for(x in seq(2, 1, -0.25)) {
  print(paste('Valor de x:', x))
}
[1] "Valor de x: 2"
[1] "Valor de x: 1.75"
[1] "Valor de x: 1.5"
[1] "Valor de x: 1.25"
[1] "Valor de x: 1"

No exemplo acima, x é inicializada com valor 1 e vai sendo incrementada em 1 unidade ao início do próximo passo. Um laço for também pode fazer iterações sobre vetores com texto, por exemplo.

for(i in c('São Paulo', 'Rio de Janeiro', 'Porto Alegre')){
  print(paste('Cidade atual:', i))
}
[1] "Cidade atual: São Paulo"
[1] "Cidade atual: Rio de Janeiro"
[1] "Cidade atual: Porto Alegre"

No laço for a sequência no qual será feita a iteração é considerada antes de se iniciar o laço, assim mesmo se houver alguma alteração nesta sequência em um dos passos esta alteração não impactará na execução.

x <- 3
for(i in 1:x) {
  x <- x + 2
  print(x)
}
[1] 5
[1] 7
[1] 9

12.6 While

For x While

Um laço for é utilizado quando se tem uma sequência definida de passos. Caso se deseje executar alguma operação até o atendimeto de uma condição, use while.

A estrutura while possui a seguinte configuração: while(condição). Assim, a repetição do código dentro de um bloco while ocorre até que a condição não seja mais satisfeita. Exemplo:

condicao <- 5
while(condicao < 7){
  print(condicao)
  condicao <- condicao + 1
}
[1] 5
[1] 6

A variável condicao é iniciada com valor 5 e atende a condição se < 7. O código então é executado, imprimindo no console o valor da variavél e após esta recebe seu próprio valor mais 1. Na iteração seguinte seu valor é 6 e ainda atende a condição de se < 7. Na terceira iteração seu valor, novamente atualizado, será 7 e não cumprindo a condição o while é encerrado.

A estrutura while pode ficar operando indefinidamente se por algum motivo a condição seja sempre atendida. Teste o código abaixo e veja que ele rodará indefinidamente. Você pode pará-lo teclando ESC no teclado.

while(TRUE){
  print(condicao)
  condicao <- condicao + 1
}

12.7 Repeat

E estrutura repeat funciona de forma análoga ao while, entretanto esta não testa condição de parada. Para efetuar a parada o usuário deve fazer de forma explícita.

x <- 1
y <- 2
  
repeat{
  x <- x + y  
  print(x)  
  if (x > 11) break
}
[1] 3
[1] 5
[1] 7
[1] 9
[1] 11
[1] 13

12.8 Break e Next

O break encerra as estruturas for, while e repeat. Next, por sua vez, interrompe a execução da iteração atual e inicia a próxima.

Abaixo um exemplo com uso de break em um laço for. Note que apenas a primeira iteração é executada.

for (i in 1:3){
  print(i)
  break
}
[1] 1

Abaixo um exemplo de uso do next. Repare que o comando print('Teste') nunca é executado, pois o next interrompe a execução da iteração atual, assim tudo que for colocado após esta linha (dentro do laço) não é executado.

for (i in 1:3){
  print(i)
  next
  print('Teste')
}
[1] 1
[1] 2
[1] 3

Em caso de laços embutidos, break e next impactam apenas o mais “interno”.

for (i in 1:3){
  for (j in 1:3){
    break
    print(paste('Valor de j é:', j))
  }
  print(paste('Valor de i é:', i))
}
[1] "Valor de i é: 1"
[1] "Valor de i é: 2"
[1] "Valor de i é: 3"

DataMentor (s.d.)

R Core Team (2023)

Última atualização: 11/10/2024 - 21:49:34