Definindo e Chamando uma Função
Uma função no R é um valor, como um número ou uma string. Você constrói uma com a palavra-chave function e a prende a um nome com <-, do mesmo jeito que guardaria qualquer outra coisa em uma variável:
As partes: function(x) declara um parâmetro chamado x, as chaves contêm o corpo, e chamar square(4) roda o corpo com x valendo 4. Para um corpo de uma linha as chaves são opcionais - square <- function(x) x^2 é a mesma função - mas as chaves ficam mais legíveis quando o corpo cresce.
Como uma função é apenas um valor, tudo o que você sabe sobre variáveis se aplica: você pode reatribuí-la, passá-la para outra função ou guardá-la em uma lista. Esse único fato sustenta metade do R idiomático, incluindo toda a família apply.
Valores de Retorno: A Última Expressão Vence
Uma função em R retorna o que sua última expressão avaliada produzir. Não existe instrução return obrigatória:
return() existe, sim, e funciona como você esperaria - ele interrompe a função imediatamente e devolve seu argumento. O R idiomático o guarda para saídas antecipadas: abandonar a função logo no começo quando uma entrada torna o resto do trabalho inútil. Combine-o com verificações if-else:
Escrever return(a / b) na última linha não seria errado, apenas ruído. Reserve return() para as saídas que acontecem cedo, e deixe a última expressão falar pelo caminho normal.
Valores Padrão e Argumentos Nomeados
Um parâmetro pode carregar um valor padrão, declarado com = na lista de parâmetros. Quem chama e está satisfeito com o padrão simplesmente omite o argumento:
A terceira chamada mostra a outra metade da história: argumentos nomeados. Quando você escreve name = "Ada" no local da chamada, a posição deixa de importar - o R faz a correspondência primeiro por nome e depois preenche os parâmetros restantes por posição. Duas regras práticas saem disso:
- Coloque os parâmetros obrigatórios primeiro e os com padrão depois, para que chamadas posicionais continuem naturais.
- No local da chamada, nomeie qualquer argumento que não seja óbvio pela posição.
greet("Ada", punctuation = "?")é mais claro do que fazer quem lê contar vírgulas.
Repassando Argumentos com ...
O parâmetro especial ... (pronunciado "dots", ou pontos) significa "qualquer número de argumentos extras". Uma função que declara ... pode aceitar argumentos que nunca listou e encaminhá-los para outra função:
shout() não sabe nem se importa com quantas palavras você passa - ela entrega todas a paste(). Repare que punctuation vem depois dos pontos: qualquer parâmetro declarado depois de ... só pode ser definido por nome, que é exatamente o que você quer para opções. Esse padrão de repasse está em toda parte no R base - sapply(x, round, digits = 2) funciona porque sapply encaminha digits = 2 para round via seu próprio ....
O custo dos pontos é que erros de digitação passam despercebidos: escreva punctation em vez de punctuation e ele simplesmente é engolido pelo ... em vez de gerar um erro. Mantenha pequenas as funções que usam pontos.
Funções Anônimas
Quando uma função é necessária apenas uma vez - normalmente como argumento de outra função - você pode pular o nome por completo:
As duas linhas fazem a mesma coisa. function(x) x^2 é a grafia clássica; \(x) x^2 é o atalho adicionado no R 4.1, em que \ faz as vezes da palavra function. Elas são idênticas em tudo, exceto no número de teclas - o atalho não é um tipo diferente de função.
Use uma função anônima quando a operação é uma linha só amarrada a um único local de chamada. No momento em que você colar o mesmo lambda em dois lugares, ou ele crescer para mais de uma linha, dê um nome a ele - uma função nomeada é testável e se documenta sozinha.
Escopo: O Que uma Função Enxerga
O R usa escopo léxico: quando uma função precisa de uma variável que não encontra entre seus próprios parâmetros e atribuições locais, ela procura no ambiente onde a função foi definida - não onde foi chamada. Na prática isso significa que uma função pode ler variáveis do script ao redor dela:
O outro lado da moeda: uma atribuição dentro de uma função nunca vaza para fora. rate <- 0.5 dentro de change_inside cria uma variável local nova que morre quando a função retorna; o rate externo ainda imprime 0.1. Isso é um recurso - funções não podem pisotear seu workspace por acidente - mas surpreende iniciantes que esperam que a atribuição interna permaneça. Se uma função precisa entregar um resultado ao mundo externo, retorne-o e atribua no local da chamada. (Existe um operador <<- que alcança o exterior; trate-o como um cheiro de código até você realmente precisar dele.)
Um Exemplo Trabalhado
Aqui está o padrão que compensa: você se pega repetindo três linhas de análise, envolve-as em uma função e a reutiliza. Digamos que você viva resumindo vetores de medições:
Tudo desta página está aí: um parâmetro digits com padrão, uma chamada nomeada sobrescrevendo-o e uma última expressão (round(out, digits)) fazendo o retorno. A função se lê como uma frase, funciona em qualquer vetor numérico e mora em um único lugar quando você decidir acrescentar uma mediana.
O Que Você Leva Daqui
nome <- function(args) { corpo }cria uma função; a última expressão avaliada é seu valor de retorno.return()é para saídas antecipadas, não para a linha final normal.- Padrões são declarados com
=na lista de parâmetros; argumentos nomeados tornam as chamadas independentes de ordem e legíveis. ...aceita e encaminha quaisquer argumentos extras - poderoso, mas esconde erros de digitação.function(x)e\(x)são a mesma coisa; use funções anônimas para linhas únicas de uso pontual.- Funções leem variáveis de onde foram definidas; atribuições dentro delas ficam dentro.
A seguir: a família apply - as funções que pegam as suas funções e as rodam sobre vetores e listas inteiros.
Perguntas frequentes
Como criar uma função no R?
Atribua um objeto function a um nome: square <- function(x) { x^2 }. Os parâmetros vão entre parênteses, o corpo vai entre chaves, e você a chama como square(4). A última expressão avaliada é o que a função retorna.
É preciso usar return() no R?
Não. Uma função em R retorna automaticamente o valor da última expressão que avalia. return() existe, e o R idiomático o reserva para saídas antecipadas - abandonar a função logo no início quando uma entrada é inválida ou um caso extremo já foi tratado.
O que é uma função anônima no R?
Uma função que você define sem dar nome, normalmente passada direto para outra função: sapply(x, function(v) v^2). Desde o R 4.1 também existe o atalho \(v) v^2, que significa exatamente a mesma coisa com menos teclas.