Style de Programmation R: Meilleures Pratiques



Style de Programmation R: Meilleures Pratiques

Cet article décrit les éléments essentiels des meilleures pratiques du style de codage R. Il est basé sur le [style tidyverse] (https://style.tidyverse.org/). Le guide actuel de Gougle est également dérivé du guide de style tidyverse.

Deux packages R importants sont disponibles pour vous aider à appliquer les meilleures pratiques du style de codage R:

  • ** styler vous permet de restyler de manière interactive textes sélectionnés, fichiers ou projets**. Il comprend un add-in RStudio, la manière la plus simple de réorganiser le code existant.

package styler

Le but de styler est de fournir une impression non invasive du code source de R tout en respectant les règles de formatage tidyverse. Il peut être installé en utilisant le code R suivant: install.packages("styler"). Les principales fonctions sont les suivantes:

  • style_file(): styles .R, .Rmd .Rnw et .Rprofile, fichiers.
  • style_dir(): stylise tous les fichiers .R et/ou .Rmd dans un répertoire.
  • style_pkg(): les styles des fichiers sources d’un paquet R.

La fonctionnalité “styler” est disponible par le biais d’autres outils, notamment : usethis::use_tidy_style() façonne votre projet selon le guide de style tidyverse.

  • ** lintr effectue des contrôles automatisés pour confirmer que vous vous conformez au guide de style**. Il peut être installé en utilisant le code R suivant: install.packages("lintr").

package lintr

Les résultats de lintr s’affichent automatiquement dans le panneau Markers de RStudio (versions Rstudio > v0.99.206). Afin de montrer le volet " Markers " dans RStudio : Menu “Outils” -> “Options globales…”, une fenêtre avec le titre “Options” apparaîtra. Dans cette fenêtre : Cliquez sur “Code” à gauche ; cliquez sur l’onglet “Diagnostics” ; cochez “Afficher les diagnostics pour R”.

Pour lier un fichier source test.R, tapez dans la console lintr::lint("test.R") et regardez le résultat dans le panneau " Markers ".

Ce package comprend également deux addins pour lier la source et le package actuels. Pour lier l’addin à un raccourci clavier, accédez à Outils > addins > Parcourir les addins > Raccourcis clavier. Il est recommandé d’utiliser Alt+Shift+L pour le code source actuel et Ctrl+Shift+Alt+L pour le code du package. Il est facile de les mémoriser puisque vous êtes Alt+Shift+L(int) 😉

Rstudio lintr lints

Dans ce tutoriel, vous apprendrez les meilleures pratiques pour:

  • Noms de fichiers et structures du contenu
  • Variables et conventions de dénomination des objets
  • Syntaxee R et meilleures pratiques en matière de pipes


Sommaire:

Fichiers

Conventions de dénomination des fichiers

Les noms de fichiers doivent être significatifs et se terminer par .R. Évitez d’utiliser des caractères spéciaux dans les noms de fichiers - s’en tenir aux chiffres, aux lettres, -, and _.

# Bon
fit_models.R
utility_functions.R

# Mauvais
fit models.R
foo.r
stuff.r

Si les fichiers doivent être exécutés dans un ordre particulier, les préfixer avec des numéros. S’il semble probable que vous ayez plus de 10 fichiers, mettez zéro devant le numéro:

00_download.R
01_explore.R
...
09_model.R
10_visualize.R

Si vous vous rendez compte par la suite que vous avez manqué certaines étapes, il est tentant d’utiliser “02a”, “02b”, etc. Cependant, il est généralement préférable de renommer tous les fichiers.

Structure du contenu des fichiers

  • Chargez tous les paquets requis au tout début du fichier
  • Use commented lines of - and = to break up your file into easily readable chunks.
# Charger des données --------------------------

# Créer un graphique --------------------------

Syntaxe

Convention de dénomination des objets

  • Utilisez uniquement des lettres minuscules et des chiffres.
  • Utilisez des traits underscores (_) (dit “snake case”) pour séparer les mots dans un nom.
  • Utilisez des noms concis et significatifs (ce n’est pas facile !).
  • En général, les noms de variables doivent être des noms et les noms de fonctions des verbes.
  • Dans la mesure du possible, évitez de réutiliser les noms des fonctions et des variables communes. Cela créera une confusion pour les lecteurs de votre code.
  • Si vous essayez de comprimer des données dans des noms de variables (par exemple. model_2018, model_2019, model_2020), envisagez plutôt d’utiliser une liste ou un data frame.
# Exemples de noms de variables ------------
# Bon
day_one
day_1

# Mauvais
DayOne
dayone

Espacement

Commas

Mettez toujours un espace après une virgule, jamais avant, comme en anglais normal.

# Bon
x[, 1]

# Mauvais
x[,1]
x[ ,1]
x[ , 1]

Parenthèses

Ne mettez pas d’espaces entre parenthèses pour les appels de fonction réguliers.

# Bon
mean(x, na.rm = TRUE)

# Mauvais
mean (x, na.rm = TRUE)
mean( x, na.rm = TRUE )

Placez un espace avant et après () lorsqu’il est utilisé avec if, for, ou while.

# Bon
if (debug) {
  show(x)
}

# Mauvais
if(debug){
  show(x)
}

Placez un espace après () utilisé pour les arguments de fonction:

# Bon
function(x) {}

# Mauvais
function (x) {}
function(x){}

Opérateurs Infix

Most infix operators (==, +, -, <-, etc.) should always be surrounded by spaces:

# Bon
height <- (feet * 12) + inches
mean(x, na.rm = 10)

# Mauvais
height<-feet*12+inches
mean(x, na.rm=10)

There are a few exceptions, to this rule: ::, :::, $, @, [, [[, ^, unary -, unary +, and :.

# Bon
sqrt(x^2 + y^2)
df$z
x <- 1:10

# Mauvais
sqrt(x ^ 2 + y ^ 2)
df $ z
x <- 1 : 10

Espaces supplémentaires

L’ajout d’espaces supplémentaires est acceptable si cela améliore l’alignement de = ou <-.

# Bon
list(
  total = a + b + c,
  mean  = (a + b + c) / n
)

# Aussi bien
list(
  total = a + b + c,
  mean = (a + b + c) / n
)

N’ajoutez pas d’espaces supplémentaires aux endroits où l’espace n’est généralement pas autorisé.

Noms des arguments

Les arguments d’une fonction se divisent généralement en deux grandes catégories : l’une fournit les données sur lesquelles calculer ; l’autre contrôle les détails du calcul. Lorsque vous appelez une fonction, vous omettez généralement les noms des arguments de données, car ils sont utilisés si souvent. Si vous passez outre la valeur par défaut d’un argument, utilisez le nom complet:

# Bon
mean(1:10, na.rm = TRUE)

# Mauvais
mean(x = 1:10, , FALSE)
mean(, TRUE, x = c(1:10, NA))

Éviter les correspondances partielles ou partial matching.

Blocs de code

Les accolades, {}, définissent la plus importante hiérarchie du code R. Pour que cette hiérarchie soit facile à voir:

  • { doit être le dernier caractère de la ligne. Le code associé (par exemple, une clause if, une déclaration de fonction, une virgule de fin, …) doit être sur la même ligne que l’accolade d’ouverture.
  • Le contenu doit être mis en retrait de deux espaces.
  • } doit être le premier caractère de la ligne.
# Bon
if (y < 0 && debug) {
  message("y is negative")
}

if (y == 0) {
  if (x > 0) {
    log(x)
  } else {
    message("x is negative or zero")
  }
} else {
  y^x
}


# Mauvais
if (y < 0 && debug) {
message("Y is negative")
}

if (y == 0)
{
    if (x > 0) {
      log(x)
    } else {
  message("x is negative or zero")
    }
} else { y ^ x }

Longues lignes

  • Essayez de limiter votre code à 80 caractères par ligne.
  • Si un appel de fonction est trop long pour tenir sur une seule ligne, utilisez une ligne pour chaque le nom de la fonction, chaque argument et la clôture ). Cela rend le code plus facile à lire et à modifier ultérieurement.
  • Vous pouvez placer plusieurs arguments sur la même ligne s’ils sont proches liées les unes aux autres
# Bon
do_something_very_complicated(
  something = "that",
  requires = many,
  arguments = "some of which may be long"
)

# Mauvais
do_something_very_complicated("that", requires, many, arguments,
                              "some of which may be long"
                              )

Affectation

Use <-, not =, for assignment.

# Bon
x <- 5

# Mauvais
x = 5

Points-virgules

Ne mettez pas ; à la fin d’une ligne, et n’utilisez pas ; pour mettre plusieurs commandes sur une ligne.

Citations

Utilisez ", et non “`”, pour citer le texte. La seule exception est lorsque le texte contient déjà des guillemets doubles et pas de guillemets simples.

# Bon
"Text"
'Text with "quotes"'
'<a href="http://style.tidyverse.org">A link</a>'

# Mauvais
'Text'
'Text with "double" and \'single\' quotes'


Commentaires

Si vous avez besoin de commentaires pour expliquer ce que fait votre code, envisagez de le réécrire pour qu’il soit plus clair. Si vous découvrez que vous avez plus de commentaires que de codes, envisagez de passer à R Markdown.

Fonctions

Convention d’appellation des fonctions

Utiliser des verbes pour les noms de fonctions:

# Bon
add_row()
permute()

# Mauvais
row_adder()
permutation()

Définition de fonction long avec plein d’arguments

Si la définition d’une fonction s’étend sur plusieurs lignes, indentez la deuxième ligne jusqu’au point de départ de la définition.

# Bon
long_function_name <- function(a = "a long argument",
                               b = "another argument",
                               c = "another long argument") {
  # Comme d'habitude, le code est indenté par deux espaces.
}

# Mauvais
long_function_name <- function(a = "a long argument",
  b = "another argument",
  c = "another long argument") {
  # Il est difficile de savoir où s'arrête la définition et le
  # code commence
}

Fonction return()

  • N’utilisez return() que pour les retours anticipés. Sinon, utilisez R pour renvoyer le résultat de la dernière expression évaluée.
  • Les déclarations de “return()” doivent toujours être sur leur propre ligne.
# Bon
find_abs <- function(x) {
  if (x > 0) {
    return(x)
  }
  x * -1
}
add_two <- function(x, y) {
  x + y
}

# Mauvais
add_two <- function(x, y) {
  return(x + y)
}

Si votre fonction est appelée principalement pour ses effets secondaires (comme l’impression, le tracé ou la sauvegarde sur disque), elle doit renvoyer le premier argument de manière invisible. Cela permet d’utiliser la fonction comme une partie d’un pipe. Les méthodes printdevraient généralement le faire, comme cet exemple tiré de httr:

print.url <- function(x, ...) {
  cat("Url: ", build_url(x), "\n", sep = "")
  invisible(x)
}

Pipes

Introduction

Utilisez %>% pour mettre l’accent sur une séquence d’actions.

Évitez d’utiliser le pipe lorsque:

  • Vous devez manipuler plus d’un objet à la fois. Réserver les pipes pour une séquence d’étapes appliquée à un objet primaire.
  • Il existe des objets intermédiaires significatifs auxquels on pourrait donner des noms informatifs.

Espace

Le caractère %>% doit toujours être précédé d’un espace et doit généralement être suivi d’une nouvelle ligne. Après la première étape, chaque ligne doit être indentée de deux espaces.

# Bon
iris %>%
  group_by(Species) %>%
  summarize_if(is.numeric, mean) %>%
  ungroup() %>%
  gather(measure, value, -Species) %>%
  arrange(value)

# Mauvais
iris %>% group_by(Species) %>% summarize_all(mean) %>%
ungroup %>% gather(measure, value, -Species) %>%
arrange(value)

Longues lignes

Si les arguments en faveur d’une fonction ne tiennent pas tous sur une seule ligne, placez chaque argument sur sa propre ligne et mettez un retrait:

iris %>%
  group_by(Species) %>%
  summarise(
    Sepal.Length = mean(Sepal.Length),
    Sepal.Width = mean(Sepal.Width),
    Species = n_distinct(Species)
  )

Pipes courts

Un pipe en une seule étape peut rester sur une ligne, mais à moins que vous ne prévoyiez de l’étendre plus tard, vous devriez envisager de le réécrire en un appel de fonction régulier.

# Bon
iris %>% arrange(Species)

iris %>% 
  arrange(Species)

arrange(iris, Species)



Version: English





No Comments

Give a comment

Want to post an issue with R? If yes, please make sure you have read this: How to Include Reproducible R Script Examples in Datanovia Comments