Funkcije u R programiranju s primjerom
โก Pametni saลพetak
Funkcije u R-u pakiraju skup instrukcija pod jednim imenom, tako da se ponovljeni zadatak izvrลกava iz jednog poziva. Ugraฤeni matematiฤki i statistiฤki pomagaฤi, korisniฤki definirane funkcije, sco okruลพenjaping, a uvjetni argumenti ovdje su obraฤeni s primjerima obrade.

ล to je funkcija u R-u?
A funkcija, u programskom okruลพenju, skup je instrukcija. Programer gradi funkciju koju treba izbjegavati ponavljanje istog zadatkaili smanjiti sloลพenost.
Funkcija bi trebala biti
- napisan za izvrลกavanje odreฤenog zadatka
- moลพe ali ne mora ukljuฤivati โโargumente
- sadrลพavati tijelo
- moลพe, ali i ne mora vratiti jednu ili viลกe vrijednosti.
Opฤi pristup funkciji je koriลกtenje dijela argumenta kao ulazi, nahrani tijelu dio i konaฤno vratiti an izlaz. Sintaksa funkcije je sljedeฤa:
function (arglist) { #Function body }
R vaลพne ugraฤene funkcije
Postoji mnogo ugraฤenih funkcija u R. R usklaฤuje vaลกe ulazne parametre sa svojim argumentima funkcije, bilo prema vrijednosti ili poloลพaju, a zatim izvrลกava tijelo funkcije. Argumenti funkcije mogu imati zadane vrijednosti: ako ne navedete ove argumente, R ฤe uzeti zadanu vrijednost.
biljeลกke:
Moguฤe je vidjeti izvorni kod funkcije pokretanjem naziva same funkcije u konzoli.
Typing Naziv funkcije bez zagrada ispisuje njen izvorni kod, kao ลกto je prikazano u konzoli ispod.
Vidjet ฤemo tri skupine funkcija na djelu
- Opฤa funkcija
- Matematiฤka funkcija
- Statistiฤka funkcija
Opฤe funkcije
Veฤ smo upoznati s opฤim funkcijama poput cbind(), rbind(), range(), vrsta()i order(). Svaka od ovih funkcija ima specifiฤan zadatak, prima argumente za vraฤanje izlaza. Slijede vaลพne funkcije koje morate znati -
funkcija diff().
Ako radite na vremenske serije, trebate stacionirati seriju uzimajuฤi njihove vrijednosti kaลกnjenja. stacionarni proces Omoguฤuje konstantnu srednju vrijednost, varijancu i autokorelaciju tijekom vremena. To uglavnom poboljลกava predviฤanje vremenskog niza. To se moลพe uฤiniti funkcijom diff(). Moลพemo izgraditi sluฤajni vremenski niz podataka s trendom, a zatim koristiti funkciju diff() za stacionarizaciju niza. Funkcija diff() prihvaฤa jedan argument, vektor, i vraฤa odgovarajuฤu pomaknutu i iteriranu razliku.
biljeลกkeฤesto trebamo stvarati sluฤajne podatke, ali za uฤenje i usporedbu ลพelimo da brojevi budu identiฤni na svim strojevima. Kako bismo osigurali da svi generiramo iste podatke, koristimo funkciju set.seed() s proizvoljnim vrijednostima 123. set.seed() fiksira poฤetnu toฤku generatora pseudosluฤajnih brojeva, tako da svaki stroj proizvodi isti niz. Bez set.seed(), svako pokretanje vraฤa drugaฤiji niz.
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')
Dva panela ispod smjeลกtaju izvorni kumulativni niz pored diferenciranog niza, koji sada fluktuira oko konstantne srednje vrijednosti.
funkcija length().
U mnogim sluฤajevima ลพelimo znati duljinu vektora za izraฤun ili za koriลกtenje u for petlji. Funkcija length() broji broj redaka u vektoru x. Sljedeฤi kodovi uvoze skup podataka o automobilima i vraฤaju broj redaka.
biljeลกke: length() vraฤa broj elemenata u vektoru. Ako se funkcija prosljeฤuje u matrica ili podatkovni okvir, vraฤa se broj stupaca.
dt <- cars
## number columns
length(dt)
Izlaz:
## [1] 1
## number rows
length(dt[,1])
Izlaz:
## [1] 50
Matematiฤke funkcije
Osim opฤih pomoฤnih funkcija, R ima niz matematiฤkih funkcija koje operiraju element po element na vektoru.
| Operahumka | Description |
|---|---|
| trbuลกnjaci (x) | Uzima apsolutnu vrijednost x |
| log(x,baza=y) | Uzima logaritam od x s bazom y; ako baza nije navedena, vraฤa prirodni logaritam |
| exp(x) | Vraฤa eksponencijal od x |
| sqrt (x) | Vraฤa kvadratni korijen od x |
| faktorijel(x) | Vraฤa faktorijel 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)
Izlaz:
## [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)
Izlaz:
## [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)
Izlaz:
## [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
Statistiฤke funkcije
Tamo gdje matematiฤke funkcije transformiraju vrijednosti, statistiฤke funkcije ih saลพimaju. Standardna instalacija R-a sadrลพi ลกirok raspon statistiฤkih funkcija. U ovom ฤemo vodiฤu ukratko pogledati najvaลพnije.
Osnovne statistiฤke funkcije
| Operahumka | Description |
|---|---|
| srednja vrijednost (x) | Srednja vrijednost x |
| medijan(x) | Medijan od x |
| var(x) | Varijanca x |
| sd(x) | Standardna devijacija x |
| skala (x) | Standardni rezultati (z-rezultati) od x |
| kvantil(x) | Kvartili od x |
| saลพetak(x) | Saลพetak x: srednja vrijednost, min, maks itd. |
speed <- dt$speed
speed
# Mean speed of cars dataset
mean(speed)
Izlaz:
## [1] 15.4
# Median speed of cars dataset
median(speed)
Izlaz:
## [1] 15
# Variance speed of cars dataset
var(speed)
Izlaz:
## [1] 27.95918
# Standard deviation speed of cars dataset
sd(speed)
Izlaz:
## [1] 5.287644
# Standardize vector speed of cars dataset
head(scale(speed), 5)
Izlaz:
## [,1] ## [1,] -2.155969 ## [2,] -2.155969 ## [3,] -1.588609 ## [4,] -1.588609 ## [5,] -1.399489
# Quantile speed of cars dataset
quantile(speed)
Izlaz:
## 0% 25% 50% 75% 100% ## 4 12 15 19 25
# Summary speed of cars dataset
summary(speed)
Izlaz:
## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 4.0 12.0 15.0 15.4 19.0 25.0
Do ove toฤke nauฤili smo puno R ugraฤenih funkcija.
biljeลกke: Budite oprezni s klasa argumenta, tj. numeriฤki, logiฤki ili niz znakova. Na primjer, ako trebamo proslijediti niz znakova, moramo ga staviti u navodnike: โABCโ.
Napiลกite funkciju u R
U nekim sluฤajevima moramo napisati vlastitu funkciju jer moramo izvrลกiti odreฤeni zadatak, a ne postoji gotova funkcija. Korisniฤki definirana funkcija ukljuฤuje ime, argumenti a tijelu.
function.name <- function(arguments) { computations on the arguments some other code }
biljeลกke: Dobra praksa je imenovanje korisniฤki definirane funkcije drugaฤije od ugraฤene funkcije. Izbjegava zabunu.
Funkcija jednog argumenta
U sljedeฤem isjeฤku definiramo jednostavnu kvadratnu funkciju. Funkcija prihvaฤa vrijednost i vraฤa kvadrat vrijednosti.
square_function<- function(n) { # compute the square of integer `n` n^2 } # calling the function and passing value 4 square_function(4)
Code Objaลกnjenje
- Funkcija se zove square_function; moลพe se zvati kako god ลพelimo.
- Prima argument "n". Mi nije odredio vrstu varijable tako da korisnik moลพe proslijediti cijeli broj, vektor ili matricu
- Funkcija uzima ulaz "n" i vraฤa kvadrat ulaza. Kada zavrลกite s upotrebom funkcije, moลพemo je ukloniti pomoฤu funkcije rm().
# nakon ลกto stvorite funkciju
rm(square_function) square_function
Na konzoli moลพemo vidjeti poruku o pogreลกci :Error: object 'square_function' not found ลกto govori da funkcija ne postoji.
Okoliลกna komisijaping
U R, okolina je skup objekata poput funkcija, varijabli, okvira podataka itd.
R otvara okruลพenje svaki put kada se pokrene RStudio.
Dostupno okruลพenje najviลกe razine je globalno okruลพenje, nazvan R_GlobalEnv. I imamo lokalnoj sredini.
Moลพemo navesti sadrลพaj trenutnog okruลพenja.
ls(environment())
Izlaz
## [1] "diff_ts" "dt" "speed" "square_function" ## [5] "ts" "x" "x_vector"
Moลพete vidjeti sve varijable i funkcije stvorene u R_GlobalEnv.
Gornji popis ฤe se razlikovati ovisno o povijesnom kodu koji izvrลกavate u RStudiu.
Imajte na umu da n, argument funkcije kvadrat_funkcije nije u ovom globalnom okruลพenju.
Za svaku funkciju stvara se novo okruลพenje. U gornjem primjeru, funkcija square_function() stvara novo okruลพenje unutar globalno okruลพenje.
Da razjasnimo razliku izmeฤu globalno i lokalne okruลพenje, prouฤimo sljedeฤi primjer
Ova funkcija uzima vrijednost x kao argument i dodaje je y definiranju izvan i unutar funkcije
Funkcija f vraฤa izlaz 15. To je zato ลกto je y definiran u globalnom okruลพenju. Bilo koja varijabla definirana u globalnom okruลพenju moลพe se koristiti lokalno. Varijabla y ima vrijednost 10 tijekom svih poziva funkcije i dostupna je u bilo kojem trenutku.
Pogledajmo ลกto se dogaฤa ako je varijabla y definirana unutar funkcije.
Moramo ispustiti `y` prije pokretanja ovog koda koristeฤi rm r
Izlaz je takoฤer 15 kada pozovemo f(5), ali vraฤa pogreลกku kada pokuลกamo ispisati vrijednost y. Varijabla y nije u globalnom okruลพenju.
Konaฤno, R koristi najnoviju definiciju varijable za prolaz unutar tijela funkcije. Razmotrimo sljedeฤi primjer:
R zanemaruje y vrijednosti definirane izvan funkcije jer smo eksplicitno stvorili y varijablu unutar tijela funkcije.
Funkcija s viลกe argumenata
Funkciju moลพemo napisati s viลกe od jednog argumenta. Razmotrite funkciju koja se zove "puta". To je jednostavna funkcija koja mnoลพi dvije varijable.
times <- function(x,y) {
x*y
}
times(2,4)
Izlaz:
## [1] 8
Kada trebamo napisati funkciju?
Znanstvenici podataka moraju obavljati mnogo repetitivnih zadataka. Veฤinu vremena kopiramo i lijepimo dijelove koda viลกe puta. Na primjer, normalizacija varijable se toplo preporuฤuje prije pokretanja stroj za uฤenje algoritam. Formula za normalizaciju varijable je:
Veฤ znamo kako koristiti funkcije min() i max() u R. Koristimo biblioteku tibble za stvaranje okvira podataka. Tibble je do sada najprikladnija funkcija za stvaranje skupa podataka od nule.
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), )
Gore opisanu funkciju izraฤunat ฤemo u dva koraka. U prvom koraku stvorit ฤemo varijablu pod nazivom c1_norm koja predstavlja preoblikovanje c1. U drugom koraku samo kopiramo i zalijepimo kod c1_norm te ga zamijenimo s c2 i c3.
Detalj funkcije sa stupcem c1:
Nominator: : data_frame$c1 -min(data_frame$c1))
Nazivnik: max(data_frame$c1)-min(data_frame$c1))
Stoga ih moลพemo podijeliti da dobijemo normaliziranu vrijednost stupca c1:
(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
Moลพemo kreirati 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)
Izlaz:
## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991
Radi. Moลพemo kopirati i zalijepiti
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
zatim promijenite c1_norm u c2_norm i c1 u c2. ฤinimo isto da stvorimo 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))
Savrลกeno smo skalirali varijable c1, c2 i c3.
Meฤutim, ova metoda je sklona pogreลกkama. Mogli bismo kopirati i zaboraviti promijeniti naziv stupca nakon lijepljenja. Stoga je dobra praksa napisati funkciju svaki put kada trebate zalijepiti isti kod viลกe od dva puta. Kod moลพemo preurediti u formulu i pozvati je kad god je potrebno. Da bismo napisali vlastitu funkciju, moramo dati:
- Naziv: normalizirati.
- broj argumenata: Trebamo samo jedan argument, a to je stupac koji koristimo u naลกem izraฤunu.
- Tijelo: to je jednostavno formula koju ลพelimo vratiti.
Nastavit ฤemo korak po korak za stvaranje normalizacije funkcije.
Korak 1) Stvaramo nominator, koji je x โ min(x). U R-u moลพemo pohraniti nominator u varijablu poput ove:
nominator <- x-min(x)
Korak 2) Izraฤunavamo nazivnik: max(x) โ min(x). Moลพemo ponoviti ideju iz koraka 1 i pohraniti izraฤun u varijablu:
denominator <- max(x)-min(x)
Korak 3) Izvodimo dijeljenje izmeฤu nazivnika i nazivnika.
normalize <- nominator/denominator
Korak 4) Da bismo vratili vrijednost pozivnoj funkciji, moramo proฤi normalizaciju unutar return() da bismo dobili izlaz funkcije.
return(normalize)
Korak 5) Spremni smo koristiti funkciju prelamanjemping sve unutar zagrade.
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) }
Testirajmo naลกu funkciju s varijablom c1:
normalize(data_frame$c1)
Radi savrลกeno. Stvorili smo naลกu prvu funkciju.
Funkcija je sveobuhvatniji naฤin izvrลกavanja zadatka koji se ponavlja. Moลพemo koristiti formulu za normalizaciju nad razliฤitim stupcima, kao ลกto je prikazano u nastavku:
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)
Iako je primjer jednostavan, moลพemo zakljuฤiti snagu formule. Gornji kod je lakลกi za ฤitanje i izbjegava pogreลกke koje se javljaju prilikom lijepljenja koda.
Funkcije s uvjetom
Funkcija normalize() uvijek radi istu stvar. Ponekad moramo ukljuฤiti uvjete u funkciju kako bismo omoguฤili kodu da vraฤa razliฤite izlaze.
U zadacima strojnog uฤenja moramo podijeliti skup podataka izmeฤu skupa vlakova i testnog skupa. Skup vlakova omoguฤuje algoritmu da uฤi iz podataka. Kako bismo testirali izvedbu naลกeg modela, moลพemo koristiti testni skup za vraฤanje mjere izvedbe. R nema funkciju za stvaranje dva skupa podataka. Moลพemo napisati vlastitu funkciju da to uฤinimo. Naลกa funkcija uzima dva argumenta i zove se split_data(). Ideja iza je jednostavna, mnoลพimo duljinu skupa podataka (tj. broj opaลพanja) s 0.8. Na primjer, ako ลพelimo podijeliti skup podataka 80/20, a naลก skup podataka sadrลพi 100 redaka, tada ฤe naลกa funkcija pomnoลพiti 0.8*100 = 80. 80 redaka bit ฤe odabrano da postanu naลกi podaci za obuku.
Koristit ฤemo skup podataka o kvaliteti zraka za testiranje naลกe korisniฤki definirane funkcije. Skup podataka o kvaliteti zraka ima 153 retka. Moลพemo to vidjeti pomoฤu koda ispod:
nrow(airquality)
Izlaz:
## [1] 153
Postupit ฤemo na sljedeฤi naฤin:
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
Naลกa funkcija ima dva argumenta. Niz argumenata je Booleov parametar. Ako je postavljeno na TRUE, naลกa funkcija stvara skup podataka o vlaku, u suprotnom, stvara testni skup podataka.
Moลพemo nastaviti kao ลกto smo uฤinili s funkcijom normalize(). Kod piลกemo kao da je rijeฤ samo o jednokratnom kodu, a zatim sve s uvjetom omotamo u tijelo kako bismo stvorili funkciju.
Korak 1:
Moramo izraฤunati duljinu skupa podataka. To se radi pomoฤu funkcije nrow(). Nrow vraฤa ukupan broj redaka u skupu podataka. Promjenljivu duljinu nazivamo.
length<- nrow(airquality) length
Izlaz:
## [1] 153
Korak 2:
Duljinu mnoลพimo s 0.8. Vratit ฤe broj redaka za odabir. Trebalo bi biti 153*0.8 = 122.4
total_row <- length*0.8 total_row
Izlaz:
## [1] 122.4
ลฝelimo odabrati 122 retka meฤu 153 retka u skupu podataka o kvaliteti zraka. Stvaramo popis koji sadrลพi vrijednosti od 1 do total_row. Rezultat pohranjujemo u varijablu koja se zove split
split <- 1:total_row split[1:5]
Izlaz:
## [1] 1 2 3 4 5
split odabire prva 122 reda iz skupa podataka. Na primjer, moลพemo vidjeti da naลกa varijabla split okuplja vrijednosti 1, 2, 3, 4, 5 i tako dalje. Ove vrijednosti ฤe biti indeks kada budemo birali retke koje ฤemo vratiti.
Korak 3:
Moramo odabrati retke u skupu podataka o kvaliteti zraka na temelju vrijednosti pohranjenih u podijeljenoj varijabli. To se radi ovako:
train_df <- airquality[split, ] head(train_df)
Izlaz:
##[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
Korak 4:
Moลพemo izraditi testni skup podataka koriลกtenjem preostalih redaka, 123:153. To se radi pomoฤu โ ispred split.
test_df <- airquality[-split, ] head(test_df)
Izlaz:
##[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
Korak 5:
Moลพemo stvoriti stanje unutar tijela funkcije. Upamtite, imamo niz argumenata koji je Booleov postavljen na TRUE prema zadanim postavkama za vraฤanje skupa niza. Za stvaranje uvjeta koristimo if sintaksu:
if (train ==TRUE){ train_df <- airquality[split, ] return(train) } else { test_df <- airquality[-split, ] return(test) }
To je to, moลพemo napisati funkciju. Samo trebamo promijeniti kvalitetu zraka u df jer ลพelimo isprobati naลกu funkciju na bilo koju podatkovni okvir, ne samo kvaliteta zraka:
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) } }
Isprobajmo naลกu funkciju na skupu podataka o kvaliteti zraka. Trebali bismo imati jedan skup vlakova sa 122 retka i testni skup s 31 retkom.
train <- split_data(airquality, train = TRUE)
dim(train)
Izlaz:
## [1] 122 6
test <- split_data(airquality, train = FALSE)
dim(test)
Izlaz:
## [1] 31 6






