Retornando Funções
Parte da seção Lógica e Fluxo do Journey de R da Coddy. Lição 29 de 64.
Uma função também pode retornar uma função. make_multiplier(3) retorna uma nova função que multiplica seu argumento por 3:
make_multiplier <- function(n) {
function(x) x * n
}
triple <- make_multiplier(3)
print(triple(5))
print(make_multiplier(10)(5))Saída:
[1] 15
[1] 50A função retornada se lembra dos valores com os quais foi criada. Essa combinação de uma função e das variáveis ao redor dela é chamada de closure. Cada chamada da criadora constrói uma closure separada:
make_greeter <- function(greeting) {
function(name) paste0(greeting, ", ", name, "!")
}
hello <- make_greeter("Hello")
hola <- make_greeter("Hola")
print(hello("Ada"))
print(hola("Ada"))Saída:
[1] "Hello, Ada!"
[1] "Hola, Ada!"Uma função criadora transforma algumas configurações em uma ferramenta pronta, por exemplo, um conversor entre unidades:
make_converter <- function(factor, offset = 0) {
function(x) x * factor + offset
}
c_to_f <- make_converter(1.8, 32)
km_to_miles <- make_converter(0.621)
print(c_to_f(100))
print(km_to_miles(10))Saída:
[1] 212
[1] 6.21Funções podem ser combinadas em novas funções. compose(f, g) retorna uma função que executa f e depois g:
compose <- function(f, g) function(x) g(f(x))
clean <- compose(trimws, toupper)
print(clean(" hi there "))Saída:
[1] "HI THERE"Desafio
FácilComplete make_formatter(prefix, digits). Ela retorna uma função que recebe um número e retorna prefix seguido pelo número com digits casas decimais: make_formatter("$", 2)(3.5) retorna $3.50.
sprintf("%.*f", digits, x) formata x com digits casas decimais.
O código fornecido lê o prefixo, o número de casas decimais e uma lista de números separados por vírgulas. Ele cria um formatador e imprime o resultado para cada número.
Experimente você mesmo
make_formatter <- function(prefix, digits) {
# Escreva seu código aqui
function(x) ""
}
# Código de entrada/saída fornecido: mantenha-o como está
input <- suppressWarnings(readLines(file("stdin")))
fmt <- make_formatter(input[1], as.integer(input[2]))
for (x in as.numeric(strsplit(input[3], ",")[[1]])) cat(fmt(x), "\n", sep = "")
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Lógica e Fluxo
1Strings em Profundidade
Substrings com substr()Formatação com sprintf()Dividindo e UnindoPesquisando StringsSubstituindo TextoRecapitulação - Criador de Nome de Usuário4Matrizes
Criando MatrizesIndexando MatrizesResumos de Linhas e ColunasAritmética de MatrizesRecapitulação - Tabela de Assentos10Fluxo de Controle Avançado
A Função switch()ifelse() Vetorizadorepeat e breakFunções RecursivasRevisão — Classificador de Notas2Consultas de Chave-Valor
Consultas em Vetores NomeadosVerificando ChavesAdicionando e Removendo ChavesPercorrendo NomesRecapitulação - Mesa de Ações5Projeto - Boletim de Notas
Adicionando AlunosRegistrando Notas3Conjuntos e Contagem
Valores ÚnicosOperações com ConjuntosTestes de PertinênciaContagem com table()Recapitulação - Convidados do Evento6Funções como Valores
Funções AnônimasPassando FunçõesRetornando FunçõesClosures com EstadoRecapitulação - Regras de Desconto9Data Frames
Criando Data FramesColunas e LinhasFiltrando LinhasAdicionando e OrdenandoRecapitulação - Relatório de Vendas12Projeto - Rastreador de Despesas
Registro de DespesasGastos TotaisPratique por conta própria: Compilador de R online