Développer des fonctions#

Dans les chapitres précédents, nous avons développé plusieurs exemples de code. Par exemple, nous avons calculé la valeur présente d’une série de paiements. Dans cette section, nous verrons qu’il est possible de faire ces mêmes calculs en se servant de nos propres fonctions. Creer des fonctions nous permet d’éviter de réécrire le code qui fait le même calcule à chaque fois.

Syntaxe:

prenons l’exemple classique où l’on crée une fonction qui additionne deux éléments;

somme<-function(x,y){
    return(x+y)
}

Appliquons cette fonction maintenant:

somme(2,3)
5

Gestion de erreurs,#

On peut éviter des erreurs d’exécution par le moyen de conditions. Toutesfois, cette solution nécessite une connaissance des erreurs qui peuvent survenir. Dans notre exemple d’adition de deux éléments, on peut demander au programme de vérifier si les éléments à additionner sont d’abord de type numérique;

somme<-function(x,y){
    if(is.numeric(x) & is.numeric(y)){
        return(x+y)
    }else {
        print("veuillez vérifier vos arguments")
    }
        
}
somme(2,2)
4

Toutefois, lorsqu’on essaie ceci:

somme(2, "a")
[1] "veuillez vérifier vos arguments"

Dans l’exemple précédent, nous avons eu comme résultat la somme de deux éléments, il est possible de faire en sorte que le résultat de la fonction nous retourne plusieurs éléments. Par exemple, dans la fonction operation suivante, elle nous retourne trois opérations sur les deux arguments de la fonction; la somme, la différence,la multiplication , ainsi que la division des deux éléments;

operation<-function(x,y){
    if(is.numeric(x) & is.numeric(y)){
        return(c(x+y, x-y, x*y, x/y))
    }else {
        print("veuillez vérifier vos arguments")
    }        
}
operation(2,3)
  1. 5
  2. -1
  3. 6
  4. 0.666666666666667

Résultat en plusieurs éléments (list)#

Au lieu d’utiliser return, on peut utiliser list afin d’avoir une liste d’éléments dans le résultat. L’avantage d’avoir une liste est bien sûr la manipulation d’élément de cette dernière.

operation_l<-function(x,y){
    if(is.numeric(x) & is.numeric(y)){
        list(x+y, x-y, x*y, x/y)
    }else {
        print("veuillez vérifier vos arguments")
    }        
}
resultat_sousForme_liste<-operation_l(2,3)
resultat_sousForme_liste
  1. 5
  2. -1
  3. 6
  4. 0.666666666666667

Ainsi, on peut extraire un seul (ou plusieurs) élément de notre liste résultante;

resultat_sousForme_liste[2]
  1. -1

Au lieu d’insérer deux éléments comme argument de notre fonction operation_l, insérons deux vecteurs et regardons la différence entre le résultat de la fonction operation_l et la fonction operation

xvec<-c(1:5)
yvec<-c(6:10)
operation_l(xvec, yvec)
    1. 7
    2. 9
    3. 11
    4. 13
    5. 15
    1. -5
    2. -5
    3. -5
    4. -5
    5. -5
    1. 6
    2. 14
    3. 24
    4. 36
    5. 50
    1. 0.166666666666667
    2. 0.285714285714286
    3. 0.375
    4. 0.444444444444444
    5. 0.5

Maintenant, appliquons la fonction operation sur les mêmes vecteurs et inspectons à nouveau le résultat:

operation(xvec, yvec)
  1. 7
  2. 9
  3. 11
  4. 13
  5. 15
  6. -5
  7. -5
  8. -5
  9. -5
  10. -5
  11. 6
  12. 14
  13. 24
  14. 36
  15. 50
  16. 0.166666666666667
  17. 0.285714285714286
  18. 0.375
  19. 0.444444444444444
  20. 0.5

Si l’on voulait par exemple extraire le deuxième élément de la liste, qui est le résultat de la soustraction dans notre exemple, il est plus difficile de le faire avec la fonction operation.

operation_l(xvec, yvec)[2]
    1. -5
    2. -5
    3. -5
    4. -5
    5. -5

au lieu de:

operation(xvec, yvec)[6:10]
  1. -5
  2. -5
  3. -5
  4. -5
  5. -5

Où il est nécessaire de connaitre les index du seul vecteur résultant.

inspecter la fonction:#

On peut inspecter le code de notre fonction en inscrivant le nom de cette dernière. Surtout, lorsque le code de la fonction est perdu quelque part dans un autre code 100 lignes plutôt.

le code#

operation_l
function (x, y) 
{
    if (is.numeric(x) & is.numeric(y)) {
        list(x + y, x - y, x * y, x/y)
    }
    else {
        print("veuillez vérifier vos arguments")
    }
}

les arguments de la fonction#

On peut obtenir les arguments d’une fonction avec l’instruction suivante;

formals(operation_l)
$x


$y

Les arguments par défaut#

Il convient souvent de donner des arguments par défaut à notre fonction créée. Dans notre exemple operation_l, on pourrait données les valeurs (x,y)={1,1} afin d’éviter des division par 0 par exemple;

operation_l<-function(x=1,y=1){
    if(is.numeric(x) & is.numeric(y)){
        list(x+y, x-y, x*y, x/y)
    }else {
        print("veuillez vérifier vos arguments")
    }        
}

Lorsqu’on écrit la fonction sans aucun argument;

operation_l()
  1. 2
  2. 0
  3. 1
  4. 1

On obtient le résultat de nos valeurs par défaut

Best practice#

Il est très conseillé de bien documenter les fonctions que vous créez. Cela vous aide lorsque vous revisez ou corrigez votre code. Sans oublier que la bonne documentation aide la personne qui relie votre code à bien comprendre ce que vous voulez avoir comme résultat. Que ce soit dans un contexte académique (travaux, examen….etc.) Et surtout dans le contexte professionnel, où les codes sont plus longs et plus lourds à lire lorsque la documentation est quasi absente.

operation_l<-function(x=1,y=1){
  # Cette fonction calcule l'adition, soustraction, multiplication
  # ainsi que la division de deux vecteurs
  # Args:
  #   x: La valeur du premier vecteur, la valeur par défaut étant =1
  #   y: La valeur du deuxième vecteur, la valeur par défaut étant =1
  #
  # retourne:
  #   une liste du résultat des opérations ....      

    if(is.numeric(x) & is.numeric(y)){
        list(x+y, x-y, x*y, x/y)
    }
    # Gestion d'erreurs
    else {
        print("veuillez vérifier vos arguments")
    }        
} 

Question#

Est-ce que la condition if ne fonctionne pas sur une colonne. Contrairement à ifelse (voir l’exemple de categorie d’age)