library(officer)
library(ggplot2)
# A self-contained chart: mean tooth length by dose, grouped by supplement
tg <- aggregate(len ~ dose + supp, data = ToothGrowth, FUN = mean)
tg$dose <- factor(tg$dose)
p <- ggplot(tg, aes(x = dose, y = len, fill = supp)) +
geom_col(position = "dodge") +
scale_fill_viridis_d(end = 0.85) +
labs(x = "Dose (mg/day)", y = "Mean length", fill = "Supplement") +
theme_minimal(base_size = 13)
# Build the slide: start a deck, add a slide, fill the placeholders
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = "Mean tooth length by dose",
location = ph_location_type(type = "title"))
doc <- ph_with(doc, value = p,
location = ph_location_type(type = "body"))
print(doc, target = "cover.pptx") # write the real .pptx fileCréer des présentations PowerPoint depuis R avec officer
Générez des diapositives .pptx — titres, texte à puces, tableaux et graphiques — depuis R
Apprenez à créer des présentations PowerPoint depuis R avec le package officer — ajoutez des diapositives avec titres, texte à puces, tableaux via flextable et graphiques ggplot2, et générez une présentation .pptx par programmation. Le remplaçant moderne du package ReporteRs, désormais retiré.
- Construire une présentation PowerPoint entièrement en R avec
officer—read_pptx()→add_slide()→ph_with()→print(). - Remplir chaque diapositive avec les quatre éléments essentiels : un titre, du texte à puces, un tableau (via
flextable) et un graphiqueggplot2. - Garder les graphiques modifiables dans PowerPoint (véritable vecteur) avec
rvg::dml(), ou les intégrer comme une image nette. - Partir d’un modèle d’entreprise pour que chaque présentation soit aux couleurs de la marque — polices, couleurs, logo.
- Pourquoi
officerest le remplaçant moderne du packageReporteRs, désormais retiré.
Votre analyse est en R, mais votre auditoire vit dans PowerPoint. Redessiner chaque graphique à la main dans un fichier .pptx est l’étape lente et source d’erreurs — et dès que les données changent, tout est à refaire. officer comble cet écart : il écrit de vrais fichiers Microsoft PowerPoint par programmation, si bien qu’un seul script R produit une présentation finie que vous relancez chaque fois que les chiffres évoluent.
Si vous avez appris ce flux de travail il y a des années avec ReporteRs, ce package a disparu (il dépendait de Java et a été archivé de CRAN). officer en est le successeur spirituel — pas de Java, du R pur, activement maintenu, et il s’associe naturellement au reporting Office sous R Markdown / Quarto via officedown. Ce billet est la recette pratique, prête à copier-coller.
Ce que produit officer
Voici une seule diapositive construite depuis R — un espace réservé de titre et un graphique ggplot2 déposé dans l’espace réservé de contenu. Le code R ci-dessous est exactement ce qui l’a générée ; la seule chose masquée est l’étape qui convertit le .pptx final en image pour pouvoir l’afficher ici.

C’est une véritable diapositive .pptx — ouvrez-la dans PowerPoint et le titre est du texte modifiable, le graphique est une véritable image sur la diapositive. Tout ce qui suit décompose ce schéma en ses éléments.
De ReporteRs à officer : ce qui a changé
Si vous cherchez ReporteRs et tombez sur des liens morts, voici la correspondance en une ligne. Toute l’API doc <- pptx(); addSlide(); addTitle(); writeDoc() est retirée. Les équivalents officer sont :
| ReporteRs (obsolète) | officer (à utiliser) |
|---|---|
pptx() |
read_pptx() |
addSlide(doc, layout) |
add_slide(doc, layout, master) |
addTitle() / addParagraph() |
ph_with(doc, value, location = ...) |
addFlexTable(FlexTable(x)) |
ph_with(doc, flextable(x), ...) |
addPlot(doc, fun) |
ph_with(doc, gg_or_dml, ...) |
writeDoc(doc, file) |
print(doc, target = file) |
Le modèle mental est plus simple que l’ancien : vous n’appelez pas une fonction différente par type de contenu — vous appelez ph_with() et vous lui passez ce que vous voulez (du texte, une liste à puces, un flextable, un graphique), en lui indiquant où le placer avec une fonction auxiliaire ph_location_*().
Installer et charger officer
Il vous faut trois packages : officer pour le document, flextable pour les tableaux et rvg pour les graphiques vectoriels modifiables.
install.packages(c("officer", "flextable", "rvg"))library(officer)
library(flextable)
library(rvg)Construire une présentation en quatre étapes
Chaque script PowerPoint officer répète les mêmes quatre gestes. Démarrez une présentation à partir du modèle par défaut avec read_pptx(), ajoutez une diapositive avec add_slide() (en nommant une disposition et son masque), remplissez les espaces réservés de la diapositive avec ph_with(), et écrivez le fichier avec print(). Voici la plus petite présentation complète :
library(officer)
doc <- read_pptx() # 1. start from the default template
doc <- add_slide(doc, layout = "Title and Content", # 2. add a slide
master = "Office Theme")
doc <- ph_with(doc, value = "Hello from R", # 3. fill the title placeholder
location = ph_location_type(type = "title"))
doc <- ph_with(doc, value = "Built entirely with officer",
location = ph_location_type(type = "body"))
print(doc, target = "hello.pptx") # 4. write the .pptxDeux idées font le gros du travail. Une disposition est un gabarit de diapositive (« Title Slide », « Title and Content », « Two Content »…) ; elle détermine quels espaces réservés existent. Un emplacement d’espace réservé — ph_location_type("title"), ph_location_type("body") — indique à ph_with() dans quelle zone déposer le contenu. Adaptez la disposition au contenu dont vous disposez, et les espaces réservés s’alignent d’eux-mêmes.
Voir quelles dispositions votre modèle propose
Les dispositions viennent du modèle, alors listez-les avant d’écrire. layout_summary() renvoie chaque paire disposition/masque que vous pouvez passer à add_slide() :
layout_summary(read_pptx()) layout master
1 Title Slide Office Theme
2 Title and Content Office Theme
3 Section Header Office Theme
4 Two Content Office Theme
5 Comparison Office Theme
6 Title Only Office Theme
7 Blank Office Theme
Le thème Office par défaut fournit l’ensemble habituel — une Title Slide pour la couverture, Title and Content pour un seul graphique ou tableau, Two Content pour une mise côte à côte, et Section Header pour scinder une longue présentation. N’utilisez que les noms qui figurent dans cette liste ; une faute de frappe fait silencieusement échouer le placement de votre contenu.
Ajouter une diapositive de titre
Une diapositive de couverture utilise la disposition Title Slide, qui expose deux espaces réservés spéciaux : ctrTitle (le grand titre centré) et subTitle. Adressez-les par type, comme le corps :
library(officer)
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title Slide", master = "Office Theme")
doc <- ph_with(doc, value = "Quarterly Results",
location = ph_location_type(type = "ctrTitle"))
doc <- ph_with(doc, value = "Generated from R with officer",
location = ph_location_type(type = "subTitle"))
print(doc, target = "title.pptx")Ajouter du texte à puces (listes ordonnées et non ordonnées)
Le texte simple s’insère sous forme de chaîne de caractères. Pour des puces à plusieurs niveaux, enveloppez vos éléments dans unordered_list() et donnez à chacun un niveau via level_list — le niveau 1 est une puce de premier niveau, le niveau 2 un retrait. Cela remplace l’ancienne gymnastique addParagraph(..., par.properties = ...) :
library(officer)
bullets <- unordered_list(
str_list = c("Revenue up 12% YoY",
"Driven by the EMEA region",
"APAC flat",
"New product line launches Q3"),
level_list = c(1, 2, 2, 1)
)
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = "Highlights", location = ph_location_type(type = "title"))
doc <- ph_with(doc, value = bullets, location = ph_location_type(type = "body"))
print(doc, target = "bullets.pptx")Les deux éléments en retrait se placent sous « Revenue up 12% YoY » comme sous-puces ; le dernier élément revient au niveau supérieur. Remplacez unordered_list() par un simple block_list() de paragraphes fpar() lorsque vous avez besoin de listes numérotées ou d’une mise en forme mixte.
Ajouter un tableau avec flextable
flextable est le package compagnon pour les tableaux — il construit un objet tableau stylé que ph_with() dépose directement sur une diapositive. Créez le tableau, appliquez-lui un thème, puis placez-le dans l’espace réservé de contenu :
library(officer)
library(flextable)
ft <- flextable(head(iris, 5))
ft <- theme_vanilla(ft) # clean, presentation-ready styling
ft <- autofit(ft) # size columns to their content
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = "First rows of iris", location = ph_location_type(type = "title"))
doc <- ph_with(doc, value = ft, location = ph_location_type(type = "body"))
print(doc, target = "table.pptx")flextable vous donne un contrôle total — bg() pour les rayures zébrées, bold() pour les en-têtes, color() pour la mise en forme conditionnelle — et le même objet tableau se rend aussi vers Word, HTML et PDF, si bien qu’une seule définition de tableau sert toutes les sorties.
Ajouter un graphique ggplot2 — image ou vecteur modifiable
Vous avez deux façons de placer un graphique sur une diapositive, et le choix a son importance. Passez à ph_with() l’objet ggplot directement et officer l’intègre comme une image haute résolution — simple et parfaite au pixel près. Enveloppez-le plutôt dans rvg::dml() et il devient un graphique vectoriel PowerPoint natif et modifiable — votre collègue peut cliquer sur une barre pour la recolorer, déplacer une étiquette ou le réadapter au modèle maison.
library(officer)
library(rvg)
library(ggplot2)
tg <- aggregate(len ~ dose + supp, data = ToothGrowth, FUN = mean)
tg$dose <- factor(tg$dose)
p <- ggplot(tg, aes(x = dose, y = len, fill = supp)) +
geom_col(position = "dodge") +
scale_fill_viridis_d(end = 0.85) +
labs(x = "Dose (mg/day)", y = "Mean length", fill = "Supplement") +
theme_minimal(base_size = 13)
doc <- read_pptx()
# Slide 1 — plot embedded as an image (simplest)
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = "Chart as an image", location = ph_location_type(type = "title"))
doc <- ph_with(doc, value = p, location = ph_location_type(type = "body"))
# Slide 2 — same plot as editable vector graphics
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = "Chart as editable vector", location = ph_location_type(type = "title"))
doc <- ph_with(doc, value = dml(ggobj = p), location = ph_location_type(type = "body"))
print(doc, target = "charts.pptx")C’est exactement le problème que poursuivaient les anciens tutoriels ReporteRs — garder de beaux graphiques R aussi beaux dans PowerPoint. rvg::dml() est la réponse : pas de capture d’écran floue, pas de redessin, un graphique vectoriel qui reste net à n’importe quel zoom et modifiable en pleine réunion.
Assembler le tout : une présentation complète
Comme read_pptx() → add_slide() → ph_with() renvoie le document à chaque fois, vous enchaînez les diapositives en un seul pipeline. Voici une présentation de quatre diapositives — couverture, puces, tableau, graphique — depuis un seul script :
library(officer)
library(flextable)
library(rvg)
library(ggplot2)
tg <- aggregate(len ~ dose + supp, data = ToothGrowth, FUN = mean)
tg$dose <- factor(tg$dose)
p <- ggplot(tg, aes(x = dose, y = len, fill = supp)) +
geom_col(position = "dodge") +
scale_fill_viridis_d(end = 0.85) +
labs(x = "Dose (mg/day)", y = "Mean length", fill = "Supplement") +
theme_minimal(base_size = 13)
doc <- read_pptx()
# 1. Title slide
doc <- add_slide(doc, layout = "Title Slide", master = "Office Theme")
doc <- ph_with(doc, "ToothGrowth Report", ph_location_type(type = "ctrTitle"))
doc <- ph_with(doc, "Generated from R with officer", ph_location_type(type = "subTitle"))
# 2. Bullet highlights
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, "Highlights", ph_location_type(type = "title"))
doc <- ph_with(doc,
unordered_list(str_list = c("Higher dose → longer teeth",
"Orange juice leads at low doses"),
level_list = c(1, 1)),
ph_location_type(type = "body"))
# 3. Data table
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, "Group means", ph_location_type(type = "title"))
doc <- ph_with(doc, autofit(theme_vanilla(flextable(tg))), ph_location_type(type = "body"))
# 4. Chart (editable vector)
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, "Mean length by dose", ph_location_type(type = "title"))
doc <- ph_with(doc, dml(ggobj = p), ph_location_type(type = "body"))
print(doc, target = "report.pptx")Relancez ce script demain avec de nouvelles données et vous obtenez une présentation à jour et correcte en quelques secondes — la raison même de générer des diapositives depuis du code.
Partir d’un modèle d’entreprise
La plupart des équipes ont besoin de présentations sur un modèle maison — polices, couleurs et logo définis. Pointez read_pptx() vers un .pptx existant et officer en hérite les dispositions, les masques et le style ; chaque diapositive que vous ajoutez est aux couleurs de la marque :
doc <- read_pptx(path = "company-template.pptx")
layout_summary(doc) # inspect the template's own layout names first
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = "On-brand slide", location = ph_location_type(type = "title"))
print(doc, target = "branded.pptx")Exécutez toujours layout_summary() sur un modèle avant d’écrire — les modèles d’entreprise renomment leurs dispositions et leurs masques, et add_slide() a besoin des noms exacts.
Foire aux questions
Oui. ReporteRs a été archivé (il reposait sur Java et n’est plus maintenu). officer, du même auteur, en est le successeur moderne — du R pur, pas de Java, activement développé. L’API a changé : utilisez read_pptx() au lieu de pptx(), add_slide() au lieu de addSlide(), ph_with() pour tout le contenu, et print(doc, target = ...) au lieu de writeDoc().
Enveloppez le graphique dans rvg::dml() : ph_with(doc, value = dml(ggobj = p), location = ph_location_type(type = "body")). Cela intègre le graphique comme du DrawingML PowerPoint natif (vectoriel) plutôt qu’une image plate, si bien qu’il reste net à n’importe quel zoom et peut être modifié dans PowerPoint. Passer plutôt l’objet ggplot directement (value = p) intègre une image haute résolution — plus simple, mais non modifiable.
Oui — passez-le à read_pptx(path = "template.pptx"). officer hérite des dispositions de diapositive, des masques, des polices, des couleurs et du logo du modèle. Exécutez d’abord layout_summary() pour voir les noms exacts de disposition et de masque que le modèle définit, puis référencez ces noms dans add_slide().
Construisez le tableau avec le package flextable, puis placez-le avec ph_with() : ph_with(doc, value = flextable(my_data), location = ph_location_type(type = "body")). Stylez-le d’abord avec des fonctions auxiliaires comme theme_vanilla(), autofit(), bg() et bold(). Le même objet flextable se rend aussi vers Word, HTML et PDF.
Celles que fournit le modèle. Appelez layout_summary(read_pptx()) pour les lister. Le thème Office par défaut inclut, entre autres, « Title Slide », « Title and Content », « Two Content », « Section Header », « Comparison », « Title Only » et « Blank ». La disposition que vous choisissez détermine quels espaces réservés existent sur la diapositive.
Pour aller plus loin dans /learn
Ce billet est la recette ciblée. Pour une vue d’ensemble du déplacement des données et des résultats en entrée et en sortie de R — CSV, Excel, RDS, Parquet et rapports Office formatés — voyez la leçon :
- Exporter des données depuis R — chaque format d’export et quand utiliser chacun.
- ggplot2 — construisez les graphiques que vous déposez sur vos diapositives.
Voir aussi
- Exporter des données depuis R — la leçon complète. · Série ggplot2 — des graphiques de qualité publication. · Programmation.
Demandez à Prova « transforme mon ggplot en un graphique modifiable sur une diapositive PowerPoint avec officer » — elle répond avec du code que vous pouvez exécuter sur vos propres données. The runtime is the judge. Demander à Prova →
Citation
@online{kassambara2026,
author = {Kassambara, Alboukadel},
title = {Créer des présentations PowerPoint depuis R avec officer},
date = {2026-07-08},
url = {https://www.datanovia.com/blog/powerpoint-in-r-officer},
langid = {fr}
}