Écrire une fonction en R : arguments, valeurs par défaut et valeurs de retour

Factorisez du code répété dans une fonction nommée que vous pouvez appeler partout

Écrivez vos propres fonctions R : la syntaxe function(args) { }, les arguments et leurs valeurs par défaut, le renvoi d’une valeur avec return() ou la dernière expression implicite, la portée locale vs globale (et la mise en garde sur <<-), les points ..., les fonctions anonymes y compris le raccourci \(x) de R 4.1, et la signalisation des problèmes avec stop() et warning() — pour cesser de copier-coller et rester DRY.

Date de publication

26 juin 2026

Modifié

7 juillet 2026

AstucePoints clés
  • Une fonction s’écrit name <- function(args) { body } — appelez-la avec name(values).
  • Donnez à vos arguments des valeurs par défaut (function(x, na.rm = TRUE)) pour que l’appelant puisse les omettre.
  • Une fonction renvoie sa dernière expression évaluée ; utilisez return() pour sortir tôt, pas comme une ligne obligatoire.
  • Les variables créées à l’intérieur d’une fonction sont locales — elles ne fuient pas vers l’extérieur, et la fonction voit les variables globales qu’elle ne redéfinit pas.
  • ... (les points) permet à une fonction d’accepter et de transmettre des arguments supplémentaires à une autre fonction.
  • Utilisez des fonctions anonymesfunction(x) x^2 ou le raccourci \(x) x^2 de R 4.1 — pour des aides ponctuelles passées à sapply(), Map() et compagnie.
  • Signalez les problèmes avec stop() (interrompre) et warning() (continuer) pour que l’appelant sache ce qui n’a pas fonctionné.

Introduction

Dès que vous copiez-collez un bloc de code en n’ajustant qu’une seule valeur, vous avez une fonction qui ne demande qu’à être écrite. Envelopper ce bloc dans une fonction lui donne un nom, un ensemble d’entrées, et un seul endroit où corriger un bug — le principe DRY (don’t repeat yourself, ne vous répétez pas) en pratique.

Une fonction en R comporte trois parties : un nom auquel vous l’affectez, les arguments qu’elle accepte, et un corps qui fait le travail et renvoie un résultat. Cette leçon en construit une, de la syntaxe nue jusqu’aux valeurs par défaut, aux valeurs de retour, à la portée, aux points ..., aux fonctions anonymes et à la signalisation d’erreurs — tout ce qu’il faut pour transformer du code répété en outil réutilisable.

La syntaxe de base

Vous créez une fonction avec le mot-clé function et l’affectez à un nom. Les arguments vont entre les parenthèses ; le corps va entre les accolades :

# Convert a temperature from Celsius to Fahrenheit
to_fahrenheit <- function(celsius) {
  celsius * 9 / 5 + 32
}

to_fahrenheit(100)
[1] 212
to_fahrenheit(0)
[1] 32

to_fahrenheit est désormais une valeur comme une autre — vous l’appelez avec to_fahrenheit(100), et celsius prend la valeur que vous passez. Pour un corps d’une seule ligne, les accolades sont facultatives (function(celsius) celsius * 9/5 + 32), mais conservez-les pour tout ce que vous relirez.

Arguments et valeurs par défaut

Une fonction peut prendre plusieurs arguments, et chacun d’eux peut avoir une valeur par défaut — une valeur utilisée lorsque l’appelant n’en fournit pas. Les valeurs par défaut se placent dans la signature avec = :

# Round to a given number of digits; default to 2
round_to <- function(x, digits = 2) {
  round(x, digits)
}

round_to(3.14159)        # uses the default, digits = 2
[1] 3.14
round_to(3.14159, 4)     # override it
[1] 3.1416

Placez d’abord les arguments que l’appelant doit toujours fournir, puis ceux qui sont facultatifs et ont une valeur par défaut. Vous pouvez aussi nommer les arguments à l’endroit de l’appel (round_to(3.14159, digits = 4)), ce qui rend les appels auto-documentés et vous permet de sauter les valeurs par défaut précédentes.

Renvoyer une valeur

Une fonction renvoie la valeur de sa dernière expression évaluée — aucun return() nécessaire. Ces deux versions sont identiques :

# implicit: the last line is the return value
add_implicit <- function(a, b) {
  a + b
}

# explicit: same result
add_explicit <- function(a, b) {
  return(a + b)
}

add_implicit(2, 3)
[1] 5
add_explicit(2, 3)
[1] 5

Réservez return() pour quitter une fonction tôt, généralement à l’intérieur d’un if. Ici, nous sortons avant de diviser par zéro :

safe_divide <- function(x, y) {
  if (y == 0) {
    return(NA)            # exit now, skip the rest
  }
  x / y
}

safe_divide(10, 2)
[1] 5
safe_divide(10, 0)
[1] NA

Écrire return() sur la dernière ligne est sans danger mais peu idiomatique — la plupart du code R laisse la dernière expression être le résultat.

Portée : locale vs globale

Les variables que vous créez à l’intérieur d’une fonction sont locales : elles n’existent que pendant l’exécution de la fonction et disparaissent à son retour. Elles n’écrasent rien à l’extérieur, même si les noms correspondent :

x <- 10                    # global x

bump <- function() {
  x <- 99                  # a different, local x
  x
}

bump()                     # the function sees its local x
[1] 99
x                          # the global x is untouched
[1] 10

Une fonction peut lire une variable globale qu’elle ne définit pas localement (R cherche vers l’extérieur les noms qu’il ne trouve pas), mais une affectation avec <- crée toujours une copie locale. Pour atteindre et modifier une variable dans la portée englobante, vous utiliseriez l’opérateur de super-affectation <<- — mais cela couple la fonction à son environnement et rend le code difficile à suivre, donc préférez renvoyer une nouvelle valeur et la réaffecter :

# Preferred: take a value in, hand a new value back
increment <- function(value) {
  value + 1
}

count <- 5
count <- increment(count)  # reassign explicitly
count
[1] 6

... — transmettre des arguments supplémentaires

L’argument ... (« les points ») permet à une fonction d’accepter un nombre quelconque d’arguments supplémentaires et de les transmettre à une autre fonction — sans avoir à tous les énumérer. C’est ainsi que mean() passe discrètement na.rm à ses rouages internes, et c’est ainsi que vous écrivez de fines surcouches :

# A mean that drops NAs and forwards anything else to mean()
clean_mean <- function(x, ...) {
  mean(x, na.rm = TRUE, ...)
}

clean_mean(c(1, 2, NA, 4))           # NA dropped
[1] 2.333333
clean_mean(c(1, 2, NA, 4), trim = 0) # `trim` flows through ... to mean()
[1] 2.333333

Tout ce que l’appelant passe au-delà de x voyage dans ... et atterrit dans mean(). Utilisez les points lorsque vous enveloppez une autre fonction et voulez disposer de son jeu complet d’options sans les retaper.

Fonctions anonymes et le raccourci \(x)

Lorsque vous avez besoin d’une fonction rapide et ponctuelle — généralement pour la passer à un appel de la famille apply — vous n’avez pas à la nommer. Une fonction anonyme s’écrit en ligne. R 4.1 a ajouté un raccourci, \(x), qui signifie exactement la même chose que function(x) :

# classic anonymous function
sapply(1:5, function(x) x^2)
[1]  1  4  9 16 25
# R 4.1 shorthand — identical result
sapply(1:5, \(x) x^2)
[1]  1  4  9 16 25

La forme \(x) est juste plus courte à taper pour de brèves fonctions d’aide ; les deux produisent la même fonction. Recourez à une fonction anonyme pour une transformation jetable passée à sapply(), lapply(), Map() ou Filter() ; donnez-lui un nom lorsque vous l’appellerez plus d’une fois.

Signaler les problèmes : stop() et warning()

Une fonction qui reçoit une mauvaise entrée devrait le dire. stop() interrompt avec un message d’erreur ; warning() continue mais signale que quelque chose semblait anormal. Vérifiez les entrées dès le départ et échouez clairement :

to_fahrenheit <- function(celsius) {
  if (!is.numeric(celsius)) {
    stop("`celsius` must be numeric, not ", class(celsius))
  }
  if (any(celsius < -273.15, na.rm = TRUE)) {
    warning("Some values are below absolute zero — check your data.")
  }
  celsius * 9 / 5 + 32
}

to_fahrenheit(25)
[1] 77

Un bon message d’erreur nomme le problème et la valeur fautive, afin que l’appelant le corrige sans lire le code source de votre fonction. Validez les hypothèses sur lesquelles repose votre corps de fonction, puis faites-leur confiance pour le reste de la fonction.

Tout assembler : une fonction documentée

Les fonctions réelles méritent un bref bloc de commentaires — ce qu’elles font, leurs arguments, ce qu’elles renvoient — pour que le prochain lecteur (souvent vous) n’ait pas à la décortiquer :

# Standardize a numeric vector to mean 0, sd 1 (z-scores).
#   x:     a numeric vector
#   na.rm: drop NAs when computing mean/sd? (default TRUE)
# Returns: a numeric vector of z-scores, same length as x.
zscore <- function(x, na.rm = TRUE) {
  if (!is.numeric(x)) stop("`x` must be numeric.")
  (x - mean(x, na.rm = na.rm)) / sd(x, na.rm = na.rm)
}

zscore(c(10, 12, 14, 16, 18))
[1] -1.2649111 -0.6324555  0.0000000  0.6324555  1.2649111

Des valeurs par défaut, une vérification des entrées, un retour clair et trois lignes de documentation — voilà une fonction que vous pouvez intégrer à n’importe quel projet en toute confiance.

Essayez en direct

Les blocs ci-dessus se sont exécutés au moment de la compilation. Modifiez celui-ci et appuyez sur Run pour écrire et appeler votre propre fonction — elle s’exécute dans votre navigateur via webR, sans installation.

🟢 Avec un agent IA

Vous avez une boucle ou un bloc copié-collé que vous répétez sans cesse ? Collez-le et demandez à Prova « refactorise ceci en une fonction » — elle isole les parties variables en arguments. Ensuite, parce que le runtime est juste là, vous exécutez l’original et la nouvelle fonction sur la même entrée et confirmez qu’ils renvoient le même résultat — la refactorisation n’est correcte que si elle le fait toujours. Demander à Prova →

Vous travaillez en Python ? def name(args): avec des arguments par défaut, return, *args/**kwargs et lambda couvrent le même terrain — un guide des fonctions Python arrive dans la série Python.

Problèmes courants

Ma fonction ne renvoie rien / NULL. R renvoie la dernière expression évaluée. Si votre dernière ligne est une affectation (result <- x + 1), la fonction renvoie cette valeur de façon invisible — elle est là, mais elle ne s’affiche pas. Terminez sur l’expression nue (result), ou enveloppez l’appel dans print(), pour la voir. Un if sans else correspondant qui ne s’exécute pas produit lui aussi NULL.

« object not found » à l’intérieur de la fonction. La portée fonctionne vers l’extérieur, pas vers l’intérieur : une fonction peut lire les variables globales, mais l’appelant ne peut pas voir les variables créées à l’intérieur de la fonction. Si vous calculez quelque chose d’utile dans le corps et en avez besoin à l’extérieur, renvoyez-le et affectez le résultat — ne comptez pas sur le fait qu’il fuie. (Et évitez <<- pour repousser des valeurs ; cela rend le bug plus difficile à tracer.)

Ma fonction a modifié silencieusement une variable globale — ou pas. Un simple <- à l’intérieur d’une fonction écrit toujours une copie locale, donc la variable globale est en sécurité ; les débutants s’attendent parfois à ce que bump() change le x extérieur et sont surpris qu’il n’en soit rien. Si vous devez réellement mettre à jour une valeur extérieure, renvoyez-la et réaffectez-la (count <- increment(count)). Traitez une fonction comme valeur en entrée, valeur en sortie ; les effets de bord sur les variables globales sont une source fréquente de bugs déroutants.

Questions fréquentes

Affectez le mot-clé function à un nom : my_fun <- function(arg1, arg2) { body }. Les arguments vont entre les parenthèses, le travail va entre les accolades, et la fonction renvoie sa dernière expression évaluée. Appelez-la avec my_fun(value1, value2). Pour un corps d’une seule ligne, les accolades sont facultatives.

Donnez à l’argument une valeur dans la signature avec = : function(x, digits = 2). Les appelants peuvent l’omettre (la valeur par défaut est utilisée) ou la remplacer (my_fun(x, digits = 4)). Placez d’abord les arguments requis, puis ceux qui sont facultatifs et ont une valeur par défaut.

Non. Une fonction R renvoie automatiquement sa dernière expression évaluée, donc la plupart du code se termine sur une expression nue sans return(). N’utilisez return() que pour quitter une fonction tôt — généralement à l’intérieur d’un if — avant d’en atteindre la fin. Écrire return() sur la dernière ligne fonctionne mais n’est pas idiomatique.

... collecte tous les arguments supplémentaires que l’appelant passe et vous permet de les transmettre à une autre fonction. Par exemple, function(x, ...) mean(x, na.rm = TRUE, ...) passe tout ce qui dépasse x directement à mean(). C’est la manière standard d’écrire une fine surcouche sans retaper chaque option de la fonction que vous enveloppez.

Une fonction sans nom, écrite en ligne — généralement pour la passer à sapply(), lapply(), Map() ou Filter(). Écrivez-la function(x) x^2 ou, à partir de R 4.1, avec le raccourci \(x) x^2 ; les deux sont identiques. Utilisez-en une pour une aide jetable ; donnez un nom à la fonction lorsque vous l’appellerez plus d’une fois.

Testez vos connaissances

Écrivez une fonction percent_of(part, whole, digits = 1) qui renvoie part / whole * 100 arrondi à digits décimales — mais renvoie NA si whole vaut 0 (pas de division par zéro). Puis appelez-la avec et sans l’argument digits.

# Default digits = 1 in the signature.
# Guard: if (whole == 0) return(NA) before dividing.
percent_of <- function(part, whole, digits = 1) { if (whole == 0) return(NA) round(part / whole * 100, digits) } percent_of(45, 200) # 22.5 percent_of(45, 200, 3) # 22.5 percent_of(45, 0) # NA
percent_of <- function(part, whole, digits = 1) {
  if (whole == 0) return(NA)
  round(part / whole * 100, digits)
}

percent_of(45, 200)      # 22.5
percent_of(45, 200, 3)   # 22.5
percent_of(45, 0)        # NA
f <- function(x) {
  y <- x * 2
}
f(5)

A. 10, affiché à la console B. 10, mais renvoyé de façon invisible (rien ne s’affiche) C. Une erreur

Afficher la réponse

B. La dernière expression est une affectation (y <- x * 2), donc la fonction renvoie cette valeur (10) de façon invisible — c’est la valeur de retour, mais elle ne s’affiche pas automatiquement. Terminez sur un y nu pour la rendre visible.

Conclusion

Une fonction transforme du code répété en un seul outil nommé et testable : name <- function(args) { body }, avec des valeurs par défaut pour les arguments facultatifs, la dernière expression (ou un return() anticipé) comme résultat, une portée locale qui empêche les variables de fuir, ... pour transmettre les extras, des aides anonymes \(x) pour les usages ponctuels, et stop()/warning() pour échouer clairement. Écrivez-en une dès que vous vous surprenez à copier-coller — c’est le principe DRY qui paie.

Leçons connexes

Cette page vous a-t-elle été utile ?

Prouvez que vous savez le faire. Maîtrisez toute la série Les bases de R — suivez votre parcours, construisez des projets et obtenez un certificat.

Commencer gratuitement →

Passez à Pro — Prova illimité sur vos propres données et un certificat vérifiable qui atteste la compétence.

dès 15 $/mois facturé annuellement

Passer à Pro →

✓ Vous êtes Pro — continuez. The runtime is the judge.

Recevez les nouvelles leçons R & Python par e-mail

Pratique, reproductible, sans spam. Désinscription à tout moment.

Double opt-in. Nous ne partageons jamais votre e-mail.

Partager cette pageXLinkedInRedditHN
Note

Cette leçon est reproductible : chaque résultat de cette page a été produit par le code affiché — modifiez n’importe quel bloc et appuyez sur Run pour le reproduire dans votre navigateur. The runtime is the judge.

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {Écrire une fonction en R : arguments, valeurs par défaut et
    valeurs de retour},
  date = {2026-06-26},
  url = {https://www.datanovia.com/learn/programming/r-foundations/writing-functions},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“Écrire une fonction en R : arguments, valeurs par défaut et valeurs de retour.” 2026. June 26. https://www.datanovia.com/learn/programming/r-foundations/writing-functions.