【シングルセル解析】Seurat v5のLayerとは
【はじめに】
Seurat v5は超巨大なデータをメモリにロードすることなくディスクに置いたままアクセスできるようになったことや、Integrationが1行でできるようになったり様々な更新が行われている。Seuratオブジェクトの構造でv5から新たに実装されたLayerについて紹介する。
デモデータ
PBMCの2つの実験条件(IFNγの刺激有無)のシングルセルデータをデモに使用する。
devtools::install_github('satijalab/seurat-data')
library(SeuratData)
InstallData("ifnb")
初めて使う場合はダウンロードが始まる。
ダウンロード画面
sc <- LoadData(ds = "ifnb")
sc <- ScaleData(sc)
14053遺伝子 × 13999細胞のデータ。2 layers presentsと表示されている。
【Layerとは】
Seuratは1つのオブジェクトで複数のassay(RNAやSCT、Integrated、ADTなど)を同時に保持することができる。これはSeuratObject@assays
で管理されている。
各assay(例えばSeuratObject@assays$RNA
)には発現マトリクス(counts)や正規化した発現マトリクス(data)、zスコア化した発現マトリクス(scale.data)、細胞バーコード、遺伝子ベクトルなどの情報がある。v5からはこの内のcounts/data/scale.dataをlayers
という階層で管理する。(SeuratObject@assays$RNA@layers$counts
やSeuratObject@assays$RNA@layers$data
)
デモデータのデータ構造
Layerからのデータ取得
次のコマンドはいづれもRNA assayから発現マトリクスを取り出すコマンドである。GetAssayData()
機能ではslot=
引数を使うと警告が出るようになり、代わりにlayer=
引数を使うように促される。LayerData()
機能が新たに実装された。
sc@assays$RNA$counts
sc[["RNA"]]$counts
GetAssayData(object = sc, assay = "RNA", layer = "counts")
LayerData(object = sc, assay = "RNA", layer = "counts")
Layerの発現マトリクスを上書き
次のコマンドはいづれもRNA assayの発現マトリクスをnew.dataで上書きするコマンドである。LayerData()
を使った上書きもできる。
sc[["RNA"]]$counts <- new.data
LayerData(sc, assay = "RNA", layer = "counts") <- new.data
sc <- SetAssayData(object = sc, layer = "counts", new.data = new.data)
【Seuratオブジェクトのmerge】
2つ以上のSeuratオブジェクトをmergeした場合のデータ構造がv4とは異なっているので注意が必要だ。
デモとして2つのSeuratオブジェクトをmergeしてみる。
# デモ用にSeuratオブジェクトを2つに分ける
sc_list <- SplitObject(object = sc, split.by = "stim")
# 2つのSeuratオブジェクトをmerge
sc_merge <- merge(sc_list[[1]], sc_list[[2]])
layersに2つのcounts、2つのdataが現れるようになる。
mergeしたSeuratオブジェクトのデータ構造
もし、1つの発現マトリクスに統合したければ、JoinLayers()
機能を使用する。
sc_merge <- JoinLayers(object = sc_merge)
デフォルトではcountsもdataもそれぞれ1つずつに統合されるが、layers=counts
やlayers=data
のように統合したいlayerだけを指定することもできる。
【Layerのsplit】
1つの発現マトリクスを実験条件ごとに分けるにはsplit()
機能を使用する。f=
引数でどの細胞がどの実験群かを示すベクトルを渡す。ここではmeta.dataスロットのstim列を指定した。
sc2 <- sc_merge # データ比較用にsc2にコピーして進める
sc2@assays$RNA <- split(x = sc2@assays$RNA, f = sc2@meta.data$stim)
デフォルトではcountsもdataもsplitされるが、layers="counts"
やlayers="data"
と入れるとcountsだけ、dataだけがsplitされる。
ちなみにmerge後のSeuratオブジェクトをJoinLayrs()
せずに更なるsplitをしようとするとエラーになる。
Layer名
split()
を使うと、「counts.群名」、「data.群名」のような名前が付く。
split後のデータ構造
layer名はオブジェクト名を打つか、Layers()
機能を使って確認することもできる。
layer名の確認
【Layerを使ったIntegration】
v4でIntegrationするには、異なる実験条件のSeuratオブジェクトをそれぞれ異なるオブジェクトとして用意する必要があった。上述の通り、v5からは1つのSeuratオブジェクトで複数の発現マトリクスをlayersで分けて管理することができるようになり、IntegrationもIntegrateLayers()
の1コマンドで行えるようになった。
Integration方法も5種類用意されている。
Integration前の処理
基本的な流れはv4の時と変わらない。PCAまで進めておく。
sc2 <- NormalizeData(sc2)
sc2 <- FindVariableFeatures(sc2)
sc2 <- ScaleData(sc2)
sc2 <- RunPCA(sc2)
Integration前のPCAデータで次元削減を行った場合を見ておくと、実験条件による差が出ているのがわかる。
sc2 <- RunUMAP(sc2, dims = 1:30)
DimPlot(sc2, group.by = "stim")
Integration - CCA -
method=CCAIntegration
と指定する。
sc2 <- IntegrateLayers(
object = sc2, method = CCAIntegration,
orig.reduction = "pca", new.reduction = "integrated.cca",
verbose = FALSE
)
1分20秒ほどで終了。
sc2 <- RunUMAP(sc2, dims = 1:30,
reduction="integrated.cca", reduction.name = "umap_cca")
DimPlot(sc2, group.by = "stim", reduction = "umap_cca")
Integration - RPCA -
method=RPCAIntegration
と指定する。
sc2 <- IntegrateLayers(
object = sc2, method = RPCAIntegration,
orig.reduction = "pca", new.reduction = "integrated.rpca",
verbose = FALSE
)
3秒で終了。
sc2 <- RunUMAP(sc2, dims = 1:30,
reduction="integrated.rpca", reduction.name = "umap_rpca")
DimPlot(sc2, group.by = "stim", reduction = "umap_rpca")
Integration - Harmony -
method=HarmonyIntegration
と指定する。harmonyパッケージが無い場合はインストールするか聞いてくるので言われるとおりにインストールする。
sc2 <- IntegrateLayers(
object = sc2, method = HarmonyIntegration,
orig.reduction = "pca", new.reduction = "harmony",
verbose = FALSE
)
1分程度で終了。
sc2 <- RunUMAP(sc2, dims = 1:30,
reduction="harmony", reduction.name = "umap_harmony")
DimPlot(sc2, group.by = "stim", reduction = "umap_harmony")
Integration - FastMNN -
SeuratWrappersパッケージが必要となる。さらに初めてFastMNNIntegrationを使うときはbatchelorをインストールするように聞いてくるので言われるままインストールする。
remotes::install_github('satijalab/seurat-wrappers')
library(SeuratWrappers)
Vignetted通りにmethod = FastMNNIntegration
を行うもエラーが出た。
sc2 <- IntegrateLayers(
object = sc2, method = FastMNNIntegration,
orig.reduction = "pca", new.reduction = "integrated.mnn",
verbose = FALSE
)
対処法はわからず。。。
Integration - scVI -
method=scVIIntegration
を使うには、別途python環境を用意する必要がある。
統合処理後は発現マトリクスをsplitしたままにする必要はないので、JoinLayers()
をしておくとのこと。
【SCTransformの場合のIntegration】
デモ用にsplitしたSeuratオブジェクトを用意する。
sc_list <- SplitObject(object = sc, split.by = "stim")
sc_merge <- merge(sc_list[[1]], sc_list[[2]])
sc_merge <- JoinLayers(object = sc_merge)
sc3 <- sc_merge
sc3@assays$RNA <- split(x = sc3@assays$RNA, f = sc3@meta.data$stim)
splitされた状態でSCTransform()
を実行する。
# SCTransformで前処理
sc3 <- SCTransform(sc3)
どうやらSCTransformはversion2がデフォルトになったようだ。layerがsplitしている場合は、実験群の数だけSCTransformが行われる。ここではcounts.CTRL、counts.STIMに対して実行される。
SCTransform()の実行画面
SCT assayにはlayersは無いみたい。countsやdataは1つだけである。(SCTModel.listという場所に実験群ごとのSCTModelが保存されている。)
SCTransform後のデータ構造
SCTransformでintegration無しの場合の次元削減を見ておく。
sc3 <- RunPCA(sc3)
sc3 <- RunUMAP(sc3, dims = 1:30)
DimPlot(sc3, group.by = "stim")
Integration無しでの次元削減
normalization.method = "SCT"
を付ける
※ Integrationの際にはCCA
sc3 <- IntegrateLayers(
object = sc3, method = CCAIntegration,
normalization.method = "SCT",
orig.reduction = "pca",
new.reduction = "integrated.cca",
verbose = FALSE
)
sc3 <- RunUMAP(sc3, dims = 1:30,
reduction="integrated.cca", reduction.name = "umap_cca")
DimPlot(sc3, group.by = "stim", reduction = "umap_cca")
RPCA
sc3 <- IntegrateLayers(
object = sc3, method = RPCAIntegration,
normalization.method = "SCT",
orig.reduction = "pca", new.reduction = "integrated.rpca",
verbose = FALSE
)
sc3 <- RunUMAP(sc3, dims = 1:30,
reduction="integrated.rpca", reduction.name = "umap_rpca")
DimPlot(sc3, group.by = "stim", reduction = "umap_rpca")
Harmony
sc3 <- IntegrateLayers(
object = sc3, method = HarmonyIntegration,
normalization.method = "SCT",
orig.reduction = "pca", new.reduction = "harmony",
verbose = FALSE
)
sc3 <- RunUMAP(sc3, dims = 1:30,
reduction="harmony", reduction.name = "umap_harmony")
DimPlot(sc3, group.by = "stim", reduction = "umap_harmony")
SCT assayでJoinLayers()
DefaultAssay()
がSCTの状態で、JoinLayers()
を行っても次のエラーが出る。上述の通り、SCT assayにはlayersが無いためである。
UseMethod(generic = "JoinLayers", object = object) でエラー:
'JoinLayers' をクラス "c('SCTAssay', 'Assay', 'KeyMixin')" のオブジェクトに適用できるようなメソッドがありません
その場合はDefaultAssayをRNAに変えるか、assay="RNA"
オプションをつけるとよい。
sc3 <- JoinLayers(sc3, assay = "RNA")
Discussion