Functies in R-programmering met voorbeeld
Wat is een functie in R?
A functie, in een programmeeromgeving, is een reeks instructies. Een programmeur bouwt een functie om te vermijden het herhalen van de dezelfde taak, of verminderen complexiteit.
Een functie zou moeten zijn
- geschreven om bepaalde taken uit te voeren
- kan wel of geen argumenten bevatten
- een lichaam bevatten
- kan wel of niet een of meer waarden retourneren.
Een algemene benadering van een functie is om het argumentgedeelte as te gebruiken ingangen, Eten geven aan lichaam deel en uiteindelijk een terug uitvoerDe syntaxis van een functie is als volgt:
function (arglist) { #Function body }
R belangrijke ingebouwde functies
Er zijn veel ingebouwde functies in R. R matcht uw invoerparameters met zijn functieargumenten, hetzij op waarde of op positie, en voert vervolgens de hoofdtekst van de functie uit. Functieargumenten kunnen standaardwaarden hebben: als u deze argumenten niet opgeeft, zal R de standaardwaarde aannemen.
Note:
Het is mogelijk om de broncode van een functie te zien door de naam van de functie zelf in de console uit te voeren.
We zullen drie groepen functies in actie zien
- Algemene functie
- Wiskundige functie
- Statistische functie
Algemene functies
We zijn al bekend met algemene functies zoals cbind(), rbind(), range(), sort(), order() functies. Elk van deze functies heeft een specifieke taak, neemt argumenten om een output te retourneren. Hieronder staan belangrijke functies die men moet kennen-
diff()-functie
Als je werkt aan tijdreeksen, je moet de serie stationair maken door hun te nemen lag-waarden. Een stationair proces maakt een constant gemiddelde, variantie en autocorrelatie in de loop van de tijd mogelijk. Dit verbetert vooral de voorspelling van een tijdreeks. Dit kan eenvoudig worden gedaan met de functie diff(). We kunnen willekeurige tijdreeksgegevens met een trend opbouwen en vervolgens de functie diff() gebruiken om de reeks stationair te maken. De functie diff() accepteert één argument, een vector, en retourneert een geschikt vertraagd en herhaald verschil.
Note: We moeten vaak willekeurige gegevens maken, maar voor leren en vergelijking willen we dat de getallen op alle machines identiek zijn. Om ervoor te zorgen dat we allemaal dezelfde gegevens genereren, gebruiken we de set.seed()-functie met willekeurige waarden van 123. De set.seed()-functie wordt gegenereerd via het proces van pseudorandom number generator die ervoor zorgt dat alle moderne computers dezelfde reeks getallen hebben. Als we de set.seed()-functie niet gebruiken, hebben we allemaal een andere reeks getallen.
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')
lengte() functie
In veel gevallen willen we weten wat de lengte van een vector voor berekening of om te gebruiken in een for-lus. De length()-functie telt het aantal rijen in vector x. De volgende codes importeren de dataset auto's en retourneren het aantal rijen.
Note: lengte() retourneert het aantal elementen in een vector. Als de functie wordt doorgegeven aan een matrix of een gegevensframe, wordt het aantal kolommen geretourneerd.
dt <- cars ## number columns length(dt)
Output:
## [1] 1
## number rows length(dt[,1])
Output:
## [1] 50
Wiskundige functies
R heeft een reeks wiskundige functies.
Operator | Beschrijving |
---|---|
buikspieren (x) | Neemt de absolute waarde van x |
log(x,basis=y) | Neemt de logaritme van x met grondtal y; als grondtal niet is opgegeven, retourneert de natuurlijke logaritme |
exp(x) | Geeft de exponentiële waarde van x |
sqrt (x) | Retourneert de vierkantswortel van x |
faculteit(x) | Geeft de faculteit van 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
Statistische functies
De standaardinstallatie van R bevat een breed scala aan statistische functies. In deze tutorial bekijken we kort de belangrijkste functie.
Basisstatistische functies
Operator | Beschrijving |
---|---|
gemiddelde(x) | Gemiddelde van x |
mediaan(x) | Mediaan van x |
var(x) | Variantie van x |
sd(x) | Standaardafwijking van x |
schaal(x) | Standaardscores (z-scores) van x |
kwantiel(x) | De kwartielen van x |
samenvatting(x) | Samenvatting van x: gemiddelde, min, max etc.. |
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
Tot nu toe hebben we veel ingebouwde R-functies geleerd.
Note: Wees voorzichtig met de klasse van het argument, dat wil zeggen numeriek, Booleaans of string. Als we bijvoorbeeld een tekenreekswaarde moeten doorgeven, moeten we de tekenreeks tussen aanhalingstekens plaatsen: “ABC” .
Schrijffunctie in R
In sommige gevallen moeten we onze eigen functie schrijven omdat we een bepaalde taak moeten volbrengen en er geen kant-en-klare functie bestaat. Een door de gebruiker gedefinieerde functie omvat a naam, argumenten en lichaam.
function.name <- function(arguments) { computations on the arguments some other code }
Note: Het is een goede gewoonte om een door de gebruiker gedefinieerde functie een andere naam te geven dan een ingebouwde functie. Het voorkomt verwarring.
Eén argumentfunctie
In het volgende fragment definiëren we een eenvoudige vierkante functie. De functie accepteert een waarde en retourneert het kwadraat van de waarde.
square_function<- function(n) { # compute the square of integer `n` n^2 } # calling the function and passing value 4 square_function(4)
Code Uitleg
- De functie heet vierkante_functie; het kan worden genoemd wat we willen.
- Het ontvangt een argument “n”. Wij heeft het type variabele niet gespecificeerd, zodat de gebruiker een geheel getal, een vector of een matrix kan doorgeven
- De functie neemt de invoer “n” en retourneert het kwadraat van de invoer. Wanneer u klaar bent met het gebruik van de functie, kunnen we deze verwijderen met de functie rm().
# nadat u de functie hebt gemaakt
rm(square_function) square_function
Op de console kunnen we een foutmelding zien: Error: object 'square_function' not found, wat aangeeft dat de functie niet bestaat.
Omgevingsonderzoek
In R, de milieu is een Collectie van objecten zoals functies, variabelen, dataframe, enz.
R opent een omgeving telkens wanneer Rstudio daarom wordt gevraagd.
De beschikbare omgeving op het hoogste niveau is de mondiale milieu, genaamd R_GlobalEnv. En wij hebben de Lokale omgeving.
We kunnen de inhoud van de huidige omgeving vermelden.
ls(environment())
uitgang
## [1] "diff_ts" "dt" "speed" "square_function" ## [5] "ts" "x" "x_vector"
U kunt alle variabelen en functies zien die zijn gemaakt in R_GlobalEnv.
De bovenstaande lijst varieert voor u op basis van de historische code die u uitvoert in R Studio.
Merk op dat n het argument van de vierkante functie is niet in deze mondiale omgeving.
A nieuwe Voor elke functie wordt een omgeving gecreëerd. In het bovenstaande voorbeeld creëert de functie square_function() een nieuwe omgeving binnen de globale omgeving.
Om het verschil tussen te verduidelijken globaal en Lokale omgevingLaten we het volgende voorbeeld eens bestuderen
Deze functie neemt een waarde x als argument en voegt deze toe aan de y-definitie buiten en binnen de functie
De functie f retourneert de uitvoer 15. Dit komt omdat y is gedefinieerd in de mondiale omgeving. Elke variabele die in de globale omgeving is gedefinieerd, kan lokaal worden gebruikt. De variabele y heeft bij alle functieaanroepen de waarde 10 en is op elk moment toegankelijk.
Laten we eens kijken wat er gebeurt als de variabele y binnen de functie wordt gedefinieerd.
We moeten `y` verwijderen voordat we deze code kunnen uitvoeren met rm r
De uitvoer is ook 15 als we f(5) aanroepen, maar geeft een foutmelding als we de waarde y proberen af te drukken. De variabele y bevindt zich niet in de mondiale omgeving.
Ten slotte gebruikt R de meest recente variabeledefinitie om door te geven in de body van een functie. Laten we het volgende voorbeeld bekijken:
R negeert de y-waarden die buiten de functie zijn gedefinieerd, omdat we expliciet een variabele binnen de hoofdtekst van de functie hebben gemaakt.
Functie voor meerdere argumenten
We kunnen een functie schrijven met meer dan één argument. Beschouw de functie genaamd “tijden”. Het is een eenvoudige functie die twee variabelen vermenigvuldigt.
times <- function(x,y) { x*y } times(2,4)
Output:
## [1] 8
Wanneer moeten we functie schrijven?
Datawetenschappers moeten veel repetitieve taken uitvoeren. Meestal kopiëren en plakken we stukjes code herhaaldelijk. Het normaliseren van een variabele wordt bijvoorbeeld ten zeerste aanbevolen voordat we a uitvoeren machine learning algoritme. De formule om een variabele te normaliseren is:
We weten al hoe we de functies min() en max() in R moeten gebruiken. We gebruiken de tibble-bibliotheek om het dataframe te maken. Tibble is tot nu toe de handigste functie om een dataset helemaal opnieuw te creëren.
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), )
We gaan in twee stappen te werk om de hierboven beschreven functie te berekenen. In de eerste stap zullen we een variabele creëren met de naam c1_norm, wat de herschaling van c1 is. In stap twee kopiëren en plakken we gewoon de code van c1_norm en veranderen deze met c2 en c3.
Detail van de functie met de kolom c1:
Nominator: : data_frame$c1 -min(data_frame$c1))
Noemer: max(data_frame$c1)-min(data_frame$c1))
Daarom kunnen we ze verdelen om de genormaliseerde waarde van kolom c1 te krijgen:
(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
We kunnen c1_norm, c2_norm en c3_norm creëren:
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
Het werkt. We kunnen kopiëren en plakken
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
verander vervolgens c1_norm in c2_norm en c1 in c2. We doen hetzelfde om c3_norm te creëren
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))
We hebben de variabelen c1, c2 en c3 perfect opnieuw geschaald.
Deze methode is echter gevoelig voor fouten. We kunnen kopiëren en vergeten de kolomnaam na het plakken te wijzigen. Daarom is het een goede gewoonte om elke keer dat u dezelfde code meer dan twee keer moet plakken, een functie te schrijven. We kunnen de code herschikken in een formule en deze oproepen wanneer dat nodig is. Om onze eigen functie te schrijven, moeten we geven:
- Naam: normaliseren.
- het aantal argumenten: We hebben slechts één argument nodig, namelijk de kolom die we gebruiken in onze berekening.
- Het lichaam: dit is simpelweg de formule die we willen teruggeven.
We gaan stap voor stap te werk om de functie normaliseren te creëren.
Stap 1) Wij creëren de noemer, dat is. In R kunnen we de teller opslaan in een variabele als deze:
nominator <- x-min(x)
Stap 2) Wij berekenen de noemer: . We kunnen het idee van stap 1 repliceren en de berekening opslaan in een variabele:
denominator <- max(x)-min(x)
Stap 3) We voeren de scheiding uit tussen de teller en de noemer.
normalize <- nominator/denominator
Stap 4) Om waarde terug te geven aan de aanroepende functie moeten we normalize doorgeven aan return() om de uitvoer van de functie te krijgen.
return(normalize)
Stap 5) We zijn klaar om de functie te gebruiken door alles in de beugel te wikkelen.
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) }
Laten we onze functie testen met de variabele c1:
normalize(data_frame$c1)
Het werkt perfect. We hebben onze eerste functie gemaakt.
Functies zijn een uitgebreidere manier om een repetitieve taak uit te voeren. We kunnen de normalisatieformule gebruiken voor verschillende kolommen, zoals hieronder:
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)
Hoewel het voorbeeld eenvoudig is, kunnen we de kracht van een formule afleiden. De bovenstaande code is gemakkelijker te lezen en voorkomt vooral fouten bij het plakken van codes.
Functies met voorwaarde
Soms moeten we voorwaarden in een functie opnemen, zodat de code verschillende uitvoer kan retourneren.
Bij Machine Learning-taken moeten we de dataset splitsen tussen een treinset en een testset. Dankzij het treinstel kan het algoritme leren van de gegevens. Om de prestaties van ons model te testen, kunnen we de testset gebruiken om de prestatiemaatstaf terug te geven. R heeft geen functie om twee datasets te creëren. We kunnen daarvoor onze eigen functie schrijven. Onze functie heeft twee argumenten nodig en heet split_data(). Het idee hierachter is eenvoudig: we vermenigvuldigen de lengte van de dataset (dat wil zeggen het aantal observaties) met 0.8. Als we bijvoorbeeld de dataset 80/20 willen splitsen, en onze dataset bevat 100 rijen, dan vermenigvuldigt onze functie 0.8*100 = 80. Er worden 80 rijen geselecteerd om onze trainingsgegevens te worden.
We zullen de luchtkwaliteitsdataset gebruiken om onze door de gebruiker gedefinieerde functie te testen. De luchtkwaliteitdataset bestaat uit 153 rijen. We kunnen het zien met de onderstaande code:
nrow(airquality)
Output:
## [1] 153
Wij gaan als volgt te werk:
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
Onze functie heeft twee argumenten. De argumenten train is een Booleaanse parameter. Als deze is ingesteld op TRUE, maakt onze functie de train-dataset, anders maakt deze de test-dataset.
We kunnen doorgaan zoals we deden met de functie normalise(). We schrijven de code alsof het maar een eenmalige code is en verpakken vervolgens alles met de voorwaarde in de hoofdtekst om de functie te creëren.
Stap 1:
We moeten de lengte van de dataset berekenen. Dit gebeurt met de functie nrow(). Nrow retourneert het totale aantal rijen in de gegevensset. We noemen de variabele lengte.
length<- nrow(airquality) length
Output:
## [1] 153
Stap 2:
We vermenigvuldigen de lengte met 0.8. Het retourneert het aantal te selecteren rijen. Het moet 153*0.8 = 122.4 zijn
total_row <- length*0.8 total_row
Output:
## [1] 122.4
We willen 122 rijen selecteren uit de 153 rijen in de luchtkwaliteitsdataset. We maken een lijst met waarden van 1 tot total_row. Het resultaat slaan we op in de variabele genaamd split
split <- 1:total_row split[1:5]
Output:
## [1] 1 2 3 4 5
split kiest de eerste 122 rijen uit de dataset. We kunnen bijvoorbeeld zien dat onze variabele splitsing de waarden 1, 2, 3, 4, 5 enzovoort verzamelt. Deze waarden zullen de index zijn wanneer we de rijen selecteren die moeten worden geretourneerd.
Stap 3:
We moeten de rijen in de luchtkwaliteitsgegevensset selecteren op basis van de waarden die zijn opgeslagen in de gesplitste variabele. Dit wordt als volgt gedaan:
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
Stap 4:
We kunnen de testgegevensset maken door de resterende rijen te gebruiken, 123:153. Dit wordt gedaan door – vóór de splitsing te gebruiken.
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
Stap 5:
We kunnen de voorwaarde binnen de hoofdtekst van de functie creëren. Houd er rekening mee dat we een argumenttrein hebben die standaard een Booleaanse waarde heeft die is ingesteld op TRUE om de treinset te retourneren. Om de voorwaarde te creëren, gebruiken we de if-syntaxis:
if (train ==TRUE){ train_df <- airquality[split, ] return(train) } else { test_df <- airquality[-split, ] return(test) }
Dit is het, we kunnen de functie schrijven. We hoeven de luchtkwaliteit alleen maar te veranderen in df, omdat we onze functie op iedereen willen uitproberen dataframe, niet alleen luchtkwaliteit:
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) } }
Laten we onze functie op de luchtkwaliteitsdataset uitproberen. we zouden één treinset met 122 rijen moeten hebben en een testset met 31 rijen.
train <- split_data(airquality, train = TRUE) dim(train)
Output:
## [1] 122 6
test <- split_data(airquality, train = FALSE) dim(test)
Output:
## [1] 31 6