Funcții în R Programare cu Exemplu
Ce este o funcție în R?
A funcţie, într-un mediu de programare, este un set de instrucțiuni. Un programator construiește o funcție de evitat repetarea aceeași sarcină sau reduceți complexitate.
O funcție ar trebui să fie
- scris pentru a îndeplini anumite sarcini
- poate include sau nu argumente
- conţin un corp
- poate returna sau nu una sau mai multe valori.
O abordare generală a unei funcții este de a folosi partea argument ca intrări, hraneste corp parte și în cele din urmă returnează an producție. Sintaxa unei funcții este următoarea:
function (arglist) { #Function body }
R funcții încorporate importante
Există o mulțime de funcții încorporate în R. R potrivește parametrii de intrare cu argumentele funcției sale, fie după valoare, fie după poziție, apoi execută corpul funcției. Argumentele funcției pot avea valori implicite: dacă nu specificați aceste argumente, R va lua valoarea implicită.
notițe:
Este posibil să vedeți codul sursă al unei funcții rulând numele funcției în sine în consolă.
Vom vedea trei grupuri de funcții în acțiune
- Funcția generală
- Funcția matematică
- Funcția statistică
Funcții generale
Suntem deja familiarizați cu funcțiile generale precum funcțiile cbind(), rbind(),range(),sort(),order(). Fiecare dintre aceste funcții are o sarcină specifică, ia argumente pentru a returna o ieșire. Următoarele sunt funcții importante pe care trebuie să le cunoașteți-
funcția diff().
Dacă lucrezi la serii de timp, trebuie să staționați seria prin luarea lor valori de lag. O proces staționar permite medie, varianță și autocorelare constantă în timp. Acest lucru îmbunătățește în principal predicția unei serii de timp. Se poate face cu ușurință cu funcția diff(). Putem construi o serie de date aleatoare cu o tendință și apoi să folosim funcția diff() pentru a staționa seria. Funcția diff() acceptă un argument, un vector și returnează o diferență adecvată întârziată și iterată.
notițe: De multe ori trebuie să creăm date aleatorii, dar pentru învățare și comparare dorim ca numerele să fie identice pe mașini. Pentru a ne asigura că toți generăm aceleași date, folosim funcția set.seed() cu valori arbitrare de 123. Funcția set.seed() este generată prin procesul de generator de numere pseudoaleatoare care face ca fiecare computer modern să aibă aceeași secvență de numere. Dacă nu folosim funcția set.seed(), toți vom avea o secvență diferită de numere.
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')
funcția length().
În multe cazuri, vrem să știm lungime a unui vector pentru calcul sau pentru a fi utilizat într-o buclă for. Funcția length() numără numărul de rânduri din vectorul x. Următoarele coduri importă setul de date mașini și returnează numărul de rânduri.
notițe: length() returnează numărul de elemente dintr-un vector. Dacă funcția este transmisă într-o matrice sau într-un cadru de date, este returnat numărul de coloane.
dt <- cars ## number columns length(dt)
ieșire:
## [1] 1
## number rows length(dt[,1])
ieșire:
## [1] 50
Funcții matematice
R are o serie de funcții matematice.
OperaTdR | Descriere |
---|---|
abs (x) | Ia valoarea absolută a lui x |
log(x,bază=y) | Ia logaritmul lui x cu baza y; dacă baza nu este specificată, returnează logaritmul natural |
exp (x) | Returnează exponențialul lui x |
sqrt (x) | Returnează rădăcina pătrată a lui x |
factorial(x) | Returnează factorialul lui 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)
ieșire:
## [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)
ieșire:
## [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)
ieșire:
## [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
Funcțiile statistice
Instalarea standard R conține o gamă largă de funcții statistice. În acest tutorial, ne vom uita pe scurt la cea mai importantă funcție..
Funcții statistice de bază
OperaTdR | Descriere |
---|---|
medie (x) | Media lui x |
mediana(x) | Mediana lui x |
var(x) | Varianta lui x |
sd(x) | Abaterea standard a lui x |
scară (x) | Scoruri standard (scoruri z) ale lui x |
cuantilă (x) | Quartilele lui x |
rezumat(x) | Rezumatul lui x: medie, min, max etc.. |
speed <- dt$speed speed # Mean speed of cars dataset mean(speed)
ieșire:
## [1] 15.4
# Median speed of cars dataset median(speed)
ieșire:
## [1] 15
# Variance speed of cars dataset var(speed)
ieșire:
## [1] 27.95918
# Standard deviation speed of cars dataset sd(speed)
ieșire:
## [1] 5.287644
# Standardize vector speed of cars dataset head(scale(speed), 5)
ieșire:
## [,1] ## [1,] -2.155969 ## [2,] -2.155969 ## [3,] -1.588609 ## [4,] -1.588609 ## [5,] -1.399489
# Quantile speed of cars dataset quantile(speed)
ieșire:
## 0% 25% 50% 75% 100% ## 4 12 15 19 25
# Summary speed of cars dataset summary(speed)
ieșire:
## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 4.0 12.0 15.0 15.4 19.0 25.0
Până în acest moment, am învățat o mulțime de funcții încorporate R.
notițe: Fiți atenți la clasa argumentului, adică numeric, boolean sau șir. De exemplu, dacă trebuie să transmitem o valoare șir, trebuie să includem șirul între ghilimele: „ABC” .
Scrieți funcția în R
În unele ocazii, trebuie să ne scriem propria funcție, deoarece trebuie să îndeplinim o anumită sarcină și nu există nicio funcție gata făcută. O funcție definită de utilizator implică a nume, argumente și corp.
function.name <- function(arguments) { computations on the arguments some other code }
notițe: O bună practică este de a numi o funcție definită de utilizator diferită de o funcție încorporată. Evită confuzia.
Funcția cu un singur argument
În următorul fragment, definim o funcție pătrată simplă. Funcția acceptă o valoare și returnează pătratul valorii.
square_function<- function(n) { # compute the square of integer `n` n^2 } # calling the function and passing value 4 square_function(4)
Explicarea codului
- Funcția se numește square_function; se poate numi cum vrem noi.
- Primește un argument „n”. Noi nu a specificat tipul de variabilă, astfel încât utilizatorul să poată transmite un număr întreg, un vector sau o matrice
- Funcția preia intrarea „n” și returnează pătratul intrării. Când ați terminat de utilizat funcția, o putem elimina cu funcția rm().
# după ce creați funcția
rm(square_function) square_function
Pe consolă, putem vedea un mesaj de eroare: Eroare: obiectul „square_function” nu a fost găsit, indicând că funcția nu există.
Definirea mediului
În R, mediu inconjurator este colectare de obiecte precum funcții, variabile, cadrul de date etc.
R deschide un mediu de fiecare dată când este solicitat Rstudio.
Mediul de nivel superior disponibil este mediu global, numit R_GlobalEnv. Și avem mediul local.
Putem enumera conținutul mediului actual.
ls(environment())
producție
## [1] "diff_ts" "dt" "speed" "square_function" ## [5] "ts" "x" "x_vector"
Puteți vedea toate variabilele și funcțiile create în R_GlobalEnv.
Lista de mai sus va varia pentru dvs. în funcție de codul istoric pe care îl executați în R Studio.
Rețineți că n, argumentul funcției square_function este nu în acest mediu global.
A nou mediu este creat pentru fiecare funcție. În exemplul de mai sus, funcția square_function() creează un nou mediu în mediul global.
Pentru a clarifica diferența dintre global si mediul local, să studiem următorul exemplu
Aceste funcții iau o valoare x ca argument și o adaugă la definiția y în afara și în interiorul funcției
Funcția f returnează rezultatul 15. Acest lucru se datorează faptului că y este definit în mediul global. Orice variabilă definită în mediul global poate fi utilizată local. Variabila y are valoarea 10 în timpul tuturor apelurilor de funcții și este accesibilă în orice moment.
Să vedem ce se întâmplă dacă variabila y este definită în interiorul funcției.
Trebuie să aruncăm `y` înainte de a rula acest cod folosind rm r
Ieșirea este, de asemenea, 15 când apelăm f(5), dar returnează o eroare când încercăm să tipărim valoarea y. Variabila y nu se află în mediul global.
În cele din urmă, R folosește cea mai recentă definiție a variabilei pentru a trece în corpul unei funcții. Să luăm în considerare următorul exemplu:
R ignoră valorile y definite în afara funcției, deoarece am creat în mod explicit o variabilă ay în corpul funcției.
Funcția cu mai multe argumente
Putem scrie o funcție cu mai mult de un argument. Luați în considerare funcția numită „timpi”. Este o funcție simplă care înmulțește două variabile.
times <- function(x,y) { x*y } times(2,4)
ieșire:
## [1] 8
Când ar trebui să scriem funcția?
Oamenii de știință de date trebuie să facă multe sarcini repetitive. De cele mai multe ori, copiem și lipim bucăți de cod în mod repetitiv. De exemplu, normalizarea unei variabile este foarte recomandată înainte de a rula a masina de învățare algoritm. Formula de normalizare a unei variabile este:
Știm deja cum să folosim funcția min() și max() în R. Folosim biblioteca tibble pentru a crea cadrul de date. Tibble este până acum cea mai convenabilă funcție pentru a crea un set de date de la 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), )
Vom proceda în doi pași pentru a calcula funcția descrisă mai sus. În primul pas, vom crea o variabilă numită c1_norm care este redimensionarea lui c1. În pasul doi, doar copiam și lipim codul c1_norm și schimbăm cu c2 și c3.
Detaliu al funcției cu coloana c1:
Nominator: : data_frame$c1 -min(data_frame$c1))
Numitor: max(data_frame$c1)-min(data_frame$c1))
Prin urmare, le putem împărți pentru a obține valoarea normalizată a coloanei c1:
(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
Putem crea c1_norm, c2_norm și 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)
ieșire:
## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991
Funcționează. Putem copia și lipi
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
apoi schimbați c1_norm în c2_norm și c1 în c2. Facem același lucru pentru a crea 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))
Am redimensionat perfect variabilele c1, c2 și c3.
Cu toate acestea, această metodă este predispusă la greșeală. Am putea copia și uita să schimbăm numele coloanei după lipire. Prin urmare, o practică bună este să scrieți o funcție de fiecare dată când trebuie să lipiți același cod de mai mult de două ori. Putem rearanja codul într-o formulă și îl putem apela ori de câte ori este nevoie. Pentru a scrie propria noastră funcție, trebuie să dăm:
- Nume: normalizați.
- numărul de argumente: avem nevoie de un singur argument, care este coloana pe care o folosim în calcul.
- Corpul: aceasta este pur și simplu formula pe care vrem să o întoarcem.
Vom proceda pas cu pas pentru a crea funcția normalize.
Pas 1) Noi creăm nominalizator, care este . În R, putem stoca numitorul într-o variabilă ca aceasta:
nominator <- x-min(x)
Pas 2) Calculăm numitor: . Putem replica ideea pasului 1 și stocăm calculul într-o variabilă:
denominator <- max(x)-min(x)
Pas 3) Efectuăm împărțirea între numitor și numitor.
normalize <- nominator/denominator
Pas 4) Pentru a returna valoarea funcției de apelare, trebuie să trecem normalize în interiorul return() pentru a obține rezultatul funcției.
return(normalize)
Pas 5) Suntem gata să folosim funcția înfășurând totul în interiorul suportului.
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) }
Să testăm funcția noastră cu variabila c1:
normalize(data_frame$c1)
Functioneaza perfect. Am creat prima noastră funcție.
Funcțiile sunt o modalitate mai cuprinzătoare de a efectua o sarcină repetitivă. Putem folosi formula de normalizare pe diferite coloane, ca mai jos:
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)
Chiar dacă exemplul este simplu, putem deduce puterea unei formule. Codul de mai sus este mai ușor de citit și mai ales evită greșelile la lipirea codurilor.
Funcționează cu condiție
Uneori, trebuie să includem condiții într-o funcție pentru a permite codului să returneze rezultate diferite.
În sarcinile de învățare automată, trebuie să împărțim setul de date între un set de tren și un set de testare. Setul de tren permite algoritmului să învețe din date. Pentru a testa performanța modelului nostru, putem folosi setul de testare pentru a returna măsura de performanță. R nu are o funcție pentru a crea două seturi de date. Putem scrie propria noastră funcție pentru a face asta. Funcția noastră ia două argumente și se numește split_data(). Ideea din spate este simplă, înmulțim lungimea setului de date (adică numărul de observații) cu 0.8. De exemplu, dacă dorim să împărțim setul de date 80/20, iar setul nostru de date conține 100 de rânduri, atunci funcția noastră va înmulți 0.8*100 = 80. 80 de rânduri vor fi selectate pentru a deveni datele noastre de antrenament.
Vom folosi setul de date privind calitatea aerului pentru a testa funcția noastră definită de utilizator. Setul de date privind calitatea aerului are 153 de rânduri. O putem vedea cu codul de mai jos:
nrow(airquality)
ieșire:
## [1] 153
Vom proceda astfel:
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
Funcția noastră are două argumente. Trainul de argumente este un parametru boolean. Dacă este setată la TRUE, funcția noastră creează setul de date tren, în caz contrar, creează setul de date de testare.
Putem proceda așa cum am procedat cu funcția normalise(). Scriem codul ca și cum ar fi fost un singur cod și apoi înfășurăm totul cu condiția în corp pentru a crea funcția.
Pasul 1:
Trebuie să calculăm lungimea setului de date. Acest lucru se face cu funcția nrow(). Nrow returnează numărul total de rânduri din setul de date. Numim lungimea variabilă.
length<- nrow(airquality) length
ieșire:
## [1] 153
Pasul 2:
Înmulțim lungimea cu 0.8. Va returna numărul de rânduri de selectat. Ar trebui să fie 153*0.8 = 122.4
total_row <- length*0.8 total_row
ieșire:
## [1] 122.4
Dorim să selectăm 122 de rânduri dintre cele 153 de rânduri din setul de date privind calitatea aerului. Creăm o listă care conține valori de la 1 la total_row. Stocăm rezultatul în variabila numită split
split <- 1:total_row split[1:5]
ieșire:
## [1] 1 2 3 4 5
split alege primele 122 de rânduri din setul de date. De exemplu, putem vedea că împărțirea noastră variabilă adună valorile 1, 2, 3, 4, 5 și așa mai departe. Aceste valori vor fi indexul când vom selecta rândurile de returnat.
Pasul 3:
Trebuie să selectăm rândurile din setul de date privind calitatea aerului pe baza valorilor stocate în variabila divizată. Acest lucru se face astfel:
train_df <- airquality[split, ] head(train_df)
ieșire:
##[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
Pasul 4:
Putem crea setul de date de testare utilizând rândurile rămase, 123:153. Acest lucru se face prin utilizarea – în fața split-ului.
test_df <- airquality[-split, ] head(test_df)
ieșire:
##[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
Pasul 5:
Putem crea condiția în interiorul corpului funcției. Amintiți-vă, avem un tren de argumente care este un set boolean la TRUE în mod implicit pentru a returna setul de tren. Pentru a crea condiția, folosim sintaxa if:
if (train ==TRUE){ train_df <- airquality[split, ] return(train) } else { test_df <- airquality[-split, ] return(test) }
Asta este, putem scrie funcția. Trebuie doar să schimbăm calitatea aerului în df pentru că vrem să încercăm funcția noastră la oricare cadru de date, nu numai calitatea aerului:
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) } }
Să încercăm funcția noastră pe setul de date privind calitatea aerului. ar trebui să avem o garnitură de tren cu 122 de rânduri și un set de test cu 31 de rânduri.
train <- split_data(airquality, train = TRUE) dim(train)
ieșire:
## [1] 122 6
test <- split_data(airquality, train = FALSE) dim(test)
ieșire:
## [1] 31 6