Ajouter une colonne en R : dplyr mutate() & base R

Créer une nouvelle colonne à partir de colonnes existantes — une, plusieurs, conditionnelle ou sur de nombreuses colonnes

Ajoutez ou modifiez les colonnes d’un data frame en R avec dplyr mutate() (nouvelles colonnes à partir de colonnes existantes, colonnes conditionnelles avec if_else()/case_when(), plusieurs colonnes avec across(), placement avec .before/ .after, et transmute() pour ne conserver que les colonnes calculées) et les routes base R df$new <-, df[["new"]] <-, transform(), within() et ifelse() — les deux moteurs, le même résultat.

Date de publication

26 juin 2026

Modifié

12 juillet 2026

AstucePoints clés
  • dplyr : mutate(df, new = expr) ajoute une colonne à partir de colonnes existantes ; listez plusieurs paires new = expr pour en ajouter plusieurs d’un coup.
  • base R : df$new <- expr ou df[["new"]] <- expr fait la même chose ; transform() en ajoute plusieurs en un seul appel.
  • Colonnes conditionnelles : if_else() (un seul test) ou case_when() (plusieurs) en dplyr ; ifelse() en base R.
  • Plusieurs colonnes d’un coup : mutate(across(where(is.numeric), round)) transforme un ensemble de colonnes en une seule ligne.
  • Totaux cumulés par groupe : group_by(g) |> arrange(x) |> mutate(cs = cumsum(x)) en dplyr, ou ave(x, g, FUN = cumsum) en base R — une somme cumulée conserve chaque ligne (c’est un mutate, pas un summarise).
  • Les routes dplyr et base R donnent le même data frame — choisissez celle qui correspond à votre flux de travail.

Introduction

Vous avez un data frame et il vous faut une colonne qui n’y figure pas encore — un ratio de deux colonnes existantes, une valeur arrondie, une étiquette dérivée d’un seuil. Ajouter une colonne calculée est la deuxième étape de manipulation la plus courante après le renommage.

Deux routes font le travail, et vous croiserez les deux dans le code des autres :

  • dplyr mutate() — nommez la nouvelle colonne, donnez-lui une expression, terminé ; ça se lit comme une phrase.
  • base R — assignez dans df$new ou df[["new"]] ; aucun paquet nécessaire, fonctionne partout.

Cette leçon couvre une seule nouvelle colonne, plusieurs d’un coup, des colonnes conditionnelles, la transformation de nombreuses colonnes avec across(), et le contrôle de l’endroit où la nouvelle colonne atterrit. Les deux moteurs donnent le même résultat, vous pouvez donc lire n’importe quelle base de code et choisir celui que vous préférez.

Nous utilisons le jeu de données intégré mtcars — des mesures d’essais routiers de voitures, une ligne par modèle.

head(mtcars[, c("mpg", "wt", "hp", "cyl")], 4)
                mpg    wt  hp cyl
Mazda RX4      21.0 2.620 110   6
Mazda RX4 Wag  21.0 2.875 110   6
Datsun 710     22.8 2.320  93   4
Hornet 4 Drive 21.4 3.215 110   6

Ajouter une seule colonne

dplyr — mutate(new = expr)

mutate() prend le data frame, puis new_name = expression. Ici nous ajoutons kpl, kilomètres par litre, calculé à partir de mpg :

library(dplyr)
cars2 <- mutate(mtcars, kpl = mpg * 0.425)
head(cars2[, c("mpg", "kpl")], 4)
                mpg   kpl
Mazda RX4      21.0 8.925
Mazda RX4 Wag  21.0 8.925
Datsun 710     22.8 9.690
Hornet 4 Drive 21.4 9.095

La nouvelle colonne est ajoutée à droite ; chaque colonne existante reste intacte.

base R — df$new <-

Assignez l’expression dans un nouveau nom avec $. L’expression est vectorisée, elle s’exécute donc sur chaque ligne d’un coup :

cars2 <- mtcars
cars2$kpl <- cars2$mpg * 0.425
head(cars2[, c("mpg", "kpl")], 4)
                mpg   kpl
Mazda RX4      21.0 8.925
Mazda RX4 Wag  21.0 8.925
Datsun 710     22.8 9.690
Hornet 4 Drive 21.4 9.095

df[["new"]] <- expr fait exactement la même chose et est plus sûr lorsque le nom de la colonne est stocké dans une variable (df[[nm]] <- ...). Les deux produisent la même colonne kpl que mutate()mutate() est le raccourci lisible.

Ajouter plusieurs colonnes d’un coup

dplyr

Listez autant de paires new = expr que nécessaire, séparées par des virgules. Une paire peut même référencer une colonne créée plus tôt dans le même appel mutate() :

library(dplyr)
cars2 <- mutate(
  mtcars,
  kpl       = mpg * 0.425,
  power_wt  = hp / wt,
  efficient = kpl > 9          # uses kpl, just defined above
)
head(cars2[, c("mpg", "kpl", "power_wt", "efficient")], 4)
                mpg   kpl power_wt efficient
Mazda RX4      21.0 8.925 41.98473     FALSE
Mazda RX4 Wag  21.0 8.925 38.26087     FALSE
Datsun 710     22.8 9.690 40.08621      TRUE
Hornet 4 Drive 21.4 9.095 34.21462      TRUE

base R — transform()

transform() ajoute plusieurs colonnes en un seul appel, un peu comme mutate(). La seule limite : chaque expression ne voit que les colonnes d’origine, donc une nouvelle colonne ne peut pas référencer une autre nouvelle colonne dans le même appel.

cars2 <- transform(
  mtcars,
  kpl      = mpg * 0.425,
  power_wt = hp / wt
)
head(cars2[, c("mpg", "kpl", "power_wt")], 4)
                mpg   kpl power_wt
Mazda RX4      21.0 8.925 41.98473
Mazda RX4 Wag  21.0 8.925 38.26087
Datsun 710     22.8 9.690 40.08621
Hornet 4 Drive 21.4 9.095 34.21462

Lorsque vous avez besoin qu’une nouvelle colonne s’appuie sur une autre, enchaînez deux appels transform() ou utilisez simplement df$a <- ...; df$b <- df$a * 2. within() est l’outil base R qui peut référencer les colonnes au fur et à mesure — utile pour un bloc d’assignations liées :

cars2 <- within(mtcars, {
  kpl       <- mpg * 0.425
  efficient <- kpl > 9          # within() can see kpl
})
head(cars2[, c("mpg", "kpl", "efficient")], 4)
                mpg   kpl efficient
Mazda RX4      21.0 8.925     FALSE
Mazda RX4 Wag  21.0 8.925     FALSE
Datsun 710     22.8 9.690      TRUE
Hornet 4 Drive 21.4 9.095      TRUE

Ne conserver que les nouvelles colonnes — transmute()

mutate() conserve toutes les colonnes existantes et ajoute les nouvelles. Parfois vous voulez l’inverse : un data frame ne contenant que les colonnes que vous venez de calculer, les colonnes d’origine étant supprimées. C’est ce que fait transmute().

dplyr — transmute()

Même syntaxe que mutate() — des paires new_name = expression — mais le résultat ne conserve que ce que vous nommez :

library(dplyr)
cars2 <- transmute(mtcars, kpl = mpg * 0.425, power_wt = hp / wt)
head(cars2, 4)
                 kpl power_wt
Mazda RX4      8.925 41.98473
Mazda RX4 Wag  8.925 38.26087
Datsun 710     9.690 40.08621
Hornet 4 Drive 9.095 34.21462

Seules kpl et power_wt subsistent ; mpg, wt et toutes les autres colonnes sont supprimées.

transmute() est désormais supplantée dans dplyr — elle fonctionne toujours et ne va pas disparaître, mais le tidyverse vous oriente vers mutate() avec l’argument .keep = "none", qui fait exactement la même chose tout en partageant l’intégralité du comportement de mutate() :

library(dplyr)
cars2 <- mutate(mtcars, kpl = mpg * 0.425, power_wt = hp / wt, .keep = "none")
head(cars2, 4)
                 kpl power_wt
Mazda RX4      8.925 41.98473
Mazda RX4 Wag  8.925 38.26087
Datsun 710     9.690 40.08621
Hornet 4 Drive 9.095 34.21462

Utilisez celle qui vous semble la plus claire — transmute() reste le nom que la plupart des gens recherchent, et les deux renvoient le même data frame.

base R — construire un data frame ne contenant que les nouvelles colonnes

base R n’a pas de verbe unique pour « calculer et supprimer le reste », mais cela tient en une ligne : enveloppez les expressions dans data.frame() à l’intérieur de with(), en reportant les noms de lignes pour que le résultat s’aligne sur la source :

cars2 <- with(mtcars, data.frame(
  kpl       = mpg * 0.425,
  power_wt  = hp / wt,
  row.names = rownames(mtcars)
))
head(cars2, 4)
                 kpl power_wt
Mazda RX4      8.925 41.98473
Mazda RX4 Wag  8.925 38.26087
Datsun 710     9.690 40.08621
Hornet 4 Drive 9.095 34.21462

Les deux mêmes colonnes qu’avec transmute(). Supprimez la ligne row.names = si vous n’avez pas besoin des étiquettes de lignes d’origine.

Ajouter une colonne conditionnelle

Une tâche très courante : une nouvelle colonne dont la valeur dépend d’une condition — une étiquette, un indicateur, un groupe recodé.

Une condition — if_else() / ifelse()

Le if_else(test, yes, no) de dplyr est strict sur le type (yes et no doivent être du même type, ce qui détecte les bogues). Le ifelse() de base R est l’équivalent, un peu plus permissif :

library(dplyr)

# dplyr
d1 <- mutate(mtcars, size = if_else(wt > 3.5, "heavy", "light"))

# base R — same result
d2 <- mtcars
d2$size <- ifelse(d2$wt > 3.5, "heavy", "light")

identical(d1$size, d2$size)
[1] TRUE

Les lignes TRUE reçoivent "heavy", les lignes FALSE reçoivent "light" — les deux routes renvoient le même vecteur.

Plusieurs conditions — case_when()

Lorsque vous avez plus de deux issues, les ifelse() imbriqués deviennent vite illisibles. Le case_when() de dplyr liste des paires condition ~ value, évaluées de haut en bas ; .default attrape le reste :

library(dplyr)
cars2 <- mutate(
  mtcars,
  size = case_when(
    wt > 4   ~ "heavy",
    wt > 3   ~ "medium",
    .default = "light"
  )
)
table(cars2$size)

 heavy  light medium 
     4     12     16 

L’équivalent base R est cut() pour des seuils numériques, ou des ifelse() imbriqués. case_when() est l’outil le plus clair dès que vous avez trois cas ou plus.

Transformer de nombreuses colonnes avec across()

Pour appliquer la même fonction à plusieurs colonnes — toutes les arrondir, toutes les mettre à l’échelle — across() à l’intérieur de mutate() le fait en une seule ligne. Choisissez les colonnes avec un sélecteur comme where(is.numeric) ou c(mpg, wt, hp) :

library(dplyr)
cars2 <- mutate(mtcars, across(c(mpg, wt, hp), round))
head(cars2[, c("mpg", "wt", "hp")], 4)
               mpg wt  hp
Mazda RX4       21  3 110
Mazda RX4 Wag   21  3 110
Datsun 710      23  2  93
Hornet 4 Drive  21  3 110

L’équivalent base R utilise lapply() sur les colonnes choisies :

cars2 <- mtcars
cols <- c("mpg", "wt", "hp")
cars2[cols] <- lapply(cars2[cols], round)
head(cars2[, cols], 4)
               mpg wt  hp
Mazda RX4       21  3 110
Mazda RX4 Wag   21  3 110
Datsun 710      23  2  93
Hornet 4 Drive  21  3 110

Les deux arrondissent ces trois colonnes sur place. across() est la forme dplyr concise ; l’assignation lapply() est le raccourci base R.

Si vous avez déjà croisé les anciens mutate_all(), mutate_at() et mutate_if() dans du code existant, across() est leur unique remplacement moderne — la référence dplyr indique les trois comme supplantés : mutate(across(everything(), f)) remplace mutate_all(), mutate(across(c(col1, col2), f)) remplace mutate_at(), et mutate(across(where(is.numeric), f)) remplace mutate_if().

Placer la nouvelle colonne où vous voulez

Par défaut, une nouvelle colonne atterrit tout à droite. Les arguments .before / .after de dplyr l’insèrent plutôt à côté d’une colonne existante — pratique pour garder ensemble des variables liées :

library(dplyr)
cars2 <- mutate(mtcars, kpl = mpg * 0.425, .after = mpg)
names(cars2)[1:3]
[1] "mpg" "kpl" "cyl"

kpl se trouve maintenant juste après mpg. En base R, vous réorganiseriez vous-même les colonnes après l’assignation, par ex. cars2 <- cars2[, c("mpg", "kpl", setdiff(names(cars2), c("mpg", "kpl")))].

Sommes cumulées et totaux cumulés par groupe

Un total cumulé — une somme cumulée qui croît au fil des lignes — est un mutate(), pas un summarise() : il ajoute une colonne et conserve chaque ligne, au lieu de réduire chaque groupe à un seul nombre. Deux choses comptent : le groupe, pour que le total reparte pour chaque groupe, et l’ordre, pour que « cumulé » signifie bien ce que vous attendez.

Ici nous accumulons la puissance (hp) au sein de chaque groupe de cylindres (cyl), du plus faible hp au plus élevé :

dplyr — group_by() puis mutate(cumsum())

library(dplyr)
mtcars |>
  group_by(cyl) |>
  arrange(hp, .by_group = TRUE) |>
  mutate(cum_hp = cumsum(hp)) |>
  select(cyl, hp, cum_hp) |>
  head(8)
# A tibble: 8 × 3
# Groups:   cyl [1]
    cyl    hp cum_hp
  <dbl> <dbl>  <dbl>
1     4    52     52
2     4    62    114
3     4    65    179
4     4    66    245
5     4    66    311
6     4    91    402
7     4    93    495
8     4    95    590

cum_hp repart au premier véhicule de chaque groupe cyl et croît à mesure que hp s’accumule. Retirez le group_by() et vous obtenez un seul total cumulé sur toute la table ; retirez l’arrange() et le total suit l’ordre des lignes actuel des données — rarement ce que vous voulez pour un total cumulé.

base R — ave(x, group, FUN = cumsum)

ave() applique une fonction au sein des groupes. Ordonnez d’abord les données pour que la direction cumulative soit définie, puis accumulez au sein de chaque cyl :

m <- mtcars[order(mtcars$cyl, mtcars$hp), ]
m$cum_hp <- ave(m$hp, m$cyl, FUN = cumsum)
head(m[, c("cyl", "hp", "cum_hp")], 8)
               cyl hp cum_hp
Honda Civic      4 52     52
Merc 240D        4 62    114
Toyota Corolla   4 65    179
Fiat 128         4 66    245
Fiat X1-9        4 66    311
Porsche 914-2    4 91    402
Datsun 710       4 93    495
Merc 230         4 95    590

Les deux donnent le même cum_hp. Le même schéma couvre le reste de la famille cumulative — remplacez cumsum par cumprod (produit cumulé), cummax (maximum cumulé) ou cummin (minimum cumulé) ; pour une moyenne cumulée, dplyr propose cummean() (en base R, cumsum(x) / seq_along(x) au sein de chaque groupe).

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 ajouter des colonnes à vos propres données — il s’exécute dans votre navigateur via webR (aucune installation).

🟢 Avec un agent IA

Collez un head() de vos propres données et demandez à Prova « ajoute une colonne signalant les lignes où le chiffre d’affaires dépasse l’objectif, plus une colonne de marge bénéficiaire » — elle écrit l’appel mutate() / case_when(). Comme le runtime est juste là, vous l’exécutez pour confirmer que les nouvelles colonnes contiennent les bonnes valeurs sur vos données, et non une supposition qui semble plausible. Demander à Prova →

Vous travaillez en Python ? Un guide pandas assign / df["new"] = ... arrive dans la série Python.

Problèmes fréquents

Votre nouvelle colonne est recyclée ou n’a qu’une seule valeur. mutate() et df$new <- attendent une expression vectorisée qui renvoie une valeur par ligne. Si vous appelez un résumé comme mean(mpg), il renvoie un seul nombre qui est recyclé sur chaque ligne — vous voulez généralement mpg - mean(mpg) (toujours par ligne) ou plutôt un résumé par groupe (voir résumer par groupe).

if_else() génère une erreur mais pas ifelse(). Le if_else() de dplyr est strict : les valeurs true et false doivent être du même type, et il ne convertit pas silencieusement. Cette rigueur est un atout — elle détecte if_else(x > 0, "yes", 0) (caractère vs numérique) comme un bogue. Utilisez des types concordants, ou repliez-vous sur ifelse() de base si vous voulez vraiment une conversion.

transform() ne voit pas une colonne que vous venez de créer. Chaque expression dans un seul appel transform() ne voit que les colonnes d’origine. Pour construire une nouvelle colonne à partir d’une autre, utilisez deux étapes (df$a <- ...; df$b <- df$a * 2), within(), ou un seul mutate() (qui peut enchaîner au sein d’un même appel).

Questions fréquentes

Deux routes équivalentes. dplyr : mutate(df, new = expression). Base R : df$new <- expression (ou df[["new"]] <- expression). L’expression est vectorisée, elle calcule donc la nouvelle colonne sur chaque ligne d’un coup.

Pour un seul test, utilisez mutate(df, flag = if_else(x > 0, "pos", "neg")) en dplyr, ou df$flag <- ifelse(df$x > 0, "pos", "neg") en base R. Pour plusieurs issues, utilisez le case_when(cond1 ~ val1, cond2 ~ val2, .default = "other") de dplyr.

Le if_else() de dplyr est strict sur le type — les valeurs true et false doivent être du même type, et il préserve correctement les facteurs et les dates. Le ifelse() de base R est plus permissif et convertit les types, ce qui est pratique mais peut masquer des bogues. Les deux choisissent élément par élément en fonction du test.

En dplyr, listez plusieurs paires dans un seul appel mutate() : mutate(df, a = x*2, b = x+y) — et une paire ultérieure peut utiliser une paire antérieure. En base R, utilisez transform(df, a = x*2, b = x+y) (chacune ne voit que les colonnes d’origine) ou assignez-les une par une avec df$a <- ....

mutate() conserve toutes les colonnes existantes et ajoute les nouvelles ; transmute() ne renvoie que les colonnes que vous calculez et supprime le reste. transmute() est désormais supplantée au profit de mutate(df, ..., .keep = "none"), qui fait la même chose. En base R, conservez tout avec df$new <- ..., ou construisez un nouveau data.frame() ne contenant que les colonnes calculées pour supprimer le reste.

Utilisez across() à l’intérieur de mutate() : mutate(df, across(where(is.numeric), round)) arrondit chaque colonne numérique. En base R, réassignez le résultat de lapply() sur les colonnes choisies : df[cols] <- lapply(df[cols], round).

Groupez, ordonnez, puis mutate() avec cumsum() : df |> group_by(g) |> arrange(x) |> mutate(cs = cumsum(x)) fait repartir le total cumulé pour chaque groupe. En base R, la solution en une ligne est ave(df$x, df$g, FUN = cumsum) (ordonnez d’abord le data frame pour que la direction cumulative soit définie). Comme un total cumulé conserve une valeur par ligne, c’est un mutate, pas un summarise. Remplacez cumsum par cumprod, cummax ou cummin pour les autres fonctions cumulatives.

Testez vos connaissances

À partir de mtcars, ajoutez (1) une colonne hp_per_ton = hp / wt, et (2) une colonne gas qui vaut "thirsty" quand mpg < 20 et "economical" sinon. Faites-le avec dplyr mutate(), puis confirmez avec un rapide head().

# hp_per_ton is hp divided by wt.
# if_else(test, yes, no): the test is mpg < 20.
library(dplyr) result <- mtcars |> mutate( hp_per_ton = hp / wt, gas = if_else(mpg < 20, "thirsty", "economical") ) head(result[, c("hp", "wt", "hp_per_ton", "mpg", "gas")], 5)
library(dplyr)

result <- mtcars |>
  mutate(
    hp_per_ton = hp / wt,
    gas        = if_else(mpg < 20, "thirsty", "economical")
  )

head(result[, c("hp", "wt", "hp_per_ton", "mpg", "gas")], 5)

Vous voulez une nouvelle colonne area = width * height dans le data frame df. Laquelle est correcte ?

A. mutate(df, width * height = area) B. df$area <- df$width * df$height C. df["area"] <- mean(df$width * df$height)

Afficher la réponse

B. Base R assigne l’expression par ligne dans le nouveau nom. A inverse l’ordre new = expr de dplyr (et n’est pas valide). C calcule une seule moyenne et la recycle sur chaque ligne — perdant les valeurs par ligne que vous vouliez. La forme dplyr serait mutate(df, area = width * height).

Conclusion

Ajouter une colonne se résume à deux outils équivalents : dplyr mutate(new = expr) (avec if_else()/case_when() pour les conditions et across() pour plusieurs colonnes d’un coup), ou l’assignation base R dans df$new / df[["new"]] (avec transform()/within() pour plusieurs et ifelse() pour les conditions). Les deux donnent le même data frame — utilisez mutate() pour des pipelines lisibles, base R quand vous voulez zéro dépendance.

Leçons connexes

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

Prouvez que vous savez le faire. Maîtrisez toute la série Manipulation de données en R et Python — 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 présenté — 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 = {Ajouter une colonne en R : dplyr mutate() \& base R},
  date = {2026-06-26},
  url = {https://www.datanovia.com/learn/programming/data-wrangling/mutate-columns-in-r},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“Ajouter une colonne en R : dplyr mutate() & base R.” 2026. June 26. https://www.datanovia.com/learn/programming/data-wrangling/mutate-columns-in-r.