Contrôle qualité Seurat : charger et filtrer un jeu de données scRNA-seq (pbmc3k)
Transformez une matrice 10x brute en un objet Seurat propre — inspectez les gènes, les comptages et le contenu mitochondrial par cellule, puis filtrez les gouttelettes vides et les cellules mourantes avant de regrouper
Un guide pratique du contrôle qualité pour le RNA-seq single-cell en R avec Seurat. Chargez le jeu de données 10x canonique pbmc3k avec Read10X, construisez un objet Seurat, et calculez les trois métriques de CQ que toute analyse passe au crible — gènes par cellule (nFeature_RNA), comptages par cellule (nCount_RNA) et pourcentage mitochondrial (percent.mt). Visualisez-les avec des graphiques en violon et des nuages de points, choisissez des seuils de filtrage pertinents avec un raisonnement en langage clair, et sous-sélectionnez un ensemble propre de cellules prêtes pour la normalisation et le regroupement.
Date de publication
29 juin 2026
Modifié
7 juillet 2026
AstucePoints clés
Un run 10x vous donne une matrice de comptage gènes × cellules, mais toutes les colonnes ne sont pas une vraie cellule — gouttelettes vides, doublets et cellules mourantes s’y mélangent. Le contrôle qualité les retire avant l’analyse.
Chargez la matrice avec Read10X() et construisez un objet Seurat avec CreateSeuratObject(), qui écarte déjà les gouttelettes les plus vides (min.features) et les gènes jamais détectés (min.cells).
Examinez chaque cellule sur trois métriques de CQ : gènes par cellule (nFeature_RNA), comptages par cellule (nCount_RNA) et la fraction mitochondriale (percent.mt, calculée avec PercentageFeatureSet).
Regardez avant de couper : un VlnPlot des trois métriques plus un FeatureScatter de leur relation vous indiquent où finissent les vraies cellules et où commence le rebut — les seuils se lisent sur la distribution, ils ne se mémorisent pas.
Filtrez avec subset(), puis indiquez ce que vous avez conservé. Sur pbmc3k, nFeature_RNA 200–2 500 et percent.mt < 5 % conserve 2 638 cellules sur 2 700.
Introduction
Votre run single-cell 10x Genomics revient sous forme de matrice de comptage gènes × cellules creuse — des milliers de colonnes, une par code-barres de cellule. Mais un code-barres n’est pas une cellule. Certaines gouttelettes étaient vides et n’ont capté que de l’ARN ambiant ; d’autres ont attrapé deux cellules à la fois (un doublet) ; certaines cellules étaient déjà mourantes au moment de l’encapsulation, laissant fuir l’ARNm cytoplasmique et un pic révélateur de transcrits mitochondriaux. Injectez ce mélange directement dans le regroupement et vous obtenez des types cellulaires fantômes et des frontières floues.
Le contrôle qualité est la première chose à faire, et c’est simple : mesurez quelques propriétés de chaque cellule, examinez leurs distributions, et écartez les cellules qui se trouvent dans les queues de rebut. Cette leçon fait exactement cela sur pbmc3k — le jeu de données canonique de 2 700 cellules mononucléées du sang périphérique sur lequel repose le tutoriel Seurat — de sorte que le workflow se transpose directement à vos propres données 10x.
Charger les données dans un objet Seurat
La sortie 10x se compose de trois fichiers dans un même dossier : la matrice creuse (matrix.mtx.gz), les codes-barres de cellules (barcodes.tsv.gz) et les noms de gènes (features.tsv.gz). Read10X() lit le dossier et renvoie la matrice de comptage ; CreateSeuratObject() l’enveloppe dans l’objet sur lequel travaille chaque étape en aval.
library(Seurat)# Read the 10x folder -> a sparse genes x cells count matrixpbmc.data <-Read10X("_data/filtered_gene_bc_matrices/hg19")dim(pbmc.data) # genes x cells, before any filtering
[1] 32738 2700
# Build the Seurat object: drop genes seen in < 3 cells and cells with < 200 genespbmc <-CreateSeuratObject(pbmc.data, project ="pbmc3k",min.cells =3, min.features =200)pbmc
An object of class Seurat
13714 features across 2700 samples within 1 assay
Active assay: RNA (13714 features, 0 variable features)
1 layer present: counts
La matrice brute compte 32 738 gènes pour 2 700 cellules. Les deux arguments du constructeur réalisent un premier nettoyage peu coûteux : min.cells = 3 retire les gènes détectés dans moins de trois cellules (ils ne portent aucun signal exploitable et ne font qu’alourdir la matrice), et min.features = 200 retire les gouttelettes exprimant moins de 200 gènes (presque certainement vides). Il reste 13 714 gènes pour 2 700 cellules — les mêmes 2 700 ici parce que la matrice 10x filtrée avait déjà subi l’appel des codes-barres, mais sur une sortie brute min.features seul peut écarter des milliers de gouttelettes vides.
Les trois métriques de CQ
CreateSeuratObject() stocke automatiquement deux métriques pour chaque cellule : nCount_RNA (comptages totaux, la taille de librairie) et nFeature_RNA (nombre de gènes détectés). La troisième — le pourcentage mitochondrial — c’est vous qui l’ajoutez. Une fraction mitochondriale élevée est la signature classique d’une cellule stressée ou mourante : à mesure que la membrane se dégrade, l’ARNm cytoplasmique fuit tandis que les transcrits mitochondriaux restent piégés, de sorte que leur part dans le total augmente.
PercentageFeatureSet() le calcule à partir des noms de gènes. Dans ce jeu de données humain, les gènes mitochondriaux commencent tous par MT-, si bien qu’un motif "^MT-" les capture.
library(Seurat)pbmc.data <-Read10X("_data/filtered_gene_bc_matrices/hg19")pbmc <-CreateSeuratObject(pbmc.data, project ="pbmc3k",min.cells =3, min.features =200)# Fraction of counts from mitochondrial genes (human: gene symbols start with "MT-")pbmc[["percent.mt"]] <-PercentageFeatureSet(pbmc, pattern ="^MT-")head(pbmc@meta.data) # the per-cell QC table
Les trois métriques résident maintenant dans pbmc@meta.data, une ligne par cellule. Résumez-les avant de tracer — les nombres vous disent à quoi ressemble la « normale » pour ce jeu de données :
nFeature_RNA nCount_RNA percent.mt
Min. : 212.0 Min. : 546 Min. : 0.000
1st Qu.: 690.0 1st Qu.: 1756 1st Qu.: 1.537
Median : 816.0 Median : 2196 Median : 2.031
Mean : 845.5 Mean : 2365 Mean : 2.217
3rd Qu.: 952.0 3rd Qu.: 2762 3rd Qu.: 2.643
Max. :3400.0 Max. :15818 Max. :22.569
La cellule médiane exprime 816 gènes à partir de 2 196 comptages, avec une fraction mitochondriale d’environ 2 %. Mais les maxima — 3 400 gènes, 15 818 comptages, 22,6 % mitochondrial — sont loin dans les queues. Ce sont ces extrêmes que vise le CQ.
Visualiser les métriques de CQ
Un graphique en violon montre la distribution complète de chaque métrique sur l’ensemble des cellules — où se situe le gros de l’effectif et la longueur de la queue. C’est la figure sur laquelle vous lisez vos seuils.
library(Seurat)VlnPlot(pbmc, features =c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol =3)
Lisez-le de gauche à droite. nFeature_RNA et nCount_RNA sont denses en bas et s’amincissent vers le haut — un petit nombre de cellules expriment bien plus de gènes et de comptages que les autres, la signature des doublets (deux cellules, donc environ deux fois plus de matériel). percent.mt colle au bas pour presque toutes les cellules mais présente une fine queue supérieure dépassant 20 % — ce sont les cellules mourantes.
Les deux nuages de points montrent comment les métriques se rapportent les unes aux autres, ce qui affine les coupes. FeatureScatter() affiche la corrélation dans son titre.
Comptages vs gènes (à droite) sont fortement corrélés (0,95) — comme attendu, les cellules ayant plus de transcrits détectent plus de gènes, et la ligne quasi droite signifie qu’aucune grande population ne se comporte de façon anormale. Comptages vs pourcentage mitochondrial (à gauche) ne sont presque pas corrélés (−0,13) : les cellules à fort taux mitochondrial sont dispersées hors du nuage principal au lieu de suivre la taille de librairie, et c’est exactement pourquoi percent.mt est un filtre distinct, non redondant avec nCount_RNA.
Choisir les seuils de filtrage
Les seuils se lisent sur les distributions ci-dessus, ils ne se mémorisent pas — ils dépendent du tissu, de la chimie et de la profondeur de séquençage. La logique se résume toujours aux trois mêmes coupes :
Une borne inférieure sur les gènes par cellule retire les gouttelettes vides et les cellules abîmées sans presque aucun transcrit. Le min.features = 200 du constructeur a déjà fixé ce plancher, si bien que nFeature_RNA > 200 ne fait que le confirmer.
Une borne supérieure sur les gènes par cellule retire les doublets probables — des cellules exprimant bien plus de gènes que la population. Le violon de pbmc3k s’amincit au-delà de ~2 500 gènes, donc nFeature_RNA < 2500 rogne cette queue.
Une borne supérieure sur le pourcentage mitochondrial retire les cellules mourantes. Le gros des cellules pbmc se situe sous 3 %, avec une queue nette au-delà de 5 %, si bien que percent.mt < 5 est la coupe naturelle ici.
L’objectif est de rogner les queues de rebut évidentes, pas de poursuivre un nombre parfait — placez chaque coupe à l’épaule de la distribution, là où finissent les vraies cellules. Pour pbmc3k, les seuils établis sont nFeature_RNA entre 200 et 2 500 et percent.mt en dessous de 5 %.
Filtrer les cellules
subset() ne conserve que les cellules qui satisfont les trois conditions.
Le filtrage retire 62 cellules sur 2 700 (2,3 %), en laissant 2 638 pour l’analyse en aval. La répartition est parlante : 57 cellules échouent sur le pourcentage mitochondrial (≥ 5 %) et 5 sur la borne supérieure des gènes (≥ 2 500) — le filtre mitochondrial fait donc l’essentiel du travail, et aucune cellule n’a été perdue sur la borne inférieure des gènes (le constructeur s’en était déjà chargé).
Ce que vous indiqueriez :Les cellules ont été conservées si elles exprimaient 200 à 2 500 gènes avec moins de 5 % de comptages mitochondriaux, retirant 62 des 2 700 gouttelettes (2,3 %) considérées comme probablement vides, doublets ou mourantes ; 2 638 cellules de haute qualité ont été conservées. L’objet pbmc nettoyé est maintenant prêt à normaliser et trouver les gènes variables.
Problèmes fréquents
Rien n’est filtré (ou tout l’est). La cause la plus fréquente est un motif mitochondrial qui ne correspond pas aux noms de gènes. "^MT-" vise les symboles humains ; la souris utilise "^mt-" (en minuscules), et un jeu de données annoté avec des identifiants Ensembl n’a aucun préfixe MT-. Vérifiez avec grep("^MT-", rownames(pbmc), value = TRUE) — s’il ne renvoie rien, percent.mt ne contient que des zéros et le filtre est sans effet.
Read10X génère une erreur sur le dossier. Il attend les trois fichiers réunis (matrix.mtx[.gz], barcodes.tsv[.gz], features.tsv[.gz]/genes.tsv[.gz]) dans le répertoire que vous lui indiquez. Pointez-le vers le dossier, pas vers un fichier unique, et assurez-vous que les trois sont présents et tous gzippés ou tous non gzippés.
Réutiliser un même jeu de seuils partout.nFeature_RNA < 2500 et percent.mt < 5 conviennent à pbmc3k, pas universellement. Les tissus métaboliquement actifs (cœur, foie) présentent naturellement des fractions mitochondriales plus élevées ; un séquençage plus profond décale les distributions de comptages. Tracez toujours d’abord et fixez la coupe à partir des données que vous avez sous les yeux.
Questions fréquentes
NoteQue signifient nFeature_RNA et nCount_RNA dans Seurat ?
nCount_RNA est le nombre total de molécules d’ARN (UMI) détectées dans une cellule — sa taille de librairie. nFeature_RNA est le nombre de gènes distincts détectés dans cette cellule. Les deux sont calculés automatiquement par CreateSeuratObject() et stockés dans pbmc@meta.data.
NoteComment calculer le pourcentage de gènes mitochondriaux ?
Utilisez PercentageFeatureSet() avec un motif qui correspond aux noms de gènes mitochondriaux : pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-"). Utilisez "^MT-" pour les symboles de gènes humains et "^mt-" pour la souris.
NoteQuels seuils de CQ utiliser pour le scRNA-seq ?
Il n’existe aucun nombre universel. Tracez nFeature_RNA, nCount_RNA et percent.mt avec VlnPlot(), puis placez chaque coupe à l’épaule de sa distribution, là où finissent les vraies cellules. Pour pbmc3k, c’est nFeature_RNA entre 200 et 2 500 et percent.mt en dessous de 5 %, mais un tissu ou une profondeur différents décaleront ces valeurs.
NotePourquoi faut-il retirer les cellules à fort taux mitochondrial ?
Une fraction mitochondriale élevée est la signature d’une cellule stressée ou mourante : à mesure que la membrane cellulaire se dégrade, l’ARNm cytoplasmique fuit tandis que les transcrits mitochondriaux restent piégés à l’intérieur de l’organite, de sorte que leur part dans les comptages restants augmente. Conserver ces cellules injecte un bruit technique qui peut se faire passer pour un type cellulaire.
NoteFiltrer sur les comptages retire-t-il aussi les doublets ?
En partie. Une borne supérieure élevée sur nFeature_RNA/nCount_RNA retire les doublets les plus évidents (deux cellules donnent environ deux fois plus de matériel), ce que fait ici la coupe nFeature_RNA < 2500. Pour une élimination rigoureuse des doublets, des outils dédiés (DoubletFinder, scDblFinder) modélisent explicitement la distribution des doublets — les seuils de CQ sont un premier passage, pas une solution complète.
Testez vos connaissances
ImportantÀ vous de jouer : CQ d’un objet Seurat à partir de zéro
À partir de la matrice pbmc3k commitée, construisez l’objet Seurat, ajoutez percent.mt, et indiquez combien de cellules ont une fraction mitochondriale de 5 % ou plus. Appliquez ensuite le filtre complet et confirmez le compte final de cellules.
AstuceIndice
Après avoir ajouté percent.mt, sum(pbmc$percent.mt >= 5) compte les cellules à fort taux mitochondrial. subset() avec les trois conditions applique le filtre ; ncol() donne le compte de cellules.
57 des 2 700 cellules portent 5 % ou plus de comptages mitochondriaux ; après le filtre complet, 2 638 cellules de haute qualité subsistent.
NoteVérification rapide : quelles cellules un percent.mt élevé signale-t-il ?
A. Des doublets — deux cellules capturées dans une même gouttelette. B. Des cellules mourantes ou stressées laissant fuir l’ARNm cytoplasmique. C. Les cellules les plus profondément séquencées et de plus haute qualité.
AstuceAfficher la réponse
B. Une fraction mitochondriale élevée marque les cellules mourantes ou stressées : l’ARNm cytoplasmique fuit à mesure que la membrane se dégrade, laissant les transcrits mitochondriaux surreprésentés. Les doublets, eux, sont repérés par un nFeature_RNA/nCount_RNA anormalement élevé.
Conclusion
Le contrôle qualité est le passage obligé par lequel commence toute analyse single-cell. Vous avez chargé la matrice 10x pbmc3k avec Read10X(), construit un objet Seurat, et examiné chaque cellule sur les trois métriques qui comptent — nFeature_RNA, nCount_RNA et percent.mt. Vous avez lu les seuils sur un VlnPlot et un FeatureScatter plutôt que de les mémoriser, puis utilisé subset() pour conserver les 2 638 cellules nettoyées. Les règles durables : tracez avant de couper, placez chaque seuil à l’épaule de sa distribution, et indiquez ce que vous avez conservé. L’objet nettoyé est prêt à être normalisé, à révéler ses gènes variables et à être regroupé.
Demandez à Prova« comment contrôler la qualité de mes propres données single-cell 10x dans Seurat ? » — elle répond avec du code R que vous pouvez exécuter sur votre propre matrice, calcule les métriques de CQ et vous aide à choisir les seuils à partir de vos distributions. The runtime is the judge.Demander à Prova →
Cette page vous a-t-elle été utile ?
Merci pour votre retour !
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.
Cette leçon est reproductible : chaque figure et chaque nombre ont été produits par le code montré — copiez n’importe quel bloc et exécutez-le pour les reproduire. The runtime is the judge.
Références
Hao, Y., et al. (2021). Integrated analysis of multimodal single-cell data (Seurat v4). Cell, 184(13), 3573–3587.
Satija, R., Farrell, J. A., Gennert, D., Schier, A. F., & Regev, A. (2015). Spatial reconstruction of single-cell gene expression data. Nature Biotechnology, 33(5), 495–502.
10x Genomics. 3k PBMCs from a Healthy Donor — la matrice gène–code-barres filtrée pbmc3k canonique (Cell Ranger 1.1.0).
@online{2026,
author = {},
title = {Contrôle qualité Seurat : charger et filtrer un jeu de
données scRNA-seq (pbmc3k)},
date = {2026-06-29},
url = {https://www.datanovia.com/learn/bioinformatics/single-cell/scrnaseq-quality-control.html},
langid = {fr}
}