Seuratオブジェクト作成時に以下のようなエラーが出た場合:
Error in validObject(object = value):
invalid class “Assay” object: 'counts' must have the same cells as 'data'
これは counts
と data
の 列名(細胞名)が一致していない ために起こります。
そしてこの情報を揃えないと書き出せても読み込めないh5seurat
が出来上がってしまいます。
Seurat objectを書き出して保存する際、色々なフォーマットで保存することが可能だ。時にはScanpyにデータを移行しなければならない場面があるが、h5seurat
形式はデータの損失も少なく、優れた形式の一つだ。
seu = Read10X("/shared/oodake/sc-public-data/Autsornworawat2020/GSE151117/GSM4567001_ES1txp/")
seu = CreateSeuratObject(counts = seu, project = "ES1txp")
SaveH5Seurat(seu, "test1.h5seurat",overwrite = TRUE)
ところがどっこい、これを読み込もうとするとエラーになるのである。
# ポイント
colnames(expr_mat) <- colnames(seurat_obj)
# 新しい Assay オブジェクトを作成し、data も counts と同じに設定する
new_assay <- CreateAssayObject(counts = expr_mat)
new_assay@data <- new_assay@counts
# 既存の Seurat オブジェクトの "RNA" アッセイを置き換える
seu[["RNA"]] <- new_assay
# h5seurat形式で書き出し(以下のコードではディレクトリが存在している前提です)
SaveH5Seurat(seu, filename = "Augsorworawat2020/ES1txp.h5seurat", overwrite = TRUE)
Seuratオブジェクトの内部はS4クラスで実装されており、以下のような構造を持っています。
@assays$RNA@counts
:生のカウントデータ(未処理)@assays$RNA@data
:正規化済みデータ(例:log1p-transformedなど)h5seurat
を読み込む際、data
を参照しに行くようです。
counts
は細胞A, B, C の順なのに、data
は A, C, B の順だったdata
にしか含まれていない細胞、またはその逆があったcounts
, data
, scale.data
, raw.data
など、使用状況によって異なる命名slotNames(seurat_obj)
str(seurat_obj)
colnames(seurat_obj@assays$RNA@counts)
colnames(seurat_obj@assays$RNA@data)
このエラーはSeuratユーザーの間でよく出ているようです:
Seuratオブジェクトは S4 クラスで実装されているため、内部の各要素(スロット)には @
演算子でアクセスできます。
例:
生データ(raw counts):
オブジェクト名@assays$RNA@counts
正規化済みデータ(normalized data):
オブジェクト名@assays$RNA@data
Seuratでは、以下のように要素名が状況に応じて命名されています:
"counts"
"data"
"raw.data"
など、異なる名前が使われる場合もありました"counts"
と "data"
に統一されています要素名や内容が不明な場合、以下の方法で確認・検証できます:
slotNames()
関数slotNames(オブジェクト名)
→ これでそのSeuratオブジェクトが持つ全てのスロット名が一覧で得られます
str()
関数str(オブジェクト名)
→ オブジェクト全体の構造を詳細に確認可能
このように、Seuratオブジェクトの各要素(例えば counts
や data
)は、その役割に応じた名前が付けられており、バージョンや処理の流れによっては異なる名称になることもあります。
内部の中身が不明な場合は、slotNames()
や str()
を利用して、現在のオブジェクトの構造や中身を把握することが解決の鍵となります。
# シンプルなチェック関数
check_alignment <- function(counts, data) {
if (!identical(colnames(counts), colnames(data))) {
warning("列名が一致していません")
} else {
message("OK: 列名は一致しています")
}
}
Seuratは便利ですが、内部構造が複雑なので、こうした 「静かなる地雷」 に引っかかることがあります。今回のようにエラー文が示す構造を理解しておくと、次回から落ち着いて対応できるようになります。