R: Funções do R
Última atualização: 2026-08-26
Nas últimas 6 aulas, temos usado as funções embutidas do R (
sum()mean()c()). Mas o que realmente torna o R poderoso é a possibilidade de escrever suas próprias funções. Nesta aula, aprenderemos sobre as “funções personalizadas” do R — transformando código repetitivo em ferramentas reutilizáveis.
O R é uma linguagem de programação funcional, na qual as funções são “cidadãos de primeira classe”. Isso significa que as funções podem ser atribuídas a variáveis, passadas como argumentos e retornadas como valores. Nesta aula, exploraremos todos os recursos das funções do R.
1. O que você vai aprender
- function(){} Sintaxe básica
- 4 tipos de parâmetros (parâmetros posicionais, nomeados, padrão e variáveis...)
- 3 tipos de valores de retorno (retorno / última linha / invisível)
- Funções anônimas (lambda)
- Funções como objetos (atribuição, passagem como argumentos, retorno)
- chamadas em lote com do.call()
- Prática: Escreva uma função utilidade completa
2. Uma história sobre a reutilização de código
(1) Problema: Código duplicado
Chen é um analista de dados que precisa “converter dados de vendas em relatórios” 10 vezes por dia. A cada vez, ele escreve a mesma coisa repetidamente:
# Repeat 10 The code for this
sales <- c(120, 150, 80, 200, 175)
total <- sum(sales)
avg <- mean(sales)
top <- max(sales)
cat("Total Sales:", total, "Average:", avg, "Highest:", top, "\n")
10 operações de copiar e colar = 200 linhas de código duplicado. Se você precisar alterar a lógica em um lugar, terá que alterá-la em 10 lugares — mais cedo ou mais tarde, você vai deixar passar alguma coisa.
(2) Resolução de funções
# Write a function (just write 1 time)
report <- function(x) {
cat("Total Sales:", sum(x), " Average:", mean(x), " Highest:", max(x), "\n")
}
# Call 10 times (Every time 1 row)
report(c(120, 150, 80, 200, 175))
report(c(80, 90, 100))
report(c(1000, 2000, 3000))
5 linhas de código de função + 10 linhas de chamadas = 15 linhas de código. Para alterar a lógica, basta uma única modificação. Esse é o poder das funções.
3. function(){}: Sintaxe básica
(1) Definição da função
# The Simplest Function
greet <- function() {
cat("Hello, World!\n")
}
# Call
greet()
# Output:Hello, World!
(2) Funções com parâmetros
# Single parameter
greet <- function(name) {
cat("Hello,", name, "!\n")
}
greet("Alice")
# Output:Hello, Alice !
# Multiple parameters
greet_full <- function(name, age) {
cat("I am", name, ",This year", age, "yrs\n")
}
greet_full("Bob", 25)
# Output:I am Bob ,This year 25 yrs
(3) Diferenças entre funções em R e Python
| Recurso | R | Python |
|---|---|---|
| definição | function(x) { ... } |
def func(x): |
| Bloco de código | {} |
Recuo |
| Valor de retorno | A última linha é retornada automaticamente | Requer return |
| Documentação | Começa com #' (roxygen2) |
docstring |
| Declaração de tipo | Nenhuma (tipagem dinâmica) | Opcional (Python 3.5+) |
# R the special:The last line wraps automatically(Not necessary return)
add <- function(a, b) {
a + b # The last line wraps automatically
}
result <- add(3, 4)
result
# [1] 7
4. 4 Tipos de parâmetros
(1) Parâmetros de posição x parâmetros nomeados
# Function Definition:3 parameter
power <- function(base, exp, mod) {
result <- (base ^ exp) %% mod
return(result)
}
# Location Parameters(In order)
power(2, 10, 1000)
# [1] 24 ← 2^10=1024, 1024 %% 1000 = 24
# Named parameters(By Name,Out of order)
power(mod = 1000, base = 2, exp = 10)
# [1] 24 ← The same result
(2) Parâmetros padrão
# The second parameter has a default value.
power <- function(base, exp = 2, mod = 1000) {
result <- (base ^ exp) %% mod
return(result)
}
# Do not pass a second parameter,Use the default exp = 2
power(10)
# [1] 100 ← 10^2=100, 100 %% 1000 = 100
# Partial Parameter Passing
power(10, mod = 100)
# [1] 0 ← 10^2=100, 100 %% 100 = 0
(3) Regras para a ordem dos parâmetros
Regras de correspondência de parâmetros do R:
graph TB
A[Function Call power 10 exp=3] --> B[1. Exact Match for Named Parameters]
B --> C[2. Prefix Matching]
C --> D[3. Location Matching]
style A fill:#fff3cd
style B fill:#d4edda
style C fill:#d4edda
style D fill:#d4edda
- Correspondência exata:
exp = 3(a mais específica) - Correspondência de prefixos:
e = 3→exp(menos teclas digitadas) - Correspondência de posições: Primeiro parâmetro sem nome →
base(menos seguro)
exp = 3). Digitar um pouco mais não economiza muito tempo, mas ajuda a evitar ambiguidades.
(4) Parâmetros variáveis ...
... significa “qualquer número de argumentos” e é comumente usado em funções wrapper:
# Use ... to accept any parameters
my_sum <- function(...) {
args <- list(...)
result <- sum(unlist(args))
cat("Summed up", length(args), "parameter:", result, "\n")
return(result)
}
my_sum(1, 2, 3)
# Summed up 3 parameter: 6
my_sum(10, 20, 30, 40, 50)
# Summed up 5 parameter: 150
... é muito usado ao encapsular outras funções (como quando um my_mean() personalizado encapsula alguns parâmetros de mean()).
5. 3 Tipos de valores de retorno
(1) A última linha quebra automaticamente
A última expressão em uma função R retorna automaticamente:
add <- function(a, b) {
a + b # Last line,Auto-Return
}
add(3, 4)
# [1] 7
(2) Explícito return()
# Use return() to return early
check_age <- function(age) {
if (age < 0) {
return("Age of Invalidity") # Return Early
}
if (age >= 18) {
return("Adulthood")
}
"Minor" # Implicit Return
}
check_age(-5) # [1] "Age of Invalidity"
check_age(20) # [1] "Adulthood"
check_age(15) # [1] "Minor"
(3) invisible(): Oculta o valor de retorno
invisible() Impedir que uma função imprima automaticamente seu valor de retorno (mas ainda permita que ele seja atribuído):
# Ordinary Functions
add_print <- function(a, b) {
a + b # It will print automatically
}
add_print(3, 4)
# [1] 7 ← Automatic Printing
# invisible Function
add_silent <- function(a, b) {
invisible(a + b) # Do not print automatically
}
add_silent(3, 4)
# No output ← Do not print
# But it can still be assigned a value
result <- add_silent(3, 4)
result
# [1] 7 ← You can see it after the assignment.
<- Atribuir um valor usando invisible() — x <- 5 não exibe o resultado.
6. Funções anônimas: expressões lambda
O R suporta funções anônimas (funções sem nome):
# Ordinary Functions
square <- function(x) x ^ 2
square(5)
# [1] 25
# Anonymous Functions(Use directly)
(function(x) x ^ 2)(5)
# [1] 25
# Common Use Cases for Anonymous Functions:lapply/sapply
numbers <- list(1, 2, 3, 4, 5)
result <- lapply(numbers, function(x) x ^ 2)
result
# [[1]] 1
# [[2]] 4
# [[3]] 9
# [[4]] 16
# [[5]] 25
apply — abordaremos esse assunto em profundidade na Lição 8.
7. Funções como objetos (O cerne da programação funcional em R)
As funções no R são de “primeira classe”, o que significa que elas podem:
(1) Atribuição de um valor a uma variável
f <- function(x) x * 2
g <- f # A function has two names
f(5) # [1] 10
g(5) # [1] 10 ← Equivalent
(2) Passado como parâmetro
# Functions that take other functions as arguments
apply_twice <- function(f, x) {
f(f(x))
}
# Passing Different Functions
apply_twice(function(x) x + 1, 5) # 5+1+1=7
apply_twice(function(x) x * 2, 5) # 5*2*2=20
(3) Como valor de retorno
# A function that returns a function(Closure)
make_multiplier <- function(k) {
function(x) x * k
}
# Creating Functions with Different Scales
double <- make_multiplier(2)
triple <- make_multiplier(3)
double(5) # [1] 10
triple(5) # [1] 15
map() reduce()) fazem uso disso.
8. do.call(): Chamada dinâmica
do.call() Expandir uma lista/vetor em argumentos de função:
# Regular Call
sum(1, 2, 3, 4, 5)
# [1] 15
# do.call Call(The parameter is a list)
args <- list(1, 2, 3, 4, 5)
do.call(sum, args)
# [1] 15
# Practical Application:Dynamic Creation data.frame
col_names <- c("name", "age", "score")
col1 <- c("Alice", "Bob", "Charlie")
col2 <- c(25, 30, 35)
col3 <- c(95, 88, 92)
df <- do.call(data.frame, list(
name = col1,
age = col2,
score = col3
))
print(df)
# name age score
# 1 Alice 25 95
# 2 Bob 30 88
# 3 Charlie 35 92
9. Âmbito: Onde as variáveis são válidas?
O R utiliza escopo léxico:
# Global Variables
x <- 10
# Global variables can be accessed within a function.
read_x <- function() {
cat("x =", x, "\n") # Read the whole picture x
}
read_x()
# x = 10
# However, local variables within a function do not affect the global scope.
set_local <- function() {
x <- 999 # Local variables
cat("Inside a function x =", x, "\n")
}
set_local()
# Inside a function x = 999
cat("Global x =", x, "\n")
# Global x = 10 <- Global x unchanged
global). Para modificá-las, use <<- (mas isso não é recomendado).
10. Exemplo completo: Funções da ferramenta de relatório de vendas
A seguir, apresentamos um exemplo de um fluxo de trabalho completo que reúne todos os recursos das funções abordados nesta aula.
▶ Exemplo: Funções da ferramenta de relatório de vendas
# ============================================
# Sales Report Tool Functions
# Features:Encapsulate Common Analytical Logic,Reuse
# ============================================
# 1. Basic Statistical Functions(Back to List)
basic_stats <- function(x) {
list(
n = length(x),
sum = sum(x),
mean = round(mean(x), 2),
median = median(x),
sd = round(sd(x), 2),
min = min(x),
max = max(x)
)
}
# 2. Formatted Output Functions(invisible Back)
print_report <- function(name, x) {
stats <- basic_stats(x)
cat("=================================\n")
cat("Sales Report:", name, "\n")
cat("=================================\n")
cat("Sample size:", stats$n, "\n")
cat("Total Sales:", stats$sum, "\n")
cat("Average Sales:", stats$mean, "\n")
cat("Median:", stats$median, "\n")
cat("Standard Deviation:", stats$sd, "\n")
cat("Minimum:", stats$min, " / Maximum:", stats$max, "\n")
invisible(stats) # Silent Return
}
# 3. Classification Function(Vectorization)
classify_sales <- function(x) {
ifelse(x < 100, "Low",
ifelse(x < 200, "Mid", "High"))
}
# 4. Main Program
sales_data <- list(
"Beijing" = c(120, 150, 80, 200, 175),
"Shanghai" = c(95, 110, 130, 145, 160),
"Shenzhen" = c(200, 220, 180, 250, 300)
)
# Generate reports for each branch
for (city in names(sales_data)) {
sales <- sales_data[[city]]
print_report(city, sales)
# Batch Classification Using Anonymous Functions
levels <- sapply(sales, function(x) classify_sales(x))
cat("\nCategory Summary:\n")
print(table(levels))
cat("\n")
}
# 5. Use do.call to merge all branches
all_sales <- do.call(c, sales_data)
cat("=== Company-wide Summary ===\n")
print_report("Company-wide", all_sales)
Resultado esperado (trecho):
=================================
Sales Report: Beijing
=================================
Sample size: 5
Total Sales: 725
Average Sales: 145
Median: 150
Standard Deviation: 47.7
Minimum: 80 / Maximum: 200
Category Summary:
levels
Mid High
3 2
=================================
Sales Report: Shanghai
=================================
...
❓ Perguntas Frequentes
P: As funções do R precisam usar
return()? R: Não. A última expressão em uma função do R é retornada automaticamente; portanto, você pode usá-la sem escreverreturn(). No entanto, usarreturn()proporciona maior clareza, especialmente ao retornar antecipadamente a partir de uma condiçãoif.
P: Onde os parâmetros padrão devem ser colocados? R: Os parâmetros padrão devem ser colocados após os parâmetros não padrão.
function(a = 1, b)Isso é válido (primeiro os parâmetros padrão, depois os não padrão), mas todos os parâmetros nomeados devem ser utilizados ao chamar a função.
P: Como se usa
...? R:...significa “aceita qualquer número de parâmetros” e costuma ser usada para envolver outras funções. Por exemplo,my_mean <- function(x, ...) mean(x, na.rm = TRUE, ...)envolve os parâmetros adicionais demean().
P: Uma função pode modificar variáveis globais? R: Por padrão, não. É possível usar
<<-para fazer isso (não recomendado), mas isso contaminará o ambiente global. A boa prática é que as funções retornem apenas um valor e não modifiquem o estado externo.
P: Quando se deve usar funções anônimas? R: Elas são mais comumente usadas em funções como
lapply(),sapply(),map(), etc.—lapply(x, function(i) i^2). É mais conciso do que definir uma função primeiro e depois chamá-la.
📖 Resumo
- Definição da função R
function(params) { code }, a última linha é retornada automaticamente - 4 tipos de parâmetros: posicional, nomeado (
name = value), padrão (name = default) e variável (...) - 3 valores de retorno: última linha (automático),
return()(explícito),invisible()(silencioso, sem saída) - As funções anônimas
function(x) x^2são extremamente comuns emlapplyesapply - R é uma linguagem funcional, e as funções são “cidadãos de primeira classe”: podem ser atribuídas, passadas como argumentos e retornadas (closures).
do.call(func, list)Expandir a lista em argumentos de função- O R utiliza escopo lexical; por padrão, as variáveis globais não podem ser modificadas dentro de funções (usando
<<-, embora isso não seja recomendado)
📝 Exercícios
-
Problema básico: Escreva uma função
celsius_to_fahrenheit(c)que converta graus Celsius em graus Fahrenheit (fórmula: F = C × 9/5 + 32). Teste com os valores de entrada 0, 25 e 100 e verifique se os resultados são 32, 77 e 212. -
Problema básico: Escreva uma função
circle_area(r)que calcule a área de um círculo (pi * r^2), arredondando para 2 casas decimais. Teste com r = 1, 2, 5. -
Problema básico: Escreva uma função
greet(name = "World", greeting = "Hello")com parâmetros padrão que exiba “Hello, World!” ou “Hi, Alice!”, e teste três maneiras diferentes de chamá-la. -
Problema Avançado: Escreva uma função
analyze_scores(scores)que receba um vetor de números e retorne uma lista contendomeanmedianmaxminpass_ratetaxas de aprovação, utilizandoinvisible()para impedir a impressão automática. Após chamar a função, useresult$pass_ratepara acessar as taxas de aprovação. -
Desafio: Escreva uma função que retorne uma função
make_power(n)que retornefunction(x) x^n. Usemake_power(2)para criarsquare, usemake_power(3)para criarcubee testesquare(5) = 25ecube(3) = 27. Salve uma captura de tela.