<- function(x) {
plus3 +3
x
}
plus3(5)
[1] 8
plus3(1:3)
[1] 4 5 6
Les fonctions sont généralement abordées plus tard mais je crois non seulement en vous mais aussi qu’elles peuvent et doivent être démystifiées précocément. Nous allons commencer par la partie créative et écrire notre première fonction.
Nous pouvons définir nos propres fonctions en utilisant la fonction function
.
Nous allons ensuite encapsuler une portion de code entre des accolades {
et l’assigner comme tout autre objet R.
Définissons une fonction qui ajoute 3
à un argument que l’on va appeller x
(vous pouvez essayer avec y
ou toto
:
<- function(x) {
plus3 +3
x
}
plus3(5)
[1] 8
plus3(1:3)
[1] 4 5 6
Les fonctions permettent de ne pas copier-coller bêtement du code, de dupliquer des lignes. Dès que vous répétez un bout de code, vous pouvez profitablement en faire une fonction.
À terme, cela vous permettra d’avoir du code non dupliqué, moins propice à des erreurs de frappes.
Aussi, si vous changez d’avis, vous pourrez changer la définition de fonction et, chaque fois qu’elle sera appelée en aval, le nouveau comportement sera appliqué. Nous reviendrons sur ces bonnes pratiques à la toute fin de cette formation.
L’expérience vous guidera sur quand et comment créér des fonctions à la bonne granularité, c’est à dire les plus génériques possibles mais dans les limites du bon sens.
Les fonctions sont des unités de code qui font quelque chose d’utile. Le plus souvent on envoie une valeur, un objet, et on en récupère une autre mais certaines produisent quelque chose “ex nihilo” sqrt()
par exemple renvoie la racine carrée de la valeur passée en argument.
Les arguments, séparés par des virgules, définissent les “options” de la fonction concernée. Une fonction peut avoir zéro, un, plusieurs et même un nombre indéfini d’argument.
Toute fonction déjà disponible en R ou un package a forcément une page d’aide dédiée à laquelle on accède avec : ?nom_de_la_fonction
.
Revenons à notre fonction seq
bien pratique pour créer des seq
uences régulières. En tapant ?seq
on accède au contenu suivant :
Sequence Generation
Description
Generate regular sequences. seq is a standard generic with a default method. seq.int is a primitive which can be much faster but has a few restrictions. seq_along and seq_len are very fast primitives for two common cases.
## Default S3 method:
seq(from = 1, to = 1, by = ((to - from)/(length.out - 1)),
length.out = NULL, along.with = NULL, ...)
seq.int(from, to, by, length.out, along.with, ...)
seq_along(along.with)
seq_len(length.out)
Arguments
[...]
Details
[...]
Value
[...]
See also
[...]
Examples
[...]
Toutes les pages d’aides ont la même structure et possèdent les mêmes sections. Regardons-les de plus près :
seq
. Ces fonctions peuvent être des variantes avec des noms différents ou des méthodes c’est à dire des fonctions au comportement différent selon le type d’objet sur lequel elles opèrent.example("nom_de_la_fonction")
. Vous pouvez essayer example("plot")
par exemple.seq
, on est dans le package base
dont toutes les autres fonctions sont indexées dans le lien “Index”.Certaines pages d’aide, surtout pour le langage lui-même, sont plutôt des résumés du fonctionnement et sont un peu moins intuitives à trouver, par exemple ?Arithmetic
, ?Special
, Syntax
.
D’autres fonctions, par exemple pour les opérateurs, doivent être encadrées de guillemets arrières (`
), par exemple ?`+`
ou la mise en abyme de ?`?`
. Enfin, il existe d’autres ressources comme les “vignettes”, plus conviviales, surtout pour les packages les plus récents. Nous y reviendrons.
Les pages d’aide sont souvent compactes et obscures mais l’information que vous cherchez est probablement là. On apprend beaucoup à lire ces pages d’aide même si à première vue cette littérature n’est guère attrayante.
Enfin, la variante ??(quoiquoiquoi)
, raccourci de help.search("quoiquoiquoi")
permet de chercher toutes les occurences de quoiquoiquoi
dans toutes les pages d’aide de R.
Après avoir consulté ?seq
on peut par exemple préciser le point de départ (from
), le point d’arrivée (to
), le pas (by
) et la longueur totale du vecteur à créer (length.out
).
Vous constaterez que from
est défini avec une valeur par défaut (from=1
). Ainsi, si vous omettez sa valeur et ne spécifiez que to
, from
prendra sa valeur par défaut. Ces deux commandes sont donc équivalentes :
seq(from=1, to=5)
[1] 1 2 3 4 5
seq(to=5)
[1] 1 2 3 4 5
Vous pouvez également abréger le nom des arguments, moyennant que l’abbréviation soit univoque, c’est à dire que le nom de l’argument que vous abrégez ne soit pas identique à celui d’un autre argument. Ainsi from
et length.out
peuvent être abrégés en fr
et length
:
seq(fr=0, to=2, length=5)
[1] 0.0 0.5 1.0 1.5 2.0
Ce n’est jamais une bonne idée mais si vous utilisez le nom complet ou une abbréviation des arguments vous pouvez changer leur ordre. Ainsi seq(length=5, to=2, fr=0)
sera équivalent à la commande précédente.
Vous pouvez même omettre le nom des arguments comme on l’a fait dans les sections précédentes sans le mentionner. Dans ce cas, les arguments sont passés positionnellement et doivent être renseignés dans l’ordre tel que défini dans la section ‘Usage’ de leur documentation:
seq(-3, 4, 12)
[1] -3
Si vous avez bien compris la section précédent, alors le deuxième exemple avec deux arguments, et des valeurs par défaut, devrait vous paraître limpide :
<- function(x=1, y=0){
add_this +y
x
}
add_this()
[1] 1
add_this(5)
[1] 5
add_this(y=7)
[1] 8
add_this(2, 10)
[1] 12
Le code des fonctions est toujours accessible, le plus souvent simplement en tapant le nom des fonctions, sans parenthèses.
plus3
<srcref: file "" chars 1:10 to 3:1>
<bytecode: 0x7fe69f525a40>
add_this
<srcref: file "" chars 1:13 to 3:1>
<bytecode: 0x7fe6a1219d10>
Parfois le code est lové dans des Primitives (des fonctions non écrites en R) ou bien dans des méthodes (des fonctions qui changent de comportement suivant le type d’objet qu’on leur passe). Nous y reviendrons.
c
function (...) .Primitive("c")
seq
function (...)
UseMethod("seq")
<bytecode: 0x7fe69aad9460>
<environment: namespace:base>
❤ Placé dans le domaine public par Vincent Bonhomme