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.

R Fontos beépített funkciók

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')

Diff() függvény

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

Környezeti hatókör

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

Környezeti hatókör

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:

Környezeti hatókör

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ő:

Képlet egy változó normalizálására

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