Menu

Funções no R: Definição, Argumentos e Valores de Retorno

Como criar uma função no R - a sintaxe function(x) { }, valores de retorno, argumentos padrão e nomeados, os três pontos ..., funções anônimas e como funciona o escopo.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

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.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR