Funções na programação R (com exemplo)

Índice:

Anonim

O que é uma função em R?

Uma função , em um ambiente de programação, é um conjunto de instruções. Um programador cria uma função para evitar a repetição da mesma tarefa ou reduzir a complexidade.

Uma função deve ser

  • escrito para realizar tarefas específicas
  • pode ou não incluir argumentos
  • conter um corpo
  • pode ou não retornar um ou mais valores.

Uma abordagem geral para uma função é usar a parte do argumento como entradas , alimentar a parte do corpo e, finalmente, retornar uma saída . A sintaxe de uma função é a seguinte:

function (arglist) {#Function body}

Neste tutorial, aprenderemos

  • R funções integradas importantes
  • Funções gerais
  • Funções matemáticas
  • Funções estatísticas
  • Função de escrita em R
  • Quando devemos escrever a função?
  • Funções com condição

R funções integradas importantes

Existem várias funções embutidas em R. R combina seus parâmetros de entrada com seus argumentos de função, por valor ou por posição, e então executa o corpo da função. Os argumentos da função podem ter valores padrão: se você não especificar esses argumentos, R assumirá o valor padrão.

Nota : É possível ver o código-fonte de uma função executando o nome da própria função no console.

Veremos três grupos de funções em ação

  • Função geral
  • Função matemática
  • Função estatística

Funções gerais

Já estamos familiarizados com funções gerais como funções cbind (), rbind (), range (), sort (), order (). Cada uma dessas funções tem uma tarefa específica, leva argumentos para retornar uma saída. A seguir estão funções importantes que devemos saber -

função diff ()

Se você trabalha com séries temporais , precisa estacionar a série tomando seus valores de atraso . Um processo estacionário permite média, variância e autocorrelação constantes ao longo do tempo. Isso melhora principalmente a previsão de uma série temporal. Isso pode ser feito facilmente com a função diff (). Podemos construir dados de série temporal aleatórios com uma tendência e então usar a função diff () para estacionar a série. A função diff () aceita um argumento, um vetor, e retorna a diferença defasada e iterada adequada.

Nota : Freqüentemente, precisamos criar dados aleatórios, mas para aprendizado e comparação, queremos que os números sejam idênticos nas máquinas. Para garantir que todos geremos os mesmos dados, usamos a função set.seed () com valores arbitrários de 123. A função set.seed () é gerada por meio do processo de gerador de números pseudo-aleatórios que faz com que todos os computadores modernos tenham a mesma sequência de números. Se não usarmos a função set.seed (), todos teremos diferentes sequências de números.

set.seed(123)## Create the datax = rnorm(1000)ts <- cumsum(x)## Stationary the seriediff_ts <- diff(ts)par(mfrow=c(1,2))## Plot the seriesplot(ts,)plot(diff(ts),)

função length ()

Em muitos casos, queremos saber o comprimento de um vetor para computação ou para ser usado em um loop for. A função length () conta o número de linhas no vetor x. Os códigos a seguir importam o conjunto de dados de carros e retornam o número de linhas.

Nota : length () retorna o número de elementos em um vetor. Se a função for passada para uma matriz ou quadro de dados, o número de colunas será retornado.

dt <- cars## number columnslength(dt)

Resultado:

## [1] 1
## number rowslength(dt[,1])

Resultado:

## [1] 50

Funções matemáticas

R tem uma série de funções matemáticas.

Operador Descrição
abs (x) Obtém o valor absoluto de x
log (x, base = y) Obtém o logaritmo de x com base y; se a base não for especificada, retorna o logaritmo natural
exp (x) Retorna o exponencial de x
sqrt (x) Retorna a raiz quadrada de x
fatorial (x) Retorna o fatorial de x (x!)
# sequence of number from 44 to 55 both including incremented by 1x_vector <- seq(45,55, by = 1)#logarithmlog(x_vector)

Resultado:

## [1] 3.806662 3.828641 3.850148 3.871201 3.891820 3.912023 3.931826## [8] 3.951244 3.970292 3.988984 4.007333
#exponentialexp(x_vector)
#squared rootsqrt(x_vector)

Resultado:

## [1] 6.708204 6.782330 6.855655 6.928203 7.000000 7.071068 7.141428## [8] 7.211103 7.280110 7.348469 7.416198
#factorialfactorial(x_vector)

Resultado:

## [1] 1.196222e+56 5.502622e+57 2.586232e+59 1.241392e+61 6.082819e+62## [6] 3.041409e+64 1.551119e+66 8.065818e+67 4.274883e+69 2.308437e+71## [11] 1.269640e+73

Funções estatísticas

A instalação padrão R contém uma ampla gama de funções estatísticas. Neste tutorial, veremos brevemente a função mais importante ...

Funções estatísticas básicas

Operador

Descrição

média (x)

Média de x

mediana (x)

Mediana de x

var (x)

Variância de x

sd (x)

Desvio padrão de x

escala (x)

Pontuações padrão (pontuações z) de x

quantil (x)

Os quartis de x

resumo (x)

Resumo de x: média, mínimo, máximo etc ...

speed <- dt$speedspeed# Mean speed of cars datasetmean(speed)

Resultado:

## [1] 15.4
# Median speed of cars datasetmedian(speed)

Resultado:

## [1] 15
# Variance speed of cars datasetvar(speed)

Resultado:

## [1] 27.95918
# Standard deviation speed of cars datasetsd(speed)

Resultado:

## [1] 5.287644
# Standardize vector speed of cars datasethead(scale(speed), 5)

Resultado:

## [,1]## [1,] -2.155969## [2,] -2.155969## [3,] -1.588609## [4,] -1.588609## [5,] -1.399489
# Quantile speed of cars datasetquantile(speed)

Resultado:

## 0% 25% 50% 75% 100%## 4 12 15 19 25
# Summary speed of cars datasetsummary(speed)

Resultado:

## Min. 1st Qu. Median Mean 3rd Qu. Max.## 4.0 12.0 15.0 15.4 19.0 25.0

Até este ponto, aprendemos muitas funções integradas do R.

Nota : Tenha cuidado com a classe do argumento, ou seja, numérico, booleano ou string. Por exemplo, se precisarmos passar um valor de string, precisamos colocar a string entre aspas: "ABC".

Função de escrita em R

Em alguma ocasião, precisamos escrever nossa própria função porque temos que realizar uma tarefa específica e não existe nenhuma função pronta. Uma função definida pelo usuário envolve um nome , argumentos e um corpo .

function.name <- function(arguments){computations on the argumentssome other code}

Observação : uma boa prática é nomear uma função definida pelo usuário diferente de uma função interna. Isso evita confusão.

Uma função de argumento

No próximo trecho, definimos uma função quadrada simples. A função aceita um valor e retorna o quadrado do valor.

square_function<- function(n){# compute the square of integer `n`n^2}# calling the function and passing value 4square_function(4)

Explicação do código:

  • A função é denominada função_quadrada; pode ser chamado do que quisermos.
  • Recebe um argumento "n". Não especificamos o tipo de variável para que o usuário possa passar um inteiro, um vetor ou uma matriz
  • A função pega a entrada "n" e retorna o quadrado da entrada.

    Quando você terminar de usar a função, podemos removê-la com a função rm ().

# depois de criar a função

rm(square_function)square_function

No console, podemos ver uma mensagem de erro: Erro: objeto 'função_quadrada' não encontrado informando que a função não existe.

Escopo do ambiente

Em R, o ambiente é uma coleção de objetos como funções, variáveis, quadro de dados, etc.

R abre um ambiente sempre que o Rstudio é solicitado.

O ambiente de nível superior disponível é o ambiente global , denominado R_GlobalEnv. E temos o ambiente local.

Podemos listar o conteúdo do ambiente atual.

ls(environment())

Resultado

## [1] "diff_ts" "dt" "speed" "square_function"## [5] "ts" "x" "x_vector"

Você pode ver todas as variáveis ​​e funções criadas no R_GlobalEnv.

A lista acima irá variar para você com base no código histórico que você executa no R Studio.

Observe que n, o argumento da função square_function não está neste ambiente global .

Um novo ambiente é criado para cada função. No exemplo acima, a função square_function () cria um novo ambiente dentro do ambiente global.

Para esclarecer a diferença entre o ambiente global e local , vamos estudar o seguinte exemplo

Essas funções recebem um valor x como um argumento e o adicionam a y para definir fora e dentro da função

A função f retorna a saída 15. Isso ocorre porque y é definido no ambiente global. Qualquer variável definida no ambiente global pode ser usada localmente. A variável y tem o valor 10 durante todas as chamadas de função e pode ser acessada a qualquer momento.

Vamos ver o que acontece se a variável y for definida dentro da função.

Precisamos eliminar `y` antes de executar este código usando rm r

A saída também é 15 quando chamamos f (5), mas retorna um erro quando tentamos imprimir o valor y. A variável y não está no ambiente global.

Finalmente, R usa a definição de variável mais recente para passar para dentro do corpo de uma função. Vamos considerar o seguinte exemplo:

R ignora os valores y definidos fora da função porque criamos explicitamente uma variável y dentro do corpo da função.

Função de múltiplos argumentos

Podemos escrever uma função com mais de um argumento. Considere a função chamada "times". É uma função simples que multiplica duas variáveis.

times <- function(x,y) {x*y}times(2,4)

Resultado:

## [1] 8

Quando devemos escrever a função?

O cientista de dados precisa fazer muitas tarefas repetitivas. Na maioria das vezes, copiamos e colamos trechos de código repetidamente. Por exemplo, a normalização de uma variável é altamente recomendada antes de executarmos um algoritmo de aprendizado de máquina. A fórmula para normalizar uma variável é:

Já sabemos como usar as funções min () e max () em R. Usamos a biblioteca tibble para criar o quadro de dados. Tibble é até agora a função mais conveniente para criar um conjunto de dados do zero.

library(tibble)# Create a data framedata_frame <- tibble(c1 = rnorm(50, 5, 1.5),c2 = rnorm(50, 5, 1.5),c3 = rnorm(50, 5, 1.5),)

Continuaremos em duas etapas para calcular a função descrita acima. No primeiro passo, vamos criar uma variável chamada c1_norm que é o reescalonamento de c1. Na etapa dois, apenas copiamos e colamos o código de c1_norm e alteramos com c2 e c3.

Detalhe da função com a coluna c1:

Nominador:: data_frame $ c1 -min (data_frame $ c1))

Denominador: max (data_frame $ c1) -min (data_frame $ c1))

Portanto, podemos dividi-los para obter o valor normalizado da coluna c1:

(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1)) 

Podemos criar c1_norm, c2_norm e c3_norm:

Create c1_norm: rescaling of c1data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))# show the first five valueshead(data_frame$c1_norm, 5)

Resultado:

## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991

Funciona. Podemos copiar e colar

data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))

em seguida, altere c1_norm para c2_norm e c1 para c2. Fazemos o mesmo para criar c3_norm

data_frame$c2_norm <- (data_frame$c2 - min(data_frame$c2))/(max(data_frame$c2)-min(data_frame$c2))data_frame$c3_norm <- (data_frame$c3 - min(data_frame$c3))/(max(data_frame$c3)-min(data_frame$c3))

Reescalonamos perfeitamente as variáveis ​​c1, c2 e c3.

No entanto, esse método está sujeito a erros. Podemos copiar e esquecer de alterar o nome da coluna após colar. Portanto, uma boa prática é escrever uma função sempre que precisar colar o mesmo código mais de duas vezes. Podemos reorganizar o código em uma fórmula e chamá-lo sempre que necessário. Para escrever nossa própria função, precisamos fornecer:

  • Nome: normalize.
  • o número de argumentos: Precisamos apenas de um argumento, que é a coluna que usamos em nosso cálculo.
  • O corpo: esta é simplesmente a fórmula que queremos devolver.

Seguiremos passo a passo para criar a função normalize.

Etapa 1) Criamos o nominador , que é. Em R, podemos armazenar o nominador em uma variável como esta:

nominator <- x-min(x)

Passo 2) Nós calcular o denominador: . Podemos replicar a ideia da etapa 1 e armazenar o cálculo em uma variável:

denominator <- max(x)-min(x)

Etapa 3) Fazemos a divisão entre o nominador e o denominador.

normalize <- nominator/denominator

Etapa 4) Para retornar o valor à função de chamada, precisamos passar normalizar dentro de return () para obter a saída da função.

return(normalize)

Etapa 5) Estamos prontos para usar a função envolvendo tudo dentro do colchete.

normalize <- function(x){# step 1: create the nominatornominator <- x-min(x)# step 2: create the denominatordenominator <- max(x)-min(x)# step 3: divide nominator by denominatornormalize <- nominator/denominator# return the valuereturn(normalize)}

Vamos testar nossa função com a variável c1:

normalize(data_frame$c1)

Funciona perfeitamente. Criamos nossa primeira função.

As funções são uma forma mais abrangente de realizar uma tarefa repetitiva. Podemos usar a fórmula de normalização em colunas diferentes, como a seguir:

data_frame$c1_norm_function <- normalize (data_frame$c1)data_frame$c2_norm_function <- normalize (data_frame$c2)data_frame$c3_norm_function <- normalize (data_frame$c3)

Mesmo que o exemplo seja simples, podemos inferir o poder de uma fórmula. O código acima é mais fácil de ler e, principalmente, evita cometer erros ao colar os códigos.

Funções com condição

Às vezes, precisamos incluir condições em uma função para permitir que o código retorne saídas diferentes.

Em tarefas de aprendizado de máquina, precisamos dividir o conjunto de dados entre um conjunto de trem e um conjunto de teste. O conjunto de trem permite que o algoritmo aprenda com os dados. Para testar o desempenho do nosso modelo, podemos usar o conjunto de testes para retornar a medida de desempenho. R não tem uma função para criar dois conjuntos de dados. Podemos escrever nossa própria função para fazer isso. Nossa função recebe dois argumentos e é chamada split_data (). A ideia por trás é simples, multiplicamos o comprimento do conjunto de dados (ou seja, o número de observações) por 0,8. Por exemplo, se quisermos dividir o conjunto de dados 80/20 e nosso conjunto de dados contiver 100 linhas, nossa função multiplicará 0,8 * 100 = 80. 80 linhas serão selecionadas para se tornarem nossos dados de treinamento.

Usaremos o conjunto de dados de qualidade do ar para testar nossa função definida pelo usuário. O conjunto de dados de qualidade aérea tem 153 linhas. Podemos ver isso com o código abaixo:

nrow(airquality)

Resultado:

## [1] 153 

Vamos proceder da seguinte forma:

split_data <- function(df, train = TRUE)Arguments:-df: Define the dataset-train: Specify if the function returns the train set or test set. By default, set to TRUE

Nossa função tem dois argumentos. O trem de argumentos é um parâmetro booleano. Se for definido como TRUE, nossa função cria o conjunto de dados de trem, caso contrário, cria o conjunto de dados de teste.

Podemos proceder como fizemos com a função normalize (). Escrevemos o código como se fosse um código único e, em seguida, envolvemos tudo com a condição no corpo para criar a função.

Passo 1:

Precisamos calcular o comprimento do conjunto de dados. Isso é feito com a função nrow (). Nrow retorna o número total de linhas no conjunto de dados. Chamamos o comprimento variável.

length<- nrow(airquality)length

Resultado:

## [1] 153

Passo 2:

Multiplicamos o comprimento por 0,8. Ele retornará o número de linhas a serem selecionadas. Deve ser 153 * 0,8 = 122,4

total_row <- length*0.8total_row

Resultado:

## [1] 122.4

Queremos selecionar 122 linhas entre as 153 linhas do conjunto de dados de qualidade aérea. Criamos uma lista contendo valores de 1 a total_row. Nós armazenamos o resultado na variável chamada divisão

split <- 1:total_rowsplit[1:5] 

Resultado:

## [1] 1 2 3 4 5

a divisão escolhe as primeiras 122 linhas do conjunto de dados. Por exemplo, podemos ver que nossa divisão de variável reúne os valores 1, 2, 3, 4, 5 e assim por diante. Esses valores serão o índice quando selecionarmos as linhas a serem retornadas.

Etapa 3:

Precisamos selecionar as linhas no conjunto de dados de qualidade do ar com base nos valores armazenados na variável de divisão. Isso é feito assim:

train_df <- airquality[split, ]head(train_df)

Resultado:

##[1] Ozone Solar.R Wind Temp Month Day##[2] 51 13 137 10.3 76 6 20##[3] 15 18 65 13.2 58 5 15##[4] 64 32 236 9.2 81 7 3##[5] 27 NA NA 8.0 57 5 27##[6] 58 NA 47 10.3 73 6 27##[7] 44 23 148 8.0 82 6 13

Passo 4:

Podemos criar o conjunto de dados de teste usando as linhas restantes, 123: 153. Isso é feito usando - na frente da divisão.

test_df <- airquality[-split, ]head(test_df)

Resultado:

##[1] Ozone Solar.R Wind Temp Month Day##[2] 123 85 188 6.3 94 8 31##[3] 124 96 167 6.9 91 9 1##[4] 125 78 197 5.1 92 9 2##[5] 126 73 183 2.8 93 9 3##[6] 127 91 189 4.6 93 9 4##[7] 128 47 95 7.4 87 9 5

Etapa 5:

Podemos criar a condição dentro do corpo da função. Lembre-se, temos um argumento trem que é um conjunto booleano definido como TRUE por padrão para retornar o conjunto de trem. Para criar a condição, usamos a sintaxe if:

if (train ==TRUE){train_df <- airquality[split, ]return(train)} else {test_df <- airquality[-split, ]return(test)}

É isso, podemos escrever a função. Só precisamos alterar a qualidade do ar para df porque queremos testar nossa função para qualquer quadro de dados, não apenas a qualidade do ar:

split_data <- function(df, train = TRUE){length<- nrow(df)total_row <- length *0.8split <- 1:total_rowif (train ==TRUE){train_df <- df[split, ]return(train_df)} else {test_df <- df[-split, ]return(test_df)}}

Vamos tentar nossa função no conjunto de dados de qualidade do ar. devemos ter um conjunto de trem com 122 linhas e um conjunto de teste com 31 linhas.

train <- split_data(airquality, train = TRUE)dim(train)

Resultado:

## [1] 122 6
test <- split_data(airquality, train = FALSE)dim(test)

Resultado:

## [1] 31 6