La famille apply en R : apply, lapply, sapply, vapply, mapply, tapply

Exécutez une fonction sur chaque élément, colonne ou groupe — sans écrire de boucle

Un guide pratique de la famille apply de R : apply() sur les lignes/colonnes d’une matrice, lapply() et sapply() sur les listes et les vecteurs, le vapply() à typage sûr, mapply() sur plusieurs entrées, et tapply() par groupe — ainsi que Map(), Reduce() et Filter(). Apprenez ce que chacune retourne, quand utiliser laquelle, et pourquoi apply se lit souvent mieux qu’une boucle for.

Date de publication

26 juin 2026

Modifié

7 juillet 2026

AstucePoints clés
  • lapply() exécute une fonction sur une liste/un vecteur et retourne toujours une liste ; sapply() fait de même mais simplifie en vecteur ou matrice quand c’est possible.
  • vapply() est sapply() avec un modèle de sortie obligatoire — utilisez-le dans vos scripts pour qu’un type inattendu ne puisse pas passer inaperçu.
  • apply() s’exécute sur les marges d’une matrice : MARGIN = 1 pour les lignes, MARGIN = 2 pour les colonnes.
  • tapply() découpe un vecteur selon un facteur de regroupement et applique une fonction par groupe ; mapply() parcourt plusieurs vecteurs en parallèle.
  • Map(), Reduce() et Filter() couvrent le reste de la boîte à outils fonctionnelle : application par paires, repliement cumulatif et filtrage par prédicat.
  • Privilégiez apply plutôt qu’une boucle for pour la clarté — une seule ligne qui dit « fais ceci à chacun » — non parce que c’est toujours plus rapide.

Introduction

Vous avez une liste, un vecteur ou les colonnes d’une matrice, et vous voulez exécuter la même fonction sur chaque morceau — la moyenne de chaque colonne, la longueur de chaque élément, un résumé par groupe. Une boucle for fonctionne, mais elle enfouit une idée d’une ligne sous trois lignes de gestion comptable (allouer un résultat, l’indexer, l’agrandir).

La famille apply de R exprime cette idée en une ligne : applique cette fonction à chacun de ceux-ci. L’astuce consiste à choisir le bon membre, car ils diffèrent par ce sur quoi ils itèrent et ce qu’ils retournent :

  • lapply() / sapply() — sur une liste ou un vecteur → une liste (lapply) ou un vecteur/matrice simplifié (sapply).
  • vapply() — comme sapply() mais vous déclarez le type de retour, donc il ne vous surprend jamais.
  • apply() — sur les lignes ou colonnes d’une matrice.
  • tapply() — sur un vecteur découpé par groupe.
  • mapply() — sur plusieurs vecteurs à la fois.

Cette leçon passe en revue chacune avec un petit exemple exécutable, indique quand y recourir, et se termine par Map()/Reduce()/Filter() et une note sur l’alternative moderne purrr.

lapply() — retourne toujours une liste

lapply(X, FUN) appelle FUN sur chaque élément de X et retourne une liste de même longueur que X. La liste est le choix par défaut sûr : elle peut contenir un résultat de n’importe quelle forme, donc rien n’est forcé dans un vecteur.

Ici, nous calculons la moyenne de trois vecteurs numériques contenus dans une liste :

num_list <- list(a = 1:5, b = 6:10, c = 11:15)
lapply(num_list, mean)
$a
[1] 3

$b
[1] 8

$c
[1] 13

La sortie est une liste nommée — un élément par entrée, chacun portant sa mean. Utilisez lapply() chaque fois que le résultat par élément peut être plus qu’un simple nombre (un objet de modèle, un data frame, un vecteur de longueur variable) ; la liste le contient sans broncher.

sapply() — simplifier en vecteur quand c’est possible

sapply() est lapply() plus une étape de simplification. Si chaque résultat est une valeur unique, il retourne un vecteur nommé ; si chaque résultat est un vecteur de même longueur, il retourne une matrice. Même appel, sortie plus conviviale :

num_list <- list(a = 1:5, b = 6:10, c = 11:15)
sapply(num_list, mean)
 a  b  c 
 3  8 13 

Vous obtenez maintenant un simple vecteur numérique nommé au lieu d’une liste — plus facile à lire et à transmettre. sapply() est la fonction de commodité du quotidien pour le travail interactif.

Le piège tient au terme quand c’est possible : sapply() décide de la forme à partir des résultats, donc le même code peut retourner un vecteur un jour et une liste le lendemain si les données changent. Cette imprévisibilité est exactement ce que vapply() corrige.

vapply()sapply() avec un contrat de type

vapply() ajoute un argument obligatoire, FUN.VALUE, un modèle décrivant chaque résultat. Si un résultat ne correspond pas, vapply() lève une erreur au lieu de changer silencieusement de forme — ce qui est exactement ce que vous voulez dans un script que vous réexécuterez sur de nouvelles données.

Ici, numeric(1) indique « chaque résultat est un nombre unique » :

vapply(1:5, function(x) sqrt(x), FUN.VALUE = numeric(1))
[1] 1.000000 1.414214 1.732051 2.000000 2.236068

Utilisez vapply() dans le code de production et les packages ; utilisez sapply() dans la console. Ils se lisent presque de la même façon, mais vapply() transforme une surprise de type silencieuse en une erreur bruyante et précoce.

apply() — sur les lignes ou colonnes d’une matrice

apply(X, MARGIN, FUN) fonctionne sur une matrice ou un tableau. MARGIN = 1 applique FUN à chaque ligne ; MARGIN = 2 à chaque colonne. Construisons une petite matrice et faisons la somme dans les deux sens :

m <- matrix(1:12, nrow = 3)
m
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
apply(m, 1, sum)   # one sum per row
[1] 22 26 30
apply(m, 2, sum)   # one sum per column
[1]  6 15 24 33

Le moyen mnémotechnique : 1 = lignes, 2 = colonnes — le même ordre que dim() et m[row, col]. Pour les sommes et moyennes de lignes/colonnes courantes, il existe des aides dédiées plus rapides (rowSums(), colMeans()), mais apply() gère n’importe quelle fonction, y compris une que vous écrivez vous-même.

tapply() — appliquer par groupe

tapply(X, INDEX, FUN) découpe le vecteur X selon le facteur INDEX et applique FUN à chaque groupe — un résumé par groupe en un seul appel. En utilisant les données intégrées ToothGrowth, la longueur moyenne des dents par dose :

tapply(ToothGrowth$len, ToothGrowth$dose, mean)
   0.5      1      2 
10.605 19.735 26.100 

Une valeur par niveau de dose. tapply() est le « grouper puis résumer » de base R pour un seul vecteur ; pour des résumés groupés sur plusieurs colonnes, vous recourriez à aggregate() ou à un outil de manipulation de données, mais pour un vecteur par un facteur, tapply() est le plus direct.

mapply() — parcourir plusieurs entrées en parallèle

Les membres de la famille apply vus jusqu’ici itèrent sur une seule chose. mapply() (apply multivarié) parcourt plusieurs vecteurs à la fois, en passant le premier élément de chacun à FUN, puis le deuxième, et ainsi de suite :

mapply(function(x, y) x + y, 1:5, 6:10)
[1]  7  9 11 13 15

L’élément 1 est 1 + 6, l’élément 2 est 2 + 7, et ainsi de suite. Recourez à mapply() quand une fonction a besoin d’un argument de chacun de deux vecteurs ou plus de même longueur — construire des chemins de fichiers à partir d’une racine et d’un suffixe, formater une étiquette à partir d’une valeur et d’une unité.

Map(), Reduce(), Filter() — le reste de la boîte à outils

Trois autres fonctionnelles complètent la programmation fonctionnelle de base R :

  • Map() est mapply() qui retourne toujours une liste (sans simplification) — l’application parallèle sûre pour les listes.
  • Reduce() replie une fonction binaire sur un vecteur, en propageant le résultat courant — une combinaison cumulative.
  • Filter() conserve les éléments pour lesquels un prédicat retourne TRUE.
# Map: pairwise, returns a list
Map(function(x, y) x * y, 1:3, 4:6)
[[1]]
[1] 4

[[2]]
[1] 10

[[3]]
[1] 18
# Reduce: 1+2, then +3, then +4, then +5  ->  15
Reduce(`+`, 1:5)
[1] 15
# Filter: keep the even numbers
Filter(function(x) x %% 2 == 0, 1:10)
[1]  2  4  6  8 10

Reduce() avec accumulate = TRUE retourne chaque étape intermédiaire (un total courant), ce qui est pratique pour les calculs cumulatifs.

Pourquoi apply plutôt qu’une boucle for

La raison honnête est la clarté, non la vitesse brute. Un appel apply exprime l’intention en une ligne — transformer chaque élément — sans vecteur de résultat à préallouer ni indice à gérer, donc il y a moins de risques d’erreur :

x <- list(1:5, 6:10, 11:15)

# for loop: allocate, index, assign
out <- numeric(length(x))
for (i in seq_along(x)) out[i] <- sum(x[[i]])
out
[1] 15 40 65
# sapply: the same idea, one line
sapply(x, sum)
[1] 15 40 65

Une boucle for moderne et bien écrite qui préalloue son résultat (comme ci-dessus) est à peu près aussi rapide que sapply() — toutes deux appellent votre fonction une fois par élément en R. Le vrai gain de vitesse vient des fonctions vectorisées comme sum() ou colMeans() qui poussent toute la boucle dans le C ; les fonctions apply concernent la lisibilité et la structure, la vectorisation concerne la vitesse. Utilisez apply pour rendre l’itération lisible ; utilisez une fonction vectorisée quand il en existe une.

Essayez en direct

Les blocs ci-dessus ont été exécutés au moment de la construction. Modifiez celui-ci et appuyez sur Run pour essayer la famille apply par vous-même — il s’exécute dans votre navigateur via webR, sans installation.

🟢 Avec un agent IA

Vous avez une boucle for que vous aimeriez nettoyer ? Collez-la et demandez à Prova « réécris ceci en appel apply » — elle choisit le bon membre de la famille et la réécrit, et parce que le runtime est juste ici, vous exécutez les deux et vérifiez qu’ils retournent la même chose sur vos données. Demander à Prova →

Vous préférez le tidyverse ? Les map(), map_dbl(), map_chr() et map2() de purrr sont les équivalents modernes de lapply/sapply/mapply, avec des types de retour cohérents (un guide purrr arrive dans la série manipulation de données). La famille apply de base n’a besoin d’aucun package et est ce que vous rencontrerez dans la plupart du code existant.

Problèmes courants

sapply() a retourné une liste alors que j’attendais un vecteur. sapply() ne simplifie que lorsque chaque résultat a la même forme. Si un élément donne une longueur différente (ou NULL), il revient à une liste. Soit corrigez la fonction pour que chaque résultat corresponde, soit passez à vapply() avec un FUN.VALUE explicite pour que l’incohérence lève une erreur bruyante au lieu de changer le type de sortie.

apply() a transformé mes nombres en caractères. apply() convertit d’abord l’entrée en matrice, et une matrice ne contient qu’un seul type. Si votre data frame mélange des colonnes numériques et caractères, les nombres deviennent des chaînes. N’utilisez apply() que sur des données entièrement numériques (ou une matrice) ; pour un data frame, itérez plutôt sur les colonnes avec sapply(df, FUN), ce qui conserve à chaque colonne son propre type.

tapply() a donné NA pour un groupe. Les valeurs manquantes se propagent — la mean() d’un groupe contenant NA vaut NA. Passez l’argument : tapply(x, g, mean, na.rm = TRUE). Les arguments supplémentaires après FUN sont transmis à FUN pour chaque groupe.

Questions fréquentes

Les deux appliquent une fonction à chaque élément d’une liste ou d’un vecteur. lapply() retourne toujours une liste — un élément par entrée. sapply() retourne les mêmes résultats mais les simplifie : un vecteur quand chaque résultat est une valeur unique, une matrice quand chacun est un vecteur de même longueur, et une liste seulement quand il ne peut pas simplifier. Utilisez lapply() quand les résultats varient en forme, sapply() pour une sortie nette dans la console.

Utilisez une fonction apply quand le corps de la boucle revient à « faire la même chose à chaque élément » — elle exprime cette intention en une ligne, sans vecteur de résultat à préallouer ni indice à gérer. Utilisez une boucle for quand les itérations dépendent les unes des autres (chaque étape a besoin du résultat précédent) ou quand la logique est trop complexe pour se lire comme un seul appel. apply concerne la clarté ; pour la vitesse brute, préférez une fonction vectorisée comme sum() ou colMeans().

Généralement pas de beaucoup. Les fonctions apply appellent toujours votre fonction une fois par élément en R, exactement comme une boucle bien écrite qui préalloue son résultat. Les grands gains de vitesse viennent des fonctions vectorisées (implémentées en C) telles que rowSums() ou x * 2, qui traitent tout le vecteur d’un coup. Choisissez apply pour une structure lisible, et une fonction vectorisée quand il en existe une pour la tâche.

MARGIN indique à apply() quelle dimension d’une matrice parcourir : 1 applique la fonction à chaque ligne, 2 à chaque colonne. L’ordre correspond à m[row, column] et dim(). Ainsi apply(m, 2, mean) donne une moyenne par colonne ; apply(m, 1, mean) en donne une par ligne.

vapply() exige un modèle FUN.VALUE décrivant chaque résultat, donc il lève une erreur immédiatement si un résultat a le mauvais type ou la mauvaise longueur, au lieu de retourner silencieusement une forme différente (ce que sapply() peut faire). Cette sûreté fait de vapply() le meilleur choix dans les scripts, les fonctions et les packages que vous réexécuterez sur des données que vous n’avez pas encore vues.

Testez vos connaissances

En utilisant les données intégrées mtcars, calculez la moyenne de chaque colonne. D’abord avec sapply() sur le data frame, puis avec apply() sur MARGIN = 2, et confirmez que les deux donnent les mêmes nombres.

# sapply(df, FUN) applies FUN to each column of a data frame.
# apply(matrix, MARGIN, FUN): MARGIN = 2 means columns.
sapply_means <- sapply(mtcars, mean) apply_means <- apply(as.matrix(mtcars), 2, mean) all.equal(sapply_means, apply_means) # TRUE
sapply_means <- sapply(mtcars, mean)
apply_means  <- apply(as.matrix(mtcars), 2, mean)
all.equal(sapply_means, apply_means)  # TRUE

Vous exécutez chacun de ceux-ci sur list(a = 1:3, b = 4:6). Lequel est garanti de retourner une liste ?

A. sapply(x, sum) B. lapply(x, sum) C. vapply(x, sum, numeric(1))

Afficher la réponse

B. lapply() retourne toujours une liste. sapply() simplifie ces résultats à valeur unique en un vecteur nommé, et vapply() retourne un vecteur correspondant à son modèle numeric(1). Seul lapply() est garanti de conserver la structure de liste.

Conclusion

La famille apply est la façon de base R de dire « fais ceci à chacun » sans la gestion comptable d’une boucle. Choisissez selon ce sur quoi vous itérez et ce que vous voulez en retour : lapply() pour une liste en sortie, sapply() pour simplifier, vapply() pour un script à typage sûr, apply() pour les lignes/colonnes d’une matrice, tapply() par groupe, et mapply()/Map() sur plusieurs entrées — avec Reduce() et Filter() pour le repliement et le filtrage. Recourez-y pour la clarté ; recourez à une fonction vectorisée quand vous avez besoin de vitesse.

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 = {La famille apply en R : apply, lapply, sapply, vapply,
    mapply, tapply},
  date = {2026-06-26},
  url = {https://www.datanovia.com/learn/programming/r-foundations/apply-family},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“La famille apply en R : apply, lapply, sapply, vapply, mapply, tapply.” 2026. June 26. https://www.datanovia.com/learn/programming/r-foundations/apply-family.