Funktioner i R-programmering med eksempel
โก Smart opsummering
Funktioner i R pakker et sรฆt instruktioner under รฉt navn, sรฅ en gentagen opgave kรธrer fra et enkelt kald. Indbyggede matematik- og statistikhjรฆlpere, brugerdefinerede funktioner, miljรธ scoping, og betingede argumenter er dรฆkket her med udtรฆnkte eksempler.

Hvad er en funktion i R?
A funktion, i et programmeringsmiljรธ, er et sรฆt instruktioner. En programmรธr bygger en funktion, der skal undgรฅs gentagelse af den samme opgaveeller reducere kompleksitet.
En funktion skal vรฆre
- skrevet for at udfรธre en bestemt opgave
- kan eller kan ikke indeholde argumenter
- indeholde en krop
- kan returnere en eller flere vรฆrdier eller ej.
En generel tilgang til en funktion er at bruge argumentdelen som indgange, fodre krop del og til sidst returnere en output. Syntaksen for en funktion er fรธlgende:
function (arglist) { #Function body }
R vigtige indbyggede funktioner
Der er mange indbyggede funktioner i R. R matcher dine inputparametre med dets funktionsargumenter, enten efter vรฆrdi eller efter position, og udfรธrer derefter funktionskroppen. Funktionsargumenter kan have standardvรฆrdier: Hvis du ikke angiver disse argumenter, vil R tage standardvรฆrdien.
Bemรฆrk:
Det er muligt at se kildekoden til en funktion ved at kรธre navnet pรฅ selve funktionen i konsollen.
Typing Et funktionsnavn uden parenteser udskriver sin kildekode, som konsollen nedenfor viser.
Vi vil se tre grupper af funktioner i aktion
- Generel funktion
- Matematik funktion
- Statistisk funktion
Generelle funktioner
Vi er allerede bekendt med generelle funktioner som cbind(), rbind(), range(), sortere(), og order(). Hver af disse funktioner har en specifik opgave, tager argumenter for at returnere et output. Fรธlgende er vigtige funktioner, man skal kende -
diff() funktion
Hvis du arbejder pรฅ tidsserier, skal du stationรฆre serien ved at tage deres lag vรฆrdier. En stationรฆr proces tillader konstant middelvรฆrdi, varians og autokorrelation over tid. Dette forbedrer primรฆrt forudsigelsen af โโen tidsserie. Dette kan gรธres med diff()-funktionen. Vi kan opbygge tilfรฆldige tidsseriedata med en trend og derefter bruge funktionen diff() til at stationรฆre serien. Diff()-funktionen accepterer รฉt argument, en vektor, og returnerer en passende lagget og itereret differens.
BemรฆrkVi har ofte brug for at oprette tilfรฆldige data, men til lรฆring og sammenligning รธnsker vi, at tallene er identiske pรฅ tvรฆrs af maskiner. For at sikre, at vi alle genererer de samme data, bruger vi funktionen set.seed() med vilkรฅrlige vรฆrdier pรฅ 123. set.seed() fastsรฆtter startpunktet for pseudotilfรฆldige talgeneratoren, sรฅ hver maskine producerer den samme sekvens. Uden set.seed() returnerer hver kรธrsel en forskellig sekvens.
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')
De to paneler nedenfor placerer den oprindelige kumulative serie ved siden af โโden differenterede serie, som nu fluktuerer omkring et konstant gennemsnit.
length() funktion
I mange tilfรฆlde รธnsker vi at kende lรฆngden af โโen vektor til beregning eller til brug i et for-lรธkke. Funktionen length() tรฆller antallet af rรฆkker i vektor x. Fรธlgende koder importerer cars-datasรฆttet og returnerer antallet af rรฆkker.
Bemรฆrklength() returnerer antallet af elementer i en vektor. Hvis funktionen sendes ind i en matrix eller en dataramme, returneres antallet af kolonner.
dt <- cars
## number columns
length(dt)
Output:
## [1] 1
## number rows
length(dt[,1])
Output:
## [1] 50
Matematiske funktioner
Ud over de generelle hjรฆlpere har R en rรฆkke matematiske funktioner, der opererer element for element pรฅ en vektor.
| OperaTor | Beskrivelse |
|---|---|
| abs (x) | Tager den absolutte vรฆrdi af x |
| log(x,base=y) | Tager logaritmen af โโx med grundtallet y; hvis base ikke er angivet, returnerer den naturlige logaritme |
| exp (x) | Returnerer eksponentialet af x |
| sqrt (x) | Returnerer kvadratroden af โโx |
| fakultet (x) | Returnerer fakultetet af 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)
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
Statistiske funktioner
Hvor de matematiske funktioner transformerer vรฆrdier, opsummerer de statistiske funktioner dem. Standardinstallationen af โโR indeholder en bred vifte af statistiske funktioner. I denne vejledning vil vi kort se pรฅ de vigtigste.
Grundlรฆggende statistikfunktioner
| OperaTor | Beskrivelse |
|---|---|
| middel(x) | Gennemsnit af x |
| median(x) | Medianen af โโx |
| var(x) | Varians af x |
| sd(x) | Standardafvigelse af x |
| skala (x) | Standardscore (z-score) af x |
| kvantil (x) | Kvartilerne af x |
| resumรฉ(x) | Sammenfatning af x: middel, min, max osv.. |
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
Indtil nu har vi lรฆrt en masse R indbyggede funktioner.
BemรฆrkVรฆr forsigtig med argumentets klasse, dvs. numerisk, boolsk eller streng. Hvis vi for eksempel skal sende en strengvรฆrdi, skal vi omslutte strengen i anfรธrselstegn: โABCโ.
Skrivefunktion i R
I nogle tilfรฆlde er vi nรธdt til at skrive vores egen funktion, fordi vi skal udfรธre en bestemt opgave, og der ikke findes nogen fรฆrdiglavet funktion. En brugerdefineret funktion involverer en navn, argumenter og en krop.
function.name <- function(arguments) { computations on the arguments some other code }
Bemรฆrk: En god praksis er at navngive en brugerdefineret funktion anderledes end en indbygget funktion. Det undgรฅr forvirring.
En argumentfunktion
I det nรฆste uddrag definerer vi en simpel kvadratisk funktion. Funktionen accepterer en vรฆrdi og returnerer kvadratet af vรฆrdien.
square_function<- function(n) { # compute the square of integer `n` n^2 } # calling the function and passing value 4 square_function(4)
Code Forklaring
- Funktionen hedder square_function; det kan hedde hvad vi vil.
- Den modtager et argument "n". Vi specificerede ikke typen af โโvariabel, sรฅ brugeren kan sende et heltal, en vektor eller en matrix
- Funktionen tager input "n" og returnerer kvadratet af input. Nรฅr du er fรฆrdig med at bruge funktionen, kan vi fjerne den med rm()-funktionen.
# efter du har oprettet funktionen
rm(square_function) square_function
Pรฅ konsollen kan vi se en fejlmeddelelse: Fejl: objektet 'square_function' blev ikke fundet, der fortรฆller, at funktionen ikke eksisterer.
Miljรธ Scoping
I R, den miljรธ er en samling af objekter som funktioner, variabler, dataframes osv.
R รฅbner et miljรธ hver gang RStudio startes.
Det tilgรฆngelige miljรธ pรฅ รธverste niveau er globale miljรธ, kaldet R_GlobalEnv. Og vi har lokalmiljรธ.
Vi kan liste indholdet af det aktuelle miljรธ.
ls(environment())
Produktion
## [1] "diff_ts" "dt" "speed" "square_function" ## [5] "ts" "x" "x_vector"
Du kan se alle variabler og funktioner oprettet i R_GlobalEnv.
Ovenstรฅende liste vil variere for dig baseret pรฅ den historiske kode, du udfรธrer i RStudio.
Bemรฆrk, at n, argumentet for funktionen square_function er ikke i dette globale miljรธ.
Der oprettes et nyt miljรธ for hver funktion. I ovenstรฅende eksempel opretter funktionen square_function() et nyt miljรธ indeni globale miljรธ.
For at tydeliggรธre forskellen mellem global og lokale miljรธ, lad os studere fรธlgende eksempel
Disse funktioner tager en vรฆrdi x som et argument og tilfรธjer den til y definere uden for og inde i funktionen
Funktionen f returnerer output 15. Dette skyldes, at y er defineret i det globale miljรธ. Enhver variabel defineret i det globale miljรธ kan bruges lokalt. Variablen y har vรฆrdien 10 under alle funktionskald og er tilgรฆngelig til enhver tid.
Lad os se, hvad der sker, hvis variablen y er defineret inde i funktionen.
Vi er nรธdt til at slippe "y", fรธr vi kรธrer denne kode ved hjรฆlp af rm r
Outputtet er ogsรฅ 15, nรฅr vi kalder f(5), men returnerer en fejl, nรฅr vi forsรธger at udskrive vรฆrdien y. Variablen y er ikke i det globale miljรธ.
Endelig bruger R den seneste variabeldefinition til at passere inde i en funktions krop. Lad os overveje fรธlgende eksempel:
R ignorerer y-vรฆrdierne defineret uden for funktionen, fordi vi eksplicit oprettede en ay-variabel inde i funktionens krop.
Multi argument funktion
Vi kan skrive en funktion med mere end et argument. Overvej funktionen kaldet "tider". Det er en ligetil funktion, der multiplicerer to variable.
times <- function(x,y) {
x*y
}
times(2,4)
Output:
## [1] 8
Hvornรฅr skal vi skrive funktion?
Dataforskere skal udfรธre mange gentagne opgaver. For det meste kopierer og indsรฆtter vi kodestykker gentagne gange. For eksempel anbefales normalisering af en variabel kraftigt, fรธr vi kรธrer en machine learning algoritme. Formlen til at normalisere en variabel er:
Vi ved allerede, hvordan man bruger funktionen min() og max() i R. Vi bruger tibble-biblioteket til at oprette datarammen. Tibble er indtil videre den mest bekvemme funktion til at oprette et datasรฆt fra bunden.
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), )
Vi vil fortsรฆtte i to trin for at beregne funktionen beskrevet ovenfor. I det fรธrste trin opretter vi en variabel kaldet c1_norm, som er en reskalering af c1. I trin to kopierer og indsรฆtter vi blot koden for c1_norm og รฆndrer den med c2 og c3.
Detalje af funktionen med kolonnen c1:
Nominator: : data_frame$c1 -min(data_frame$c1))
Nรฆvner: max(data_frame$c1)-min(data_frame$c1))
Derfor kan vi dividere dem for at fรฅ den normaliserede vรฆrdi af kolonne c1:
(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
Vi kan oprette c1_norm, c2_norm og 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
Det virker. Vi kan kopiere og indsรฆtte
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
skift derefter c1_norm til c2_norm og c1 til c2. Vi gรธr det samme for at skabe 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))
Vi omskalerede variablerne c1, c2 og c3 perfekt.
Denne metode er dog tilbรธjelig til at forรฅrsage fejl. Vi kan kopiere og glemme at รฆndre kolonnenavnet efter indsรฆttelse. Derfor er det en god praksis at skrive en funktion, hver gang du skal indsรฆtte den samme kode mere end to gange. Vi kan omarrangere koden til en formel og kalde den, nรฅr det er nรธdvendigt. For at skrive vores egen funktion skal vi give:
- Navn: normalisering.
- antallet af argumenter: Vi behรธver kun et argument, som er den kolonne, vi bruger i vores beregning.
- Kroppen: dette er simpelthen den formel, vi รธnsker at returnere.
Vi vil fortsรฆtte trin for trin for at oprette funktionen normalisere.
Trin 1) Vi opretter nominatoren, som er x โ min(x). I R kan vi gemme nominatoren i en variabel som denne:
nominator <- x-min(x)
Trin 2) Vi beregner nรฆvneren: max(x) โ min(x). Vi kan gentage ideen fra trin 1 og gemme beregningen i en variabel:
denominator <- max(x)-min(x)
Trin 3) Vi udfรธrer opdelingen mellem nรฆvner og nรฆvner.
normalize <- nominator/denominator
Trin 4) For at returnere vรฆrdi til kaldende funktion skal vi sende normalize inde i return() for at fรฅ output fra funktionen.
return(normalize)
Trin 5) Vi er klar til at bruge funktionen ved at wrapping alt inden for parentesen.
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) }
Lad os teste vores funktion med variablen c1:
normalize(data_frame$c1)
Det fungerer perfekt. Vi lavede vores fรธrste funktion.
En funktion er en mere omfattende mรฅde at udfรธre en gentagen opgave pรฅ. Vi kan bruge normaliseringsformlen over forskellige kolonner, som vist nedenfor:
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)
Selvom eksemplet er simpelt, kan vi udlede en formels styrke. Ovenstรฅende kode er lettere at lรฆse og undgรฅr de fejl, der opstรฅr ved indsรฆttelse af kode.
Fungerer med stand
Funktionen normalize() gรธr altid det samme. Nogle gange er vi nรธdt til at inkludere betingelser i en funktion for at tillade koden at returnere forskellige output.
I Machine Learning-opgaver skal vi opdele datasรฆttet mellem et togsรฆt og et testsรฆt. Togsรฆttet gรธr det muligt for algoritmen at lรฆre af dataene. For at teste vores models ydeevne kan vi bruge testsรฆttet til at returnere ydeevnemรฅlet. R har ikke en funktion til at oprette to datasรฆt. Vi kan skrive vores egen funktion til at gรธre det. Vores funktion tager to argumenter og kaldes split_data(). Ideen bag er enkel, vi multiplicerer lรฆngden af โโdatasรฆttet (dvs. antallet af observationer) med 0.8. For eksempel, hvis vi รธnsker at opdele datasรฆttet 80/20, og vores datasรฆt indeholder 100 rรฆkker, sรฅ vil vores funktion gange 0.8*100 = 80. 80 rรฆkker vil blive udvalgt til at blive vores trรฆningsdata.
Vi vil bruge luftkvalitetsdatasรฆttet til at teste vores brugerdefinerede funktion. Luftkvalitetsdatasรฆttet har 153 rรฆkker. Vi kan se det med koden nedenfor:
nrow(airquality)
Output:
## [1] 153
Vi fortsรฆtter som fรธlger:
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
Vores funktion har to argumenter. Argumenttoget er en boolesk parameter. Hvis den er sat til TRUE, opretter vores funktion togdatasรฆttet, ellers opretter den testdatasรฆttet.
Vi kan fortsรฆtte, som vi gjorde med normalize()-funktionen. Vi skriver koden, som om det kun var engangskode, og derefter pakker vi alt med betingelsen ind i kroppen for at oprette funktionen.
Trin 1:
Vi skal beregne lรฆngden af โโdatasรฆttet. Dette gรธres med funktionen nrow(). Nrow returnerer det samlede antal rรฆkker i datasรฆttet. Vi kalder den variable lรฆngde.
length<- nrow(airquality) length
Output:
## [1] 153
Trin 2:
Vi gange lรฆngden med 0.8. Det vil returnere antallet af rรฆkker at vรฆlge. Det skal vรฆre 153*0.8 = 122.4
total_row <- length*0.8 total_row
Output:
## [1] 122.4
Vi รธnsker at vรฆlge 122 rรฆkker blandt de 153 rรฆkker i luftkvalitetsdatasรฆttet. Vi opretter en liste med vรฆrdier fra 1 til total_row. Vi gemmer resultatet i den variabel kaldet split
split <- 1:total_row split[1:5]
Output:
## [1] 1 2 3 4 5
split vรฆlger de fรธrste 122 rรฆkker fra datasรฆttet. For eksempel kan vi se, at vores variabelopdeling samler vรฆrdierne 1, 2, 3, 4, 5 og sรฅ videre. Disse vรฆrdier vil vรฆre indekset, nรฅr vi vรฆlger de rรฆkker, der skal returneres.
Trin 3:
Vi skal vรฆlge rรฆkkerne i luftkvalitetsdatasรฆttet baseret pรฅ de vรฆrdier, der er gemt i splitvariablen. Dette gรธres sรฅdan:
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
Trin 4:
Vi kan oprette testdatasรฆttet ved at bruge de resterende rรฆkker, 123:153. Dette gรธres ved at bruge โ foran split.
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
Trin 5:
Vi kan skabe tilstanden inde i funktionens krop. Husk, vi har et argumenttog, der er et boolesk sรฆt til TRUE som standard for at returnere togsรฆttet. For at oprette betingelsen bruger vi if-syntaksen:
if (train ==TRUE){ train_df <- airquality[split, ] return(train) } else { test_df <- airquality[-split, ] return(test) }
Dette er det, vi kan skrive funktionen. Vi skal kun รฆndre luftkvaliteten til df, fordi vi vil prรธve vores funktion til evt dataramme, ikke kun luftkvalitet:
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) } }
Lad os prรธve vores funktion pรฅ luftkvalitetsdatasรฆttet. Vi burde have รฉt togsรฆt med 122 rรฆkker og et testsรฆt med 31 rรฆkker.
train <- split_data(airquality, train = TRUE)
dim(train)
Output:
## [1] 122 6
test <- split_data(airquality, train = FALSE)
dim(test)
Output:
## [1] 31 6






