Funkciók az R programozásban példával
Mi az a függvény az R-ben?
A funkció, programozási környezetben, egy utasításkészlet. A programozó létrehoz egy függvényt, amelyet elkerülni kell megismételve a ugyanaz a feladat, vagy csökkentse bonyolultság.
Egy függvénynek lennie kell
- meghatározott feladatok elvégzésére írják
- tartalmazhat érveket vagy nem
- testet tartalmaznak
- visszaadhat egy vagy több értéket, vagy nem.
A függvény általános megközelítése az, hogy az argumentum részt használjuk bemenet, táplálja a test rész és végül visszaadja an teljesítmény. Egy függvény szintaxisa a következő:
function (arglist) { #Function body }
R fontos beépített funkciók
Az R-ben sok beépített függvény található. R egyezteti a bemeneti paramétereket a függvény argumentumaival, akár érték, akár pozíció szerint, majd végrehajtja a függvénytörzset. A függvény argumentumainak lehetnek alapértelmezett értékei: ha nem adja meg ezeket az argumentumokat, az R az alapértelmezett értéket veszi fel.
Megjegyzések:
Egy függvény forráskódját úgy tekintheti meg, ha magának a függvénynek a nevét futtatja a konzolon.
Három funkciócsoportot fogunk látni működés közben
- Általános funkció
- Matek függvény
- Statisztikai függvény
Általános funkciók
Már ismerjük az általános függvényeket, például a cbind(), rbind(),range(),sort(),order() függvényeket. Ezen függvények mindegyikének van egy meghatározott feladata, argumentumokat kér a kimenet visszaadásához. A következő fontos funkciókat ismerni kell:
diff() függvény
Ha dolgozol tovább idősorok, meg kell stacionárius a sorozat azáltal, hogy azok lag értékeket. A álló folyamat állandó átlagot, szórást és autokorrelációt tesz lehetővé az időben. Ez elsősorban az idősorok előrejelzését javítja. Könnyen megtehető a diff() függvénnyel. Felépíthetünk egy véletlenszerű idősoros adatot trenddel, majd a diff() függvény segítségével rögzíthetjük a sorozatot. A diff() függvény elfogad egy argumentumot, egy vektort, és megfelelő késleltetett és iterált különbséget ad vissza.
Megjegyzések: Gyakran véletlenszerű adatokat kell létrehoznunk, de a tanuláshoz és az összehasonlításhoz azt szeretnénk, hogy a számok azonosak legyenek a gépeken. Annak biztosítására, hogy mindannyian ugyanazokat az adatokat generáljuk, a set.seed() függvényt tetszőleges 123 értékkel használjuk. A set.seed() függvényt az álvéletlen számgenerátor folyamata hozza létre, amely minden modern számítógépet ugyanazzal a sorozattal állít elő. számokból. Ha nem használjuk a set.seed() függvényt, akkor mindannyiunknak különböző számsorozata lesz.
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')
long() függvény
Sok esetben szeretnénk tudni a hossz egy vektor számításhoz vagy for ciklusban való felhasználásához. A long() függvény megszámolja az x vektor sorainak számát. A következő kódok importálják az autók adatkészletét, és visszaadják a sorok számát.
Megjegyzések: length() a vektor elemeinek számát adja vissza. Ha a függvényt egy mátrixba vagy egy adatkeretbe adjuk át, akkor az oszlopok száma kerül visszaadásra.
dt <- cars ## number columns length(dt)
output:
## [1] 1
## number rows length(dt[,1])
output:
## [1] 50
Matematikai függvények
R-nek matematikai függvényei vannak.
Operator | Leírás |
---|---|
abs (x) | Felveszi x abszolút értékét |
log(x,bázis=y) | Felveszi x logaritmusát y bázissal; ha a bázis nincs megadva, akkor a természetes logaritmust adja vissza |
exp (x) | Az x exponenciálisát adja eredményül |
sqrt (x) | Az x négyzetgyökét adja eredményül |
faktoriális(x) | Visszaadja x faktoriálisát (x!) |
# sequence of number from 44 to 55 both including incremented by 1 x_vector <- seq(45,55, by = 1) #logarithm log(x_vector)
output:
## [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)
output:
## [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)
output:
## [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
Statisztikai függvények
Az R szabványos telepítés statisztikai funkciók széles skáláját tartalmazza. Ebben az oktatóanyagban röviden áttekintjük a legfontosabb funkciót.
Alapvető statisztikai függvények
Operator | Leírás |
---|---|
átlag(x) | x átlaga |
medián(x) | x mediánja |
var(x) | x szórása |
sd(x) | x szórása |
skála (x) | x standard pontszámai (z-pontszámai). |
kvantilis(x) | x kvartilisei |
összefoglaló(x) | x összegzése: átlag, min, max stb. |
speed <- dt$speed speed # Mean speed of cars dataset mean(speed)
output:
## [1] 15.4
# Median speed of cars dataset median(speed)
output:
## [1] 15
# Variance speed of cars dataset var(speed)
output:
## [1] 27.95918
# Standard deviation speed of cars dataset sd(speed)
output:
## [1] 5.287644
# Standardize vector speed of cars dataset head(scale(speed), 5)
output:
## [,1] ## [1,] -2.155969 ## [2,] -2.155969 ## [3,] -1.588609 ## [4,] -1.588609 ## [5,] -1.399489
# Quantile speed of cars dataset quantile(speed)
output:
## 0% 25% 50% 75% 100% ## 4 12 15 19 25
# Summary speed of cars dataset summary(speed)
output:
## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 4.0 12.0 15.0 15.4 19.0 25.0
Eddig a pontig rengeteg R beépített függvényt tanultunk meg.
Megjegyzések: Legyen óvatos az argumentum osztályával, azaz numerikus, logikai vagy karakterlánccal. Például, ha egy karakterlánc értéket kell átadnunk, akkor a karakterláncot idézőjelbe kell tennünk: „ABC” .
Írja be a függvényt R-be
Bizonyos esetekben meg kell írnunk saját függvényünket, mert egy adott feladatot kell végrehajtanunk, és nincs kész függvény. A felhasználó által definiált függvény magában foglalja a név, érvek és egy test.
function.name <- function(arguments) { computations on the arguments some other code }
Megjegyzések: Jó gyakorlat az, ha egy felhasználó által definiált függvényt másként nevezünk el, mint egy beépített függvényt. Ez elkerüli a zavart.
Egy argumentumfüggvény
A következő részletben egy egyszerű négyzetfüggvényt definiálunk. A függvény elfogad egy értéket, és az érték négyzetét adja vissza.
square_function<- function(n) { # compute the square of integer `n` n^2 } # calling the function and passing value 4 square_function(4)
Kód Magyarázat
- A függvény neve négyzet_függvény; nevezhetjük annak, aminek akarjuk.
- „n” argumentumot kap. Mi nem adta meg a változó típusát, hogy a felhasználó egész számot, vektort vagy mátrixot átadhasson
- A függvény veszi az „n” bemenetet, és visszaadja a bemenet négyzetét. Ha végzett a függvény használatával, az rm() függvénnyel eltávolíthatjuk.
# a függvény létrehozása után
rm(square_function) square_function
A konzolon hibaüzenetet láthatunk: Error: a 'square_function' objektum nem található, ami azt jelzi, hogy a függvény nem létezik.
Környezeti hatókör
R-ben a környezet egy olyan gyűjtemény objektumok, például függvények, változók, adatkeret stb.
Az R minden alkalommal megnyit egy környezetet, amikor az Rstudio kéri.
Az elérhető legfelső szintű környezet a globális környezet, az úgynevezett R_GlobalEnv. És megvan a helyi környezet.
Felsorolhatjuk az aktuális környezet tartalmát.
ls(environment())
teljesítmény
## [1] "diff_ts" "dt" "speed" "square_function" ## [5] "ts" "x" "x_vector"
Az R_GlobalEnv-ben létrehozott összes változót és függvényt láthatja.
A fenti lista az R Studio programban végrehajtott előzménykódtól függően változhat.
Jegyezzük meg, hogy n, a négyzetfüggvény argumentuma a következő nem ebben a globális környezetben.
A új környezet jön létre minden egyes funkcióhoz. A fenti példában a square_function() függvény új környezetet hoz létre a globális környezetben.
Hogy tisztázzuk a különbséget globális és a helyi környezet, tanulmányozzuk a következő példát
Ezek a függvények egy x értéket vesznek fel argumentumként, és hozzáadják az y definícióhoz a függvényen kívül és belül
Az f függvény a 15-ös kimenetet adja vissza. Ennek az az oka, hogy y a globális környezetben van definiálva. A globális környezetben definiált bármely változó lokálisan használható. Az y változó értéke 10 minden függvényhívás során, és bármikor elérhető.
Nézzük meg, mi történik, ha az y változót a függvényen belül definiáljuk.
El kell dobnunk az "y"-t, mielőtt ezt a kódot rm r használatával futtatnánk
A kimenet akkor is 15, ha meghívjuk az f(5)-et, de hibát ad vissza, amikor megpróbáljuk kinyomtatni az y értéket. Az y változó nincs a globális környezetben.
Végül az R a legfrissebb változódefiníciót használja a függvény törzsén belüli áthaladáshoz. Tekintsük a következő példát:
R figyelmen kívül hagyja a függvényen kívül definiált y értékeket, mert a függvény törzsében kifejezetten létrehoztunk egy ay változót.
Több argumentum funkció
Egy függvényt több argumentummal is írhatunk. Tekintsük a „time” nevű függvényt. Ez egy egyszerű függvény, amely két változót megszoroz.
times <- function(x,y) { x*y } times(2,4)
output:
## [1] 8
Mikor írjunk függvényt?
Az adatkutatóknak sok ismétlődő feladatot kell elvégezniük. Legtöbbször ismétlődően másolunk és illesztünk be kódrészleteket. Például egy változó normalizálása erősen ajánlott az a futtatása előtt gépi tanulás algoritmus. A változó normalizálásának képlete a következő:
Már tudjuk, hogyan kell használni a min() és max() függvényt az R-ben. Az adatkeret létrehozásához a tibble könyvtárat használjuk. A Tibble eddig a legkényelmesebb funkció egy adatkészlet létrehozásához a semmiből.
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), )
Két lépésben folytatjuk a fent leírt függvény kiszámítását. Első lépésben létrehozunk egy c1_norm nevű változót, amely a c1 átskálázása. A második lépésben csak másoljuk és illesszük be a c1_norm kódját, és változtassuk meg c2-vel és c3-mal.
A függvény részlete a c1 oszloppal:
Jelölő: : data_frame$c1 -min(data_frame$c1))
Nevező: max(data_frame$c1)-min(data_frame$c1))
Ezért feloszthatjuk őket, hogy megkapjuk a c1 oszlop normalizált értékét:
(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
Létrehozhatunk c1_norm, c2_norm és 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)
output:
## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991
Működik. Másolhatjuk és beilleszthetjük
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
majd módosítsa a c1_normát c2_norm-ra, a c1-et pedig c2-re. Ugyanezt tesszük a c3_norm létrehozásához
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))
Tökéletesen átskáláztuk a c1, c2 és c3 változókat.
Ez a módszer azonban hajlamos a tévedésre. Másolhatnánk, és a beillesztés után elfelejthetjük megváltoztatni az oszlop nevét. Ezért jó gyakorlat az, ha minden alkalommal írunk egy függvényt, amikor ugyanazt a kódot kétszer kell beilleszteni. Átrendezhetjük a kódot képletté, és bármikor meghívhatjuk, amikor szükség van rá. Saját függvény írásához meg kell adnunk:
- Név: normalizál.
- argumentumok száma: Csak egy argumentumra van szükségünk, ez az az oszlop, amelyet a számításunkban használunk.
- A test: egyszerűen ezt a képletet szeretnénk visszaadni.
Lépésről lépésre haladva létrehozzuk a függvény normalizálását.
Step 1) Mi létrehozzuk a nevező, ami . Az R-ben a nevezőt egy ilyen változóban tárolhatjuk:
nominator <- x-min(x)
Step 2) Kiszámoljuk a névadó: . Az 1. lépés ötletét megismételhetjük, és a számítást egy változóban tárolhatjuk:
denominator <- max(x)-min(x)
Step 3) Elvégezzük a nevező és nevező közötti felosztást.
normalize <- nominator/denominator
Step 4) Ahhoz, hogy értéket adjunk vissza a hívó függvénynek, át kell adnunk a normalize-t a return() belsejében, hogy megkapjuk a függvény kimenetét.
return(normalize)
Step 5) Készen állunk a funkció használatára, ha mindent a tartóba csomagolunk.
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) }
Teszteljük a függvényünket a c1 változóval:
normalize(data_frame$c1)
Tökéletesen működik. Létrehoztuk első funkciónkat.
A funkciók átfogóbb módjai az ismétlődő feladatok végrehajtásának. Használhatjuk a normalizálási képletet különböző oszlopokban, például az alábbiakban:
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)
Annak ellenére, hogy a példa egyszerű, következtethetünk egy képlet erejére. A fenti kód könnyebben olvasható, és különösen elkerülhető a hibák a kódok beillesztése során.
Feltételekkel működik
Néha feltételeket kell beépítenünk egy függvénybe, hogy a kód különböző kimeneteket adjon vissza.
A Machine Learning feladatokban fel kell osztanunk az adatkészletet egy vonatkészlet és egy tesztkészlet között. A vonatkészlet lehetővé teszi, hogy az algoritmus tanuljon az adatokból. Modellünk teljesítményének teszteléséhez használhatjuk a tesztkészletet a teljesítménymérés visszaadásához. Az R-nek nincs két adatkészlet létrehozására szolgáló funkciója. Ehhez megírhatjuk saját függvényünket. A függvényünk két argumentumot vesz fel, és a neve split_data(). Az ötlet egyszerű, az adathalmaz hosszát (azaz a megfigyelések számát) megszorozzuk 0.8-cal. Például, ha az adatkészletet 80/20 arányban akarjuk felosztani, és az adatkészletünk 100 sort tartalmaz, akkor a függvényünk 0.8*100 = 80-at szoroz. 80 sor kerül kiválasztásra a képzési adatokká.
A levegőminőségi adatkészletet használjuk a felhasználó által definiált funkciónk tesztelésére. A levegőminőségi adatkészlet 153 sorból áll. Az alábbi kóddal láthatjuk:
nrow(airquality)
output:
## [1] 153
A következőképpen járunk el:
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
A függvényünknek két argumentuma van. Az argumentumsor egy logikai paraméter. Ha IGAZ-ra van állítva, akkor a függvényünk létrehozza a vonatadatkészletet, ellenkező esetben a tesztadatkészletet.
Ugyanúgy járhatunk el, mint a normalise() függvénynél. A kódot úgy írjuk meg, mintha csak egyszeri kód lenne, majd mindent a feltétellel a törzsbe csomagolunk, hogy létrehozzuk a függvényt.
Lépés 1:
Ki kell számolnunk az adathalmaz hosszát. Ez az nrow() függvénnyel történik. A Nrow az adatkészletben lévő sorok teljes számát adja vissza. A változó hosszúságot hívjuk.
length<- nrow(airquality) length
output:
## [1] 153
Lépés 2:
A hosszt megszorozzuk 0.8-al. Visszaadja a kiválasztandó sorok számát. 153*0.8 = 122.4 legyen
total_row <- length*0.8 total_row
output:
## [1] 122.4
122 sort szeretnénk kiválasztani a levegőminőségi adatkészlet 153 sorából. Létrehozunk egy listát, amely 1 és total_row közötti értékeket tartalmaz. Az eredményt a split nevű változóban tároljuk
split <- 1:total_row split[1:5]
output:
## [1] 1 2 3 4 5
A split az első 122 sort választja ki az adatkészletből. Például láthatjuk, hogy a változó felosztásunk az 1, 2, 3, 4, 5 és így tovább értékeket gyűjti össze. Ezek az értékek lesznek az indexek, amikor kiválasztjuk a visszaadandó sorokat.
Lépés 3:
Ki kell választanunk a levegőminőségi adatkészlet sorait az osztott változóban tárolt értékek alapján. Ez így történik:
train_df <- airquality[split, ] head(train_df)
output:
##[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
Lépés 4:
A tesztadatkészletet a fennmaradó sorok 123:153 felhasználásával hozhatjuk létre. Ez a – split előtti használatával történik.
test_df <- airquality[-split, ] head(test_df)
output:
##[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
Lépés 5:
A feltételt a függvény törzsén belül tudjuk létrehozni. Ne feledje, hogy van egy argumentumsorunk, amely alapértelmezés szerint egy logikai érték IGAZ értékre van állítva, hogy visszaadja a vonatkészletet. A feltétel létrehozásához az if szintaxist használjuk:
if (train ==TRUE){ train_df <- airquality[split, ] return(train) } else { test_df <- airquality[-split, ] return(test) }
Ez az, felírhatjuk a függvényt. Csak a levegőminőséget kell df-re módosítanunk, mert ki akarjuk próbálni a funkciónkat bármelyiken adatkeret, nem csak a levegőminőség:
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) } }
Próbáljuk ki a funkciónkat a levegőminőségi adatkészleten. legyen egy 122 soros vonatkészletünk és egy 31 soros tesztkészletünk.
train <- split_data(airquality, train = TRUE) dim(train)
output:
## [1] 122 6
test <- split_data(airquality, train = FALSE) dim(test)
output:
## [1] 31 6