R: Fluxo de controle em R: if/for/while
Última atualização: 2026-08-26
Na aula anterior, aprendemos sobre operadores, e agora nossos programas em R podem “determinar se algo é verdadeiro ou falso”. Mas simplesmente ser capaz de fazer essas determinações não é suficiente — os programas também precisam ser capazes de repetir tarefas (loops) e tomar decisões de ramificação (condições). Nesta aula, aprenderemos sobre o “fluxo de controle” no R: condições if/else, loops for/while e a instrução repeat.
O fluxo de controle no R é um pouco diferente do Python: o R delimita blocos de código com {} (em vez de usar recuo), e a instrução if/else inteira é uma única expressão. Nesta lição, vamos aprender essas diferenças.
1. O que você vai aprender
- ramificação condicional if / else / else if
- Use um loop “for” para percorrer um vetor ou uma lista
- loop while
- repetir: loop infinito (use break para sair)
- Avaliação condicional vetorizada com ifelse()
- next: Pular esta rodada; break: Sair do loop
- Principais diferenças no fluxo de controle entre R e Python
2. Uma história sobre filtragem de dados
(1) Desafio: Categorização manual
Xiao Zhao é analista de dados. Seu gerente pediu que ele segmentasse 100 clientes por idade:
- Menores de 18 anos: menores de idade
- Faixa etária de 18 a 30 anos: jovens adultos
- Idades entre 31 e 50 anos: meia-idade
- 51 anos de idade ou mais: idosos
Se você usa o Excel, teria que escrever quatro fórmulas IF aninhadas; se usa Python, teria que escrever loops e instruções if-else. Mas o R tem o ifelse(), que foi projetado especificamente para vetores—
(2) Solução utilizando R
# 5 The age of each customer
ages <- c(15, 22, 35, 50, 65)
# Done in one line of code 4 File Categories(Vectorization ifelse)
labels <- ifelse(ages < 18, "Minor",
ifelse(ages < 31, "Youth",
ifelse(ages < 51, "Middle Age", "Old Age")))
cat("Customer Segmentation:\n")
print(data.frame(Age = ages, Category = labels))
Resolva um problema de classificação de 4 classes com apenas 3 linhas de código. Essa é a vantagem “vetorizada” do fluxo de controle do R — em resumo, uma única instrução é um vetor de decisão.
3. if/else: Ramificação condicional
(1) Sintaxe básica da instrução if
# R uses { } to enclose a code block (Python uses indentation)
if (Conditions) {
Execute when the condition is true
}
age <- 18
if (age >= 18) {
cat("You're an adult now.\n")
}
# Output:You're an adult now.
(2) if-else: Escolha binária
if (Conditions) {
Execute when the condition is true
} else {
Execute when the condition is false
}
score <- 45
if (score >= 60) {
cat("Passed!\n")
} else {
cat("Fail,Need to take a makeup exam\n")
}
# Output:Fail,Need to take a makeup exam
(3) if-else if-else: ramificações múltiplas
if (Conditions1) {
Branch1
} else if (Conditions2) {
Branch2
} else {
Other
}
score <- 85
if (score >= 90) {
cat("Excellent\n")
} else if (score >= 80) {
cat("Good\n")
} else if (score >= 60) {
cat("Passing Grade\n")
} else {
cat("Fail\n")
}
# Output:Good
(4) Principais diferenças entre R e Python
| Recurso | R | Python |
|---|---|---|
| Bloco de código | {} Chaves |
Recuo (4 espaços) |
| sintaxe if | if (x > 0) { ... } |
if x > 0: |
| Expressão geral | se/senão é uma expressão (atribuível) | se/senão é uma instrução (não atribuível) |
| Operações ternárias | ifelse() Funções especiais |
x if x > 0 else -x |
# R Special Usage of:ifelse It is an expression
result <- if (score >= 60) "Passing Grade" else "Fail"
result
# [1] "Passing Grade"
else na mesma linha (se for tratada como uma única expressão). Se for dividida em duas linhas, o R exibirá um erro de sintaxe.
4. ifelse(): Tomada de decisão vetorizada
(1) Por que precisamos do ifelse()?
A função padrão if só pode avaliar um único valor, mas no R, muitas vezes é necessário avaliar um vetor inteiro. Nesse caso, use ifelse():
graph LR
A["x = 1, 2, 3, 4, 5"] --> B["ifelse x > 3 yes no"]
B --> C["no no no yes yes"]
style A fill:#cce5ff
style C fill:#d4edda
# Regular if It will throw an error(Only accept lengths 1)
x <- c(1, 2, 3, 4, 5)
if (x > 3) "L" else "S" # Error: condition has length > 1
# Use ifelse() to resolve
ifelse(x > 3, "L", "S")
# [1] "S" "S" "S" "L" "L"
(2) Sintaxe do ifelse()
ifelse(Conditions, The value when the condition is true, Value when the condition is false)
(3) ifelse() aninhado: classificação em vários níveis
ages <- c(15, 22, 35, 50, 65)
# 4 File Categories
labels <- ifelse(ages < 18, "Minor",
ifelse(ages < 31, "Youth",
ifelse(ages < 51, "Middle Age", "Old Age")))
print(data.frame(Age = ages, Category = labels))
Resultado:
Age Category
1 15 Minor
2 22 Youth
3 35 Middle Age
4 50 Middle Age
5 65 Old Age
ifelse() Se você tiver mais de 3 níveis de aninhamento, recomendamos usar dplyr::case_when() (abordado na Lição 10) para maior clareza.
5. Loop “for”: Iterando pelos elementos
(1) Sintaxe básica do loop “for”
for (Variable in Vector) {
Code executed in each iteration
}
(2) Iterando por um vetor
# Iteration 1:5
for (i in 1:5) {
cat("Iteration", i, "of the loop\n")
}
# Output:
# Iteration 1 of the loop
# Iteration 2 of the loop
# Iteration 3 of the loop
# Iteration 4 of the loop
# Iteration 5 of the loop
# Iterating Through a Character Vector
fruits <- c("Apple", "Banana", "Cherries")
for (fruit in fruits) {
cat("I like to eat", fruit, "\n")
}
(3) Soma cumulativa (exemplo clássico)
# 1+2+3+...+100
total <- 0
for (i in 1:100) {
total <- total + i
}
total
# [1] 5050
(4) ⚠️ O R apresenta baixo desempenho em loops
Os loops do R for são de 10 a 100 vezes mais lentos do que os do Python. O R incentiva o uso de operações vetorizadas em vez de loops:
# Slow (Loop)
system.time({
total <- 0
for (i in 1:1e6) {
total <- total + i
}
})
# User System Passing
# 0.40 0.00 0.40 ← 0.4 s
# Fast (Vectorization)
system.time({
total <- sum(1:1e6)
})
# User System Passing
# 0.01 0.00 0.01 <- 0.01 s (40x faster)
sum() mean() ifelse(), não escreva um loop.
6. Loop while: Loop condicional
(1) Sintaxe do while
while (Conditions) {
Execute repeatedly when the condition is true
}
(2) Exemplo clássico: o jogo “Adivinhe o número”
# Target Number
target <- 42
guess <- 0
attempts <- 0
while (guess != target) {
guess <- sample(1:100, 1) # Guess at Random
attempts <- attempts + 1
if (attempts > 1000) break # More than 1000 Second attempt
}
cat("Used", attempts, "Second guess\n")
(3) Diferenças em relação a for
| Recurso | para | enquanto |
|---|---|---|
| Finalidade | Ciclos com um número conhecido de iterações | Número desconhecido de iterações, acionadas por condições |
| Encerramento | Fim da percorrida do vetor | Encerramento devido a condição falsa |
| Aplicável | Percorrer os dados | Aguardar eventos, sondagem |
7. repeat e break: loops infinitos
(1) repeat Sintaxe
repeat {
Code
if (Conditions) break # Must have break,Otherwise, an infinite loop
}
(2) Prática: Seleção de menu
choice <- 0
repeat {
cat("\n=== Main Menu ===\n")
cat("1. Check the weather\n")
cat("2. Look up stocks\n")
cat("0. Exit\n")
choice <- as.integer(readline("Please select:"))
if (choice == 0) {
cat("Goodbye!\n")
break
} else if (choice == 1) {
cat("It's sunny today,25°C\n")
} else if (choice == 2) {
cat("Shanghai Stock Exchange 3000 pt\n")
} else {
cat("Invalid input\n")
}
}
repeat deve ser usado em conjunto com break; caso contrário, ocorrerá um loop infinito (o programa travará).
8. next e break: Controle de loop
| Palavra-chave | Função | Cenário |
|---|---|---|
next |
Pular esta rodada e passar para a próxima | Pular determinados itens |
break |
Sair de todo o loop | Sair imediatamente ao encontrar o alvo |
# next:Skip even numbers
for (i in 1:10) {
if (i %% 2 == 0) next
cat(i, " ")
}
# Output:1 3 5 7 9
cat("\n")
# break:Find the first one 7 Just log out
for (i in 1:10) {
if (i == 7) break
cat(i, " ")
}
# Output:1 2 3 4 5 6
9. Armadilhas comuns
(1) Armadilhas das comparações com números de ponto flutuante
# Seemingly equal,The actual values are not equal
0.1 + 0.2 == 0.3
# [1] FALSE ← Actually, it is 0.30000000000000004
# The Correct Way to Do It:Comparison of Tolerances
abs(0.1 + 0.2 - 0.3) < 1e-9
# [1] TRUE
(2) A instrução else deve estar em uma nova linha ou na mesma linha
# ❌ Error:else Traveling Alone
if (TRUE) {
cat("yes")
}
else {
cat("no")
}
# Error: unexpected 'else' in "else"
# Correct: else must follow if block }
if (TRUE) {
cat("yes")
} else {
cat("no")
}
# Output:yes
} else { na mesma linha para evitar ambiguidades na análise.
(3) se não for impresso automaticamente
# In R, if has no "Automatic Printing" (Not like a function call)
if (TRUE) "yes"
# No output ← Do not print
# Resolve: Use cat() or print() for explicit output
if (TRUE) cat("yes\n")
# Output:yes
10. Exemplo completo: Gestão de níveis de clientes
A seguir, apresentamos um exemplo de um fluxo de trabalho completo que integra todos os fluxos de controle abordados nesta lição.
▶ Exemplo: Segmentação de clientes e estratégias de marketing
# ============================================
# Customer Segmentation and Marketing Strategies
# Features:By age+Classify Customers by Spending Amount
# ============================================
# 1. Preparation 6 Customer Data
customers <- data.frame(
name = c("Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"),
age = c(15, 22, 35, 50, 65, 28),
spend = c(100, 500, 2000, 5000, 10000, 800)
)
# 2. Use ifelse() Batch Grading (Vectorization)
customers$tier <- ifelse(customers$spend < 500, "Regular",
ifelse(customers$spend < 3000, "Silver Card",
ifelse(customers$spend < 8000, "Gold Card", "Diamond")))
# 3. Go through the customer list,Output Marketing Strategy(for Loop)
cat("=== Customer Segmentation and Marketing Strategies ===\n\n")
for (i in 1:nrow(customers)) {
name <- customers$name[i]
age <- customers$age[i]
spend <- customers$spend[i]
tier <- customers$tier[i]
# Skip Diamond Members(Optimized)
if (tier == "Diamond") {
cat(name, "(", tier, "):", spend, "USD,Existing Customers,Priority Maintenance\n")
next
}
# Exit Conditions(Demo break)
if (spend > 5000) {
cat(name, ": High-spending customers! Enter VIP Process\n")
}
# Age-Based Marketing Recommendations
if (age < 18) {
cat(name, "(", tier, "):Minor,Recommended Parent Card\n")
} else if (age < 30) {
cat(name, "(", tier, "):Youth,New Product Releases\n")
} else if (age < 50) {
cat(name, "(", tier, "):Middle Age,Promote Family Plans\n")
} else {
cat(name, "(", tier, "):Middle-Aged and Older Adults,Promote Health Products\n")
}
}
Resultado esperado (trecho):
=== Customer Segmentation and Marketing Strategies ===
Alice( Regular ):Minor,Recommended Parent Card
Bob( Regular ):Youth,New Product Releases
Charlie( Silver Card ):Middle Age,Promote Family Plans
Diana( Gold Card ):Middle Age,Promote Family Plans
Eve( Diamond ):10000 USD,Existing Customers,Priority Maintenance
Frank( Silver Card ):Youth,New Product Releases
❓ Perguntas Frequentes
P: Quais são as principais diferenças entre o if/else do R e o do Python? R: No R, os blocos de código são delimitados por
{}(enquanto o Python usa recuo); O if/else do R é uma expressão (que pode ser atribuída a uma variável), enquanto o do Python é uma instrução; oelsedo R deve estar na mesma linha que o}.
P: Como faço para escolher entre
ifeifelse? R: Useifpara avaliar um único valor; useifelse()para avaliar um vetor inteiro. Uma instruçãoifcomum gerará um erro se a condição envolver um comprimento maior que 1.
P: O que devo fazer se um loop for estiver muito lento? R: O R incentiva a “vectorização em primeiro lugar” — se você puder resolver o problema usando
sum()mean()ifelse(), não escreva um loop for. Os loops do R são de 10 a 100 vezes mais lentos que os do Python; portanto, use-os com cautela ao trabalhar com mais de 100.000 elementos.
P: Quando se deve usar
whileem vez defor? R: Usewhilequando o número de iterações for desconhecido (por exemplo, ao aguardar um evento ou em um jogo de adivinhação de números) e useforquando o número de iterações for conhecido (por exemplo, ao iterar sobre um vetor). Userepeat+breakpara “loops infinitos com interrupção antecipada”.
P: Qual é a diferença entre
nextebreak? R:nextpula a iteração atual e passa para a próxima (no R,continueé chamado denext);breaksai do loop inteiro.nexté usado para filtragem, enquantobreaké usado para sair antecipadamente.
📖 Resumo
- ramificação condicional if/else/else if: No R, coloque o bloco de código entre
{}(sem recuo) ifelse()é uma instrução condicional vetorizada capaz de avaliar um vetor inteiro; uma instruçãoifcomum só pode avaliar um único valor.- Um loop
foré executado um número conhecido de vezes; um loopwhileé executado um número desconhecido de vezes; um looprepeaté um loop infinito e deve ser usado com uma instruçãobreak. - next: Pular esta rodada; break: Sair do loop inteiro
- O R incentiva a vectorização em primeiro lugar — os loops
forsão de 10 a 100 vezes mais lentos do que no Python; para big data, usesum()eifelse()em vez disso. - Use a tolerância para comparações de ponto flutuante (
abs(x - y) < 1e-9); não use==diretamente. elseDeve ser usado em conjunto com}(para evitar ambiguidade na análise sintática)
📝 Exercícios
-
Problema básico: Escreva um script em R usando
if/else if/elsepara implementar o seguinte: Dada uma pontuaçãoscore, exiba a classificação (90+: Excelente, 80+: Bom, 60+: Aprovado; caso contrário: Reprovado). Teste o script com quatro notas: 95, 75, 60 e 40, e salve uma captura de tela do resultado. -
Problema básico: Use
ifelse()para dividir o vetorc(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)em elementos ímpares e pares e exiba o resultado. -
Problema básico: Use
forpara calcular 5! (fatorial de 5 = 5 × 4 × 3 × 2 × 1) em um loop e salve capturas de tela do processo e do resultado. -
Exercício avançado: Escreva um jogo do tipo “Adivinhe o número”: ① Use
sample(1:100, 1)para gerar um número aleatório entre 1 e 100 como meta; ② Usewhilepara percorrer as entradas do usuário (readline); ③ Exiba a dica “Muito alto” ou “Muito baixo”; ④ Quando o número for adivinhado corretamente, exiba “Parabéns! Foram necessárias N tentativas.” Execute e teste o programa. -
Desafio: Escreva um script que processe números inteiros de 1 a 100 da seguinte forma: ① Pule os múltiplos de 3 (
next); ② Saia quando chegar a 50 (break); ③ Some os números restantes. Verifique o resultado (deve ser 1+2+4+5+7+8+...+49 = ?). Salve uma captura de tela do seu código e da saída.