Cursus

Als je overweegt een carrière in data science te starten, geldt: hoe eerder je begint met coderen, hoe beter. Welke programmeertaal je ook kiest om je leerreis mee te beginnen, vroeg of laat krijg je te maken met functies.
Functies zijn een kernconcept in vrijwel elke moderne programmeertaal, waaronder populaire talen in data science zoals Python, Julia en natuurlijk R.
In deze tutorial bekijken we wat R-functies zijn en hoe je ze kunt gebruiken. Door het doel, de syntaxis en de typologie van functies in R te behandelen, krijg je alles wat je nodig hebt om dit cruciale programmeerconcept onder de knie te krijgen. Bovendien maak je kennis met de kunst van het schrijven van functies.
Wat is een functie in R?
In programmeren zijn functies instructies die samen zijn georganiseerd om een specifieke taak uit te voeren. Het idee achter functies is om zelfstandige programma's te maken die je alleen aanroept wanneer ze nodig zijn.
Met functies hoef je niet steeds vanaf nul te beginnen, voorkom je herhaling en verbeter je de robuustheid en leesbaarheid van je code. Daarom is het een goede vuistregel om een functie te maken zodra je verwacht een bepaalde set instructies meer dan twee keer in je code te gebruiken.
Functies kunnen voor eindeloos veel doelen worden ingezet en verschillende vormen aannemen. In het algemeen nemen de meeste functies invoergegevens, verwerken die en geven een resultaat terug. De gegevens waarop de functie werkt, worden aangegeven met de zogenaamde argumenten; die kunnen ook worden gebruikt om te sturen of te wijzigen hoe de functie de taken uitvoert.
Afhankelijk van de herkomst van de functie onderscheiden we in R drie hoofdtypen:
- Ingebouwde functies
- Functies in R-packages
- Door de gebruiker gedefinieerde functies (UDF)
In de volgende secties leggen we de bijzonderheden uit van de verschillende soorten functies die in R beschikbaar zijn.
Ingebouwde functies in R
R is een krachtige programmeertaal met een uitgebreide catalogus aan ingebouwde functies die je altijd kunt aanroepen. Als wiskundig georiënteerde taal bevat R veel functies voor numerieke bewerkingen. Hieronder vind je een lijst met enkele van de handigste:
- print(). Toont een R-object in de R-console
- min(), max(). Berekent het minimum en maximum van een numerieke vector
- sum(). Berekent de som van een numerieke vector
- mean(). Berekent het gemiddelde van een numerieke vector
- range(). Berekent de minimum- en maximumwaarden van een numerieke vector
- str(). Toont de structuur van een R-object
- ncol(). Geeft het aantal kolommen van een matrix of dataframe terug
- length(). Geeft het aantal elementen in een R-object terug, zoals een vector, een lijst of een matrix.
In de onderstaande code zie je hoe eenvoudig het is om deze functies te gebruiken om bepaalde statistieken van een vector te berekenen:
>>> v <- c(1, 3, 0.2, 1.5, 1.7)
>>> print(v)
[1] 1.0 3.0 0.2 1.5 1.7
>>> sum(v)
[1] 7.4
>>> mean(v)
[1] 1.48
>>> length(v)
[1] 5
Je leert R-functies en meer in onze uitgebreide R skill track, die je helpt om te leren coderen als een programmeur.
Functies in R-packages
Hoe talrijk en divers ook, ingebouwde functies zijn niet genoeg voor al het moois dat je met R kunt doen, van het maken van overtuigende data-visualisaties tot het trainen van krachtige machinelearningmodellen.
De overgrote meerderheid van de functies om deze taken uit te voeren is beschikbaar in externe packages of libraries. Packages zijn verzamelingen van R-functies, data en gecompileerde code in een goed gedefinieerd formaat, gemaakt om specifieke functionaliteit toe te voegen. De meeste van deze packages zijn gratis te gebruiken en zijn te vinden in populaire pakketrepositories zoals CRAN, dat momenteel bijna 20.000 bijdragen bevat.
Om de functies in een package te gebruiken, moet je die eerst installeren. Als je bijvoorbeeld stringr wilt installeren, een populair package om met reguliere expressies te werken, kun je de volgende instructie gebruiken:
install.packages('stringr')
Zodra je het hebt geïnstalleerd, laad je het in je R-omgeving met het library-statement
library(stringr)
Nu ben je klaar om alle functies in het stringr-package te gebruiken. Laten we bijvoorbeeld de functie str_detect() proberen, die een logische vector teruggeeft met TRUE voor elk element van de string dat overeenkomt met het patroon en FALSE anders.
str_detect('DataCamp', "Data")
[1] TRUE
Wil je meer weten over R-packages en hoe je ze gebruikt? Bekijk dan deze DataCamp-tutorial over R-packages.
Door de gebruiker gedefinieerde functies
De beste manier om te begrijpen hoe functies in R werken, is door je eigen functies te maken. De zogenoemde door de gebruiker gedefinieerde functies (UDF) worden ontworpen door programmeurs om een specifieke taak uit te voeren.
R-functies hebben doorgaans de volgende syntaxis:
function_name <- function(argument_1, argument_2) {
function body
return (output)
}
We kunnen vier hoofdelementen onderscheiden:
- Functienaam. Om een UDF te maken, geef je die eerst een naam en sla je hem op als een nieuw object. Roep simpelweg de naam aan wanneer je de functie wilt gebruiken.
- Argumenten. De functie-argumenten (ook wel parameters) geef je tussen haakjes op. Argumenten zijn essentieel zodat de functie weet welke data als input te nemen en/of hoe het gedrag van de functie aan te passen.
- Functiebody. Tussen de accolades staat de body van de functie: de instructies om een specifieke taak op te lossen op basis van de door de argumenten aangeleverde informatie.
- Return-statement. Het return-statement is nodig als je wilt dat de functie het resultaat of de resultaten uit de functiebody als variabelen opslaat.
Als je bijvoorbeeld een functie wilt maken die het gemiddelde van twee getallen berekent:
mean_two_numbers <- function(num_1, num_2) {
mean <- (num_1 + num_2) / 2
return (mean)
}
Wil je nu het gemiddelde van 10 en 20 berekenen, roep de functie dan als volgt aan:
>>> mean_two_numbers(10,20)
[1] 15
Typen argumenten in R-functies
Argumenten zijn onmisbare onderdelen van elke functie. Hoewel het theoretisch mogelijk is om een functie zonder parameters te schrijven (zie het voorbeeld hieronder), hebben de meeste functies wel argumenten. Dat is logisch, want argumenten vertellen de functie welke data hij als input moet nemen. En als we een functie meerdere manieren willen geven om een taak uit te voeren, dan regelen argumenten dat.
hello <- function() {
print('hello, my friend')
}
>>> hello()
[1] "hello, my friend"
Er staat geen limiet op het aantal argumenten in R-functies; je voegt ze toe tussen haakjes, gescheiden door komma's. Over het algemeen zijn functies met meer argumenten complexer.
Zodra je een functie met parameters hebt gemaakt, moet je elke keer dat je die wilt gebruiken de waarden van de verschillende parameters meegeven; anders geeft R een foutmelding. Als je bijvoorbeeld de waarden van de twee getallen niet opgeeft om hun gemiddelde te berekenen, werkt onze functie niet.
Je kunt deze fout echter voorkomen door bij het definiëren van een functie standaardargumenten te gebruiken. Standaardargumenten geven een standaardwaarde die wordt gebruikt als je de functie aanroept zonder dat argument mee te geven. Laten we teruggaan naar onze functie om het gemiddelde van twee getallen te berekenen. Dit keer definiëren we hem met een standaardargument voor het tweede getal.
mean_two_numbers <- function(num_1, num_2 = 30) {
mean <- (num_1 + num_2) / 2
return (mean)
}
Als we de functie nu aanroepen zonder de waarde van de parameter num_2 op te geven, neemt R automatisch de standaardwaarde (dus 30):
>>> mean_two_numbers(num_1 = 10)
[1] 20
Returnwaarden in R-functies begrijpen
Functies nemen normaal gesproken data als input en geven een resultaat als output. In sommige programmeertalen moet je het return-statement expliciet opnemen aan het einde van de functiebody om het resultaat van een functie in een variabele op te slaan. Anders geeft de functie alleen een waarde weer die alleen bestaat binnen de scope van de variabele.
In R is dat niet het geval: R zal altijd een waarde retourneren die je in een variabele kunt opslaan. Toch is het, omwille van de leesbaarheid, goede gewoonte om het return-statement op te nemen wanneer je een functie definieert.
mean_two_numbers <- function(num_1, num_2) {
# Function with return
mean <- (num_1 + num_2) / 2
return (mean)
}
mean_two_numbers_2 <- function(num_1, num_2) {
# Function without return
mean <- (num_1 + num_2) / 2
mean
}
> mean_two_numbers(10,50)
[1] 30
> mean_two_numbers_2(10,50)
[1] 30
Tot slot: als je wilt dat je functie meerdere waarden retourneert, moet je de verschillende resultaten in een lijst opslaan en die in het return-statement opnemen:
mean_sum <- function(num_1, num_2) {
mean <- (num_1 + num_2) / 2
sum <- num_1 + num_2
return (list(mean, sum))
}
>>> mean_sum (10, 20)
[[1]]
[1] 15
[[2]]
[1] 30
Functies aanroepen in R
In de vorige secties hebben we al verschillende voorbeelden gezien van hoe je een functie aanroept. Toch is het belangrijk om te verduidelijken hoe R onder de motorkap werkt wanneer we argumenten doorgeven.
R kent twee manieren om argumenten door te geven: op positie en op naam. Volgen we de eerste strategie, dan moeten we de waarden in dezelfde volgorde schrijven als de argumenten in de functie zijn gedefinieerd.
Geven we argumenten op naam door, dan moeten we expliciet de namen van de argumenten en hun bijbehorende waarden specificeren. Omdat argumenten en waarden aan elkaar zijn gekoppeld, maakt de volgorde dan niet uit.
Ten slotte is het ook mogelijk om beide strategieën te combineren. In dat geval worden de benoemde argumenten eerst uit de argumentlijst gehaald en gematcht, terwijl de rest van de argumenten op positie wordt gematcht.
hello <- function(name, surname) {
print(paste('Hello', name, surname))
}
# Calling arguments by position
> hello('Greta','Thunberg')
[1] "Hello, Greta Thunberg"
# Calling arguments by name
> hello(surname='Thunberg', name='Greta')
[1] "Hello, Greta Thunberg"
# Calling arguments by position and by name
> hello(surname='Thunberg', 'Greta')
[1] "Hello, Greta Thunberg"
Functies documenteren in R
Een goede gewoonte bij het maken van functies is om documentatie te geven over hoe je ze gebruikt, zeker als functies complex zijn. Een informele manier is om comments toe te voegen in de body van functies. Je kunt de documentatie bekijken door de functie zonder parameters aan te roepen:
hello <- function(name, surname) {
# Say hello to a person with name and surname
print(paste('Hello', name, surname))
}
>>> hello
function(name, surname) {
# Say hello to a person with name and surname
print(paste('Hello,', name, surname))
Als je functie echter deel uitmaakt van een groter package en je die wilt documenteren, moet je formele documentatie schrijven in een apart .Rd-document. Je ziet het resultaat van deze documentatie wanneer je het helpbestand voor een bepaalde functie bekijkt, bijvoorbeeld ?mean.
Conclusie
Je bent aan het eind van de tutorial gekomen. Gefeliciteerd! Net als in veel andere talen zijn functies onmisbaar in R. Of ze nu ingebouwd zijn, onderdeel van externe packages of door jouzelf gemaakt: functies beheersen is een belangrijk ijkpunt in je programmeerreis. Wil je je R-functievaardigheden verder ontwikkelen? Bekijk dan de volgende resources!
