Chapter 28 Bonnes pratiques de programmation

28.1 Pourquoi devrais-je me soucier sur les bonnes pratiques de programmation?


  • Pour vous faciliter la vie;
  • Pour améliorer la lisibilité et faciliter le partage et la réutilisation de votre code;
  • Pour réduire le temps que vous passeriez à essayer de comprendre votre code.

Gardez un code beau et propre

Les indentations et les espaces sont une première étape vers un code lisible:

  • Utilisez des espaces avant et après vos opérateurs;

x>=1&x<=10 est plus difficile à lire que x >= 1 & x <= 10

  • Utilisez toujours le même opérateur d’assignation.

<- est préférable. Vous pouvez utiliser = (parfois), mais ne changez pas entre les deux;

  • Utilisez des crochets pour encadrer vos structures de contrôle de flux:

    • À l’intérieur des crochets, faites une indentation d’au moins 2 espaces;
    • Les crochets de fermeture occupent généralement leur propre ligne, sauf s’ils précèdent une condition else.
  • Définissez chaque variable sur sa propre ligne;

  • Utilisez Cmd + I ou Ctrl + I dans RStudio pour indenter automatiquement le code mis en évidence.

28.2 Utilisez des fonctions pour simplifier le code

Écrivez une fonction: 1. Quand une portion du code est répété à plus de 2 reprises dans ton script; 2. Quand seulement une partie du code change et inclut des options pour différents arguments.

Ceci vous aidera à réduire le nombre d’erreurs de copier/coller, et réduira le temps passé à les corriger.

Modifions l’exemple de l’Exercice 3 et supposons que toutes les concentrations de \(CO_2\) du Mississipi étaient surestimées de 20 et que celles du Québec étaient sous-estimées de 50.

On pourrait écrire ceci:

for (i in 1:length(CO2[, 1])) {
    if (CO2$Type[i] == "Mississippi") {
        CO2$conc[i] <- CO2$conc[i] - 20
    }
}
for (i in 1:length(CO2[, 1])) {
    if (CO2$Type[i] == "Quebec") {
        CO2$conc[i] <- CO2$conc[i] + 50
    }
}

Ou ceci:

recalibrate <- function(CO2, type, bias) {
    for (i in 1:nrow(CO2)) {
        if (CO2$Type[i] == type) {
            CO2$conc[i] <- CO2$conc[i] + bias
        }
    }
    return(CO2)
}
newCO2 <- recalibrate(CO2 = CO2, type = "Mississipi", bias = -20)
newCO2 <- recalibrate(newCO2, "Quebec", +50)

28.3 Noms de fonctions informatifs

Voici notre fonction de l’exemple précédent avec un nom vague.

rc <- function(c, t, b) {
    for (i in 1:nrow(c)) {
        if (c$Type[i] == t) {
            c$uptake[i] <- c$uptake[i] + b
        }
    }
    return(c)
}

Qu-est ce que rc et c?

Quand possible, évitez d’utiliser des noms de fonctions R et de variables qui existent déjà pour éviter la confusion et les conflits.

28.4 Utilisez des commentaires: #

Ajoutez des commentaires pour décrire tout ce que votre code fait, que ce soit le but de la fonction, comment utiliser ses arguments, ou une description détaillée de la fonction étape par étape.

# Recalibre le jeu de données CO2 en modifiant la
# concentration de CO2 d'une valeur fixe selon la region
# Arguments CO2: the CO2 dataset type: the type
# ('Mississippi' or 'Quebec') that need to be recalibrated.
# bias: the amount to add or remove to the concentration
recalibrate <- function(CO2, type, bias) {
    for (i in 1:nrow(CO2)) {
        if (CO2$Type[i] == type) {
            CO2$conc[i] <- CO2$conc[i] + bias
        }
    }
    return(CO2)
}

28.5 Exercice de groupe

En utilisant ce que vous avez appris, écrivez une déclaration if() qui vérifie si une variable numérique x est égale à zéro. Si ce n’est pas le cas, elle attribue \(cos(x)/x\) à z, sinon elle attribue \(1\) à z.

Créez une fonction appelée ma_fonction() qui prend la variable x en argument et retourne z.

Si nous attribuons respectivement \(45\), \(20\) et \(0\) à x, laquelle des options suivantes représenterait les résultats ?

1. \(0.054\), \(0.012\), et \(0\);

2. \(0.020\), \(0.054\), et \(1\);

3. \(0.012\), \(0.020\), et \(1\).

Exercice de groupe: Solution

La bonne réponse est l’option 3 ( \(0.012\), \(0.020\) et \(1\) ).


my_function <- function(x) {
    if (x != 0) {
        z <- cos(x)/x
    } else {
        z <- 1
    }
    return(z)
}
my_function(45)
## [1] 0.01167382
my_function(20)
## [1] 0.0204041
my_function(0)
## [1] 1