Funzioni nella programmazione R con esempio
Cos'è una funzione in R?
A funzione, in un ambiente di programmazione, è un insieme di istruzioni. Un programmatore crea una funzione da evitare ripetendo il stesso compito o ridurlo complessità.
Una funzione dovrebbe essere
- scritto per svolgere compiti specifici
- può includere o meno argomenti
- contenere un corpo
- può restituire o meno uno o più valori.
Un approccio generale a una funzione consiste nell'utilizzare la parte argomento come Ingressi, nutri il stile di vita parte e infine restituire un produzioneLa sintassi di una funzione è la seguente:
function (arglist) { #Function body }
R importanti funzioni integrate
Ci sono molte funzioni integrate in R. R abbina i tuoi parametri di input con i suoi argomenti di funzione, per valore o per posizione, quindi esegue il corpo della funzione. Gli argomenti della funzione possono avere valori predefiniti: se non specifichi questi argomenti, R assumerà il valore predefinito.
Note::
E' possibile vedere il codice sorgente di una funzione eseguendo il nome della funzione stessa nella console.
Vedremo tre gruppi di funzioni in azione
- Funzione generale
- Funzione matematica
- Funzione statistica
Funzioni generali
Abbiamo già familiarità con funzioni generali come cbind(), rbind(),range(),sort(),order(). Ognuna di queste funzioni ha un compito specifico, accetta argomenti per restituire un output. Di seguito sono riportate funzioni importanti che bisogna conoscere:
funzione diff()
Se lavori su serie temporali, è necessario fermare la serie prendendo il loro valori di ritardo. UN processo stazionario consente media, varianza e autocorrelazione costanti nel tempo. Ciò migliora principalmente la previsione di una serie temporale. Si può fare facilmente con la funzione diff(). Possiamo costruire una serie temporale casuale di dati con una tendenza e quindi utilizzare la funzione diff() per stazionariare la serie. La funzione diff() accetta un argomento, un vettore, e restituisce un'adeguata differenza ritardata e iterata.
Note:: Spesso abbiamo bisogno di creare dati casuali, ma per l'apprendimento e il confronto vogliamo che i numeri siano identici su tutte le macchine. Per assicurarci che tutti generiamo gli stessi dati, utilizziamo la funzione set.seed() con valori arbitrari di 123. La funzione set.seed() viene generata tramite il processo di generatore di numeri pseudo-casuali che fa sì che tutti i computer moderni abbiano la stessa sequenza di numeri. Se non utilizziamo la funzione set.seed(), avremo tutti una sequenza di numeri diversa.
set.seed(123) ## Create the data x = rnorm(1000) ts <- cumsum(x) ## Stationary the serie diff_ts <- diff(ts) par(mfrow=c(1,2)) ## Plot the series plot(ts, type='l') plot(diff(ts), type='l')
funzione lunghezza()
In molti casi, vogliamo sapere il lunghezza di un vettore per il calcolo o da utilizzare in un ciclo for. La funzione length() conta il numero di righe nel vettore x. I seguenti codici importano il dataset cars e restituiscono il numero di righe.
Note:: length() restituisce il numero di elementi in un vettore. Se la funzione viene passata in una matrice o in un frame di dati, viene restituito il numero di colonne.
dt <- cars ## number columns length(dt)
Produzione:
## [1] 1
## number rows length(dt[,1])
Produzione:
## [1] 50
Funzioni matematiche
R ha una serie di funzioni matematiche.
Operator | Descrizione |
---|---|
addominali (x) | Prende il valore assoluto di x |
registro(x,base=y) | Prende il logaritmo di x con base y; se la base non è specificata, restituisce il logaritmo naturale |
exp (x) | Restituisce l'esponenziale di x |
sqrt (x) | Restituisce la radice quadrata di x |
fattoriale(x) | Restituisce il fattoriale di x (x!) |
# sequence of number from 44 to 55 both including incremented by 1 x_vector <- seq(45,55, by = 1) #logarithm log(x_vector)
Produzione:
## [1] 3.806662 3.828641 3.850148 3.871201 3.891820 3.912023 3.931826 ## [8] 3.951244 3.970292 3.988984 4.007333
#exponential exp(x_vector)
#squared root sqrt(x_vector)
Produzione:
## [1] 6.708204 6.782330 6.855655 6.928203 7.000000 7.071068 7.141428 ## [8] 7.211103 7.280110 7.348469 7.416198
#factorial factorial(x_vector)
Produzione:
## [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
Funzioni statistiche
L'installazione standard di R contiene un'ampia gamma di funzioni statistiche. In questo tutorial esamineremo brevemente la funzione più importante..
Funzioni statistiche di base
Operator | Descrizione |
---|---|
media(x) | Media di x |
mediana(x) | Mediana di x |
var(x) | Varianza di x |
SD(x) | Deviazione standard di x |
scala(x) | Punteggi standard (punteggi z) di x |
quantile(x) | I quartili di x |
riepilogo(x) | Riepilogo di x: media, min, max ecc.. |
speed <- dt$speed speed # Mean speed of cars dataset mean(speed)
Produzione:
## [1] 15.4
# Median speed of cars dataset median(speed)
Produzione:
## [1] 15
# Variance speed of cars dataset var(speed)
Produzione:
## [1] 27.95918
# Standard deviation speed of cars dataset sd(speed)
Produzione:
## [1] 5.287644
# Standardize vector speed of cars dataset head(scale(speed), 5)
Produzione:
## [,1] ## [1,] -2.155969 ## [2,] -2.155969 ## [3,] -1.588609 ## [4,] -1.588609 ## [5,] -1.399489
# Quantile speed of cars dataset quantile(speed)
Produzione:
## 0% 25% 50% 75% 100% ## 4 12 15 19 25
# Summary speed of cars dataset summary(speed)
Produzione:
## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 4.0 12.0 15.0 15.4 19.0 25.0
Fino a questo punto abbiamo imparato molte funzioni integrate di R.
Note:: Fai attenzione alla classe dell'argomento, ad esempio numerico, booleano o stringa. Ad esempio, se dobbiamo passare un valore stringa, dobbiamo racchiudere la stringa tra virgolette: “ABC” .
Scrivi la funzione in R
In alcune occasioni, dobbiamo scrivere la nostra funzione perché dobbiamo svolgere un compito particolare e non esiste una funzione già pronta. Una funzione definita dall'utente implica a Nome, argomenti e stile di vita.
function.name <- function(arguments) { computations on the arguments some other code }
Note:: Una buona pratica è nominare una funzione definita dall'utente diversa da una funzione incorporata. Evita confusione.
Una funzione argomento
Nel frammento successivo definiamo una semplice funzione quadrata. La funzione accetta un valore e restituisce il quadrato del valore.
square_function<- function(n) { # compute the square of integer `n` n^2 } # calling the function and passing value 4 square_function(4)
Spiegazione del codice
- La funzione si chiama funzione_quadrata; può essere chiamato come vogliamo.
- Riceve un argomento "n". Noi non ha specificato il tipo di variabile in modo che l'utente possa passare un numero intero, un vettore o una matrice
- La funzione prende l'input "n" e restituisce il quadrato dell'input. Quando hai finito di utilizzare la funzione, possiamo rimuoverla con la funzione rm().
# dopo aver creato la funzione
rm(square_function) square_function
Sulla console, possiamo vedere un messaggio di errore:Errore: oggetto 'square_function' non trovato che indica che la funzione non esiste.
Ambito dell'ambiente
In R, il Industria XNUMX è un collezione di oggetti come funzioni, variabili, frame di dati, ecc.
R apre un ambiente ogni volta che viene richiesto Rstudio.
L'ambiente di primo livello disponibile è il ambiente globale, chiamato R_GlobalEnv. E abbiamo il ambiente locale.
Possiamo elencare il contenuto dell'ambiente corrente.
ls(environment())
Uscita
## [1] "diff_ts" "dt" "speed" "square_function" ## [5] "ts" "x" "x_vector"
Puoi vedere tutte le variabili e le funzioni create nel file R_GlobalEnv.
L'elenco precedente varierà in base al codice storico eseguito in R Studio.
Nota che n, l'argomento della funzione_quadrata è non in questo ambiente globale.
A nuovi viene creato un ambiente per ciascuna funzione. Nell'esempio precedente, la funzione sq_function() crea un nuovo ambiente all'interno dell'ambiente globale.
Per chiarire la differenza tra globale e ambiente locale, studiamo il seguente esempio
Queste funzioni accettano un valore x come argomento e lo aggiungono a y definito all'esterno e all'interno della funzione
La funzione f restituisce l'output 15. Questo perché y è definito nell'ambiente globale. Qualsiasi variabile definita nell'ambiente globale può essere utilizzata localmente. La variabile y ha il valore 10 durante tutte le chiamate di funzione ed è accessibile in qualsiasi momento.
Vediamo cosa succede se la variabile y è definita all'interno della funzione.
Dobbiamo eliminare "y" prima di eseguire questo codice utilizzando rm r
Anche l'output è 15 quando chiamiamo f(5) ma restituisce un errore quando proviamo a stampare il valore y. La variabile y non è nell'ambiente globale.
Infine, R usa la definizione di variabile più recente per passare all'interno del corpo di una funzione. Consideriamo il seguente esempio:
R ignora i valori y definiti all'esterno della funzione perché abbiamo creato esplicitamente la variabile y all'interno del corpo della funzione.
Funzione multi-argomenti
Possiamo scrivere una funzione con più di un argomento. Considera la funzione chiamata “tempi”. È una funzione semplice che moltiplica due variabili.
times <- function(x,y) { x*y } times(2,4)
Produzione:
## [1] 8
Quando dovremmo scrivere la funzione?
I data scientist devono svolgere molte attività ripetitive. Nella maggior parte dei casi copiamo e incolliamo porzioni di codice ripetutamente. Ad esempio, la normalizzazione di una variabile è altamente consigliata prima di eseguire a machine learning algoritmo. La formula per normalizzare una variabile è:
Sappiamo già come utilizzare le funzioni min() e max() in R. Usiamo la libreria tibble per creare il frame di dati. Tibble è finora la funzione più conveniente per creare un set di dati da zero.
library(tibble) # Create a data frame data_frame <- tibble( c1 = rnorm(50, 5, 1.5), c2 = rnorm(50, 5, 1.5), c3 = rnorm(50, 5, 1.5), )
Procederemo in due passi per calcolare la funzione sopra descritta. Nel primo passaggio creeremo una variabile chiamata c1_norm che è il riscalamento di c1. Nel secondo passaggio, copiamo e incolliamo semplicemente il codice di c1_norm e lo modifichiamo con c2 e c3.
Dettaglio della funzione con la colonna c1:
Nominatore: : data_frame$c1 -min(data_frame$c1))
Denominatore: max(data_frame$c1)-min(data_frame$c1))
Possiamo quindi dividerli per ottenere il valore normalizzato della colonna c1:
(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
Possiamo creare c1_norm, c2_norm e c3_norm:
Create c1_norm: rescaling of c1 data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1)) # show the first five values head(data_frame$c1_norm, 5)
Produzione:
## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991
Funziona. Possiamo copiare e incollare
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
quindi cambiare c1_norm in c2_norm e c1 in c2. Facciamo lo stesso per creare 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))
Abbiamo riscalato perfettamente le variabili c1, c2 e c3.
Tuttavia, questo metodo è soggetto a errori. Potremmo copiare e dimenticare di modificare il nome della colonna dopo averlo incollato. Pertanto, è buona norma scrivere una funzione ogni volta che è necessario incollare lo stesso codice più di due volte. Possiamo riorganizzare il codice in una formula e chiamarlo ogni volta che è necessario. Per scrivere la nostra funzione, dobbiamo dare:
- Nome: normalizzare.
- il numero di argomenti: abbiamo bisogno di un solo argomento, che è la colonna che usiamo nel nostro calcolo.
- Il corpo: questa è semplicemente la formula che vogliamo restituire.
Procederemo passo passo per creare la funzione normalize.
Passo 1) Creiamo il nominatore, che è . In R, possiamo memorizzare il nominatore in una variabile come questa:
nominator <- x-min(x)
Passo 2) Calcoliamo il denominatore: . Possiamo replicare l'idea del passaggio 1 e memorizzare il calcolo in una variabile:
denominator <- max(x)-min(x)
Passo 3) Eseguiamo la divisione tra nominatore e denominatore.
normalize <- nominator/denominator
Passo 4) Per restituire il valore alla funzione chiamante dobbiamo passare normalize all'interno di return() per ottenere l'output della funzione.
return(normalize)
Passo 5) Siamo pronti per utilizzare la funzione avvolgendo tutto all'interno della staffa.
normalize <- function(x){ # step 1: create the nominator nominator <- x-min(x) # step 2: create the denominator denominator <- max(x)-min(x) # step 3: divide nominator by denominator normalize <- nominator/denominator # return the value return(normalize) }
Testiamo la nostra funzione con la variabile c1:
normalize(data_frame$c1)
Funziona perfettamente. Abbiamo creato la nostra prima funzione.
Le funzioni rappresentano un modo più completo per eseguire un'attività ripetitiva. Possiamo utilizzare la formula di normalizzazione su diverse colonne, come di seguito:
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)
Anche se l'esempio è semplice, possiamo dedurre la potenza di una formula. Il codice sopra è più facile da leggere e soprattutto evita errori quando si incollano i codici.
Funzioni con condizione
A volte è necessario includere condizioni in una funzione per consentire al codice di restituire output diversi.
Nelle attività di Machine Learning, dobbiamo dividere il set di dati tra un set di treni e un set di test. Il convoglio consente all'algoritmo di apprendere dai dati. Per testare le prestazioni del nostro modello, possiamo utilizzare il set di test per restituire la misura delle prestazioni. R non ha una funzione per creare due set di dati. Possiamo scrivere la nostra funzione per farlo. La nostra funzione accetta due argomenti e si chiama split_data(). L'idea alla base è semplice, moltiplichiamo la lunghezza del set di dati (ovvero il numero di osservazioni) per 0.8. Ad esempio, se vogliamo dividere il set di dati 80/20 e il nostro set di dati contiene 100 righe, la nostra funzione moltiplicherà 0.8*100 = 80. Verranno selezionate 80 righe per diventare i nostri dati di addestramento.
Utilizzeremo il set di dati sulla qualità dell'aria per testare la nostra funzione definita dall'utente. Il set di dati sulla qualità dell'aria ha 153 righe. Possiamo vederlo con il codice qui sotto:
nrow(airquality)
Produzione:
## [1] 153
Procederemo come segue:
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
La nostra funzione ha due argomenti. L'argomento train è un parametro booleano. Se è impostato su TRUE, la nostra funzione crea il dataset train, altrimenti crea il dataset test.
Possiamo procedere come abbiamo fatto con la funzione normalise(). Scriviamo il codice come se fosse solo un codice monouso e poi avvolgiamo tutto con la condizione nel corpo per creare la funzione.
Passo 1:
Dobbiamo calcolare la lunghezza del set di dati. Questo viene fatto con la funzione nrow(). Nrow restituisce il numero totale di righe nel set di dati. Chiamiamo la lunghezza variabile.
length<- nrow(airquality) length
Produzione:
## [1] 153
Passo 2:
Moltiplichiamo la lunghezza per 0.8. Restituirà il numero di righe da selezionare. Dovrebbe essere 153*0.8 = 122.4
total_row <- length*0.8 total_row
Produzione:
## [1] 122.4
Vogliamo selezionare 122 righe tra le 153 righe nel set di dati sulla qualità dell'aria. Creiamo una lista contenente valori da 1 a total_row. Memorizziamo il risultato nella variabile chiamata split
split <- 1:total_row split[1:5]
Produzione:
## [1] 1 2 3 4 5
split sceglie le prime 122 righe dal set di dati. Ad esempio, possiamo vedere che la nostra variabile split raccoglie i valori 1, 2, 3, 4, 5 e così via. Questi valori saranno l'indice quando selezioneremo le righe da restituire.
Passo 3:
Dobbiamo selezionare le righe nel set di dati sulla qualità dell'aria in base ai valori memorizzati nella variabile divisa. Questo è fatto in questo modo:
train_df <- airquality[split, ] head(train_df)
Produzione:
##[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:
Possiamo creare il set di dati di test utilizzando le righe rimanenti, 123:153. Questo viene fatto utilizzando – davanti a split.
test_df <- airquality[-split, ] head(test_df)
Produzione:
##[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
Passo 5:
Possiamo creare la condizione all'interno del corpo della funzione. Ricorda, abbiamo un treno di argomenti che è un valore booleano impostato su TRUE per impostazione predefinita per restituire il set di treni. Per creare la condizione utilizziamo la sintassi if:
if (train ==TRUE){ train_df <- airquality[split, ] return(train) } else { test_df <- airquality[-split, ] return(test) }
Questo è tutto, possiamo scrivere la funzione. Dobbiamo solo cambiare la qualità dell'aria in df perché vogliamo provare la nostra funzione su any Frame dati, non solo qualità dell'aria:
split_data <- function(df, train = TRUE){ length<- nrow(df) total_row <- length *0.8 split <- 1:total_row if (train ==TRUE){ train_df <- df[split, ] return(train_df) } else { test_df <- df[-split, ] return(test_df) } }
Proviamo la nostra funzione sul set di dati sulla qualità dell'aria. dovremmo avere un treno con 122 file e un set di prova con 31 file.
train <- split_data(airquality, train = TRUE) dim(train)
Produzione:
## [1] 122 6
test <- split_data(airquality, train = FALSE) dim(test)
Produzione:
## [1] 31 6