단일세포 분석: 품질관리 실습 (5)

1. 학습 목표

  • 품질관리 지표 구축 및 데이터 품질 평가
  • 적절한 필터 적용을 통한 저품질 세포 제거

2. 필터링 목표

  • 고품질의 실제 세포만 포함하도록 데이터를 필터링하여 세포 클러스터링 시 다양한 세포 유형更容易 식별
  • 부적합한 샘플 데이터를 검토하여 부적합 원인 파악

3. 과제

  • 복잡한 소량의 세포에서 저품질 세포 구분
  • 생물학적 관련 세포 유형을 제거하지 않으면서 고품질 세포를 유지하는 적절한 필터 임계값 선택

4. 품질 기준

데이터가 Seurat에 로드되고 초기 객체가 생성되면 각 셀에 대해 일부 기본 메타데이터가 어셈블됩니다. 이 메타데이터를 자세히 살펴보려면 sc_data 객체의 meta.data에 저장된 데이터프레임을 확인하세요:

# 메타데이터 확인
View(sc_data@meta.data)

품질관리 분석을 시각화하려면 다음 추가 지표를 계산해야 합니다:

  • number of genes detected per UMI: 데이터셋의 복잡성 파악 (UMI당 많은 유전자가 검출될수록 복잡도가 높음)
  • mitochondrial ratio: 미토콘드리아 유전자에서 비롯된 세포 리드수 백분율

5. Novelty Score

이 값은 각 세포에서 검출된 유전자 수의 log10과 각 세포의 UMI 수의 log10을 구한 후, UMI의 log10으로 유전자 수의 log10을 나누어 쉽게 계산할 수 있습니다.

# 각 셀의 UMI당 유전자 수를 메타데이터에 추가
sc_data$log10GenesPerUMI <- log10(sc_data$nFeature_RNA) / log10(sc_data$nCount_RNA)

6. 미토콘드리아 비율

Seurat은 미토콘드리아 유전자에 매핑된 전사본 비율을 계산하는 편리한 기능을 제공합니다. PercentageFeatureSet() 함수는 패턴 매개변수를 受け取り 데이터셋의 모든 유전자 식별자에서 해당 패턴을 검색합니다. 미토콘드리아 유전자를 찾고 있으므로 "MT-" 패턴으로 시작하는 유전자 식별자를 검색합니다. 각 세포에 대해 "Mt-" 세트에 속하는 모든 유전자(특징)의 카운트 합계를 구한 후, 모든 유전자(특징)의 카운트 합계로 나눕니다. 이 값에 100을 곱하여 백분율 값을 얻습니다.

# 백분율 계산
sc_data$mitoRatio <- PercentageFeatureSet(object = sc_data, pattern = "^MT-")
sc_data$mitoRatio <- sc_data@meta.data$mitoRatio / 100

이제 데이터 평가에 필요한 품질 지표를 갖추었습니다. 그러나 셀 ID 및 조건 정보를 포함한 몇 가지 유용한 추가 정보를 메타데이터에 포함시키고자 합니다. 먼저 Seurat 객체에서 meta.data를 추출하여 메타데이터를 생성합니다:

# 메타데이터 생성
cell_info <- sc_data@meta.data

# 셀 ID를 메타데이터에 추가
cell_info$cell_id <- rownames(cell_info)

# 샘플 열 생성
cell_info$sample_group <- NA
cell_info$sample_group[which(str_detect(cell_info$cell_id, "^ctrl_"))] <- "control"
cell_info$sample_group[which(str_detect(cell_info$cell_id, "^stim_"))] <- "stimulated"

# 열 이름 재지정
cell_info <- cell_info %>% dplyr::rename(original_id = orig.ident,
                                       total_counts = nCount_RNA, 
                                       detected_genes = nFeature_RNA)
# 업데이트된 메타데이터를 Seurat 객체에 저장
sc_data@meta.data <- cell_info

# RData로 저장
save(sc_data, file="data/processed_sc.RData")

7. 품질 평가 지표

이제 다양한 지표를 평가한 후 어떤 셀이 저품질이어서 분석에서 제거해야 하는지를 결정합니다.

셀 카운트

셀 카운트는 검출된 고유 셀 바코드 수로 결정됩니다. 이 실험에서는 12,000-13,000개 사이가 예상됩니다.

이상적으로는 고유 셀 바코드 수가 로드된 셀 수와 상대적으로 일치할 것으로 기대합니다. 그러나 상황은 항상 그렇지 않습니다. 셀 포획율은 로드된량의 일부에 불과하기 때문입니다. 예를 들어, 10X(50-60%)에 비해 inDrops의 세포 포획 효율이 더 높습니다(70-80%).

셀 수는 프로토콜에 따라也可能하여 로드된 양보다 훨씬 많은 세포 수가 생성될 수 있습니다. 예를 들어, inDrops 프로토콜 동안 셀 바코드가 수icrob에 존재하며, 이러한 수icrob는 개별 세포 및 용해/반응 혼합물과 함께 방울에 캡슐화됩니다. 각 수icrob에는 연결된 셀이 있어야 하지만 경우에 따라 여러 셀이 있을 수 있습니다. 마찬가지로, 10X 프로토콜使用时, 실제 세포 없이 방울(GEM)에서 바코드가 있는 비드가 있을 수 있습니다. 죽은 세포의 존재 외에도 이러한 모든 경우로 인해 세포보다 많은 셀이 생성될 수 있습니다.

# 각 샘플의 셀 카운트 시각화
cell_info %>% 
    ggplot(aes(x=sample_group, fill=sample_group)) + 
    geom_bar() +
    theme_classic() +
    theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1)) +
    theme(plot.title = element_text(hjust=0.5, face="bold")) +
    ggtitle("Cell Count")

각 샘플에서 15,000개 이상의 셀이 있어 예상되는 12-13,000개보다 많습니다. 명백히 일부 정크 "셀"이 존재할 수 있습니다.

셀당 UMI 카운트

각 스팟의 UMI 카운트는 일반적으로 500 이상이어야 합니다. UMI 카운트가 500-1000 사이이면 사용 가능하지만 더 깊게 시퀀싱해야 할 수 있습니다.

# 셀당 UMIs/전사본 수 시각화
cell_info %>% 
    ggplot(aes(color=sample_group, x=total_counts, fill=sample_group)) + 
    geom_density(alpha = 0.2) + 
    scale_x_log10() + 
    theme_classic() +
    ylab("Cell density") +
    geom_vline(xintercept = 500)

두 샘플의 대부분의 셀이 1000 이상의 UMI를 가지고 있음을 볼 수 있습니다.

셀당 검출된 유전자

유전자 검출에 대한 기대는 UMI 검출과 유사하지만 약간 낮을 수 있습니다. 고품질 데이터의 경우 히스토그램에 캡슐화된 세포를 나타내는 큰 봉우리(peak)가 있어야 합니다. 주요 봉우리 왼쪽에 작은 어깨가 있거나 셀이 이봉우리 분포를 보이는 경우, 일부 문제가 있을 수 있습니다. 어떤 이유로 실패한 세포 그룹이 있을 수 있습니다. 혹은 생물학적으로 다른 유형의 세포가 존재할 수 있습니다.

# 히스토그램으로 각 셀에서 검출된 유전자 분포 시각화
cell_info %>% 
    ggplot(aes(color=sample_group, x=detected_genes, fill=sample_group)) + 
    geom_density(alpha = 0.2) + 
    theme_classic() +
    scale_x_log10() + 
    geom_vline(xintercept = 300)

복잡도 (Novelty Score)

각 셀의 RNA 종류 복잡도를 평가하기 위해 novelty score라는 지표를 사용할 수 있습니다. novelty scorenGenesnUMI의 비율로 계산됩니다. 많은 전사본이 포착되고(높은 nUMI) 세포에서 소수의 유전자만 검출되면, 소수의 유전자만 포착되었고 이러한 소수의 유전자에서 전사본이 반복적으로 시퀀싱되었음을 의미할 수 있습니다. 이러한 저복잡도(낮은 novelty score) 셀이 특정 세포 유형(전형적인 전사체가 부족한 적혈구)을 나타내거나 인위적 요인이나 오염으로 인해 발생했을 수 있습니다. 일반적으로 고품질 셀이 novelty score가 0.80 이상일 것으로 예상됩니다.

# UMI당 검출된 유전자를 시각화하여 유전자 표현의 전체 복잡도 시각화
cell_info %>%
    ggplot(aes(x=log10GenesPerUMI, color = sample_group, fill=sample_group)) +
    geom_density(alpha = 0.2) +
    theme_classic() +
    geom_vline(xintercept = 0.8)

미토콘드리아 카운트 비율

이 지표는 죽거나 죽어가는 세pto기からの 미토콘드리아 오염이 많은지 확인할 수 있습니다. 미토콘드리아 비율이 0.2를 초과하는 저품질 샘플을 정의합니다.

# 각 셀에서 검출된 미토콘드리아 유전자 표현 분포 시각화
cell_info %>% 
    ggplot(aes(color=sample_group, x=mitoRatio, fill=sample_group)) + 
    geom_density(alpha = 0.2) + 
    scale_x_log10() + 
    theme_classic() +
    geom_vline(xintercept = 0.2)

결합 필터링 효과

이러한 QC 지표를 단독으로 고려하면 신호의 잘못된 해석으로 이어질 수 있습니다. 예를 들어, 미토콘드리아 카운트 비율이 높은 세포는 호흡 과정에 관여할 수 있으며 유지하고 싶은 세포일 수 있습니다. 마찬가지로, 다른 지표들도 다른 생물학적 해석을 가질 수 있습니다. QC 수행 시 일반적인 경험 법칙은 개별 지표의 임계값을 가능한 한 관대하게 설정하고 이러한 지표의 결합 영향을 항상 고려하는 것입니다. 이러한 방식으로 어떤 살아있는 세포 그룹도 필터링해버릴 위험을 줄일 수 있습니다.

함께 자주 평가되는 두 지표는 UMI 수와 각 셀에서 검출된 유전자 수입니다. 여기서는 미토콘드리아 읽기 비율로 색상이 지정된 UMI 수에 대한 유전자 수를 플롯합니다. 카운트와 유전자 임계값을 결합하고 미토콘드리아 점수를 추가로 오버레이하면 각 셀 품질의 요약图을 얻습니다.

# 검출된 유전자와 UMI 수 사이의 상관관계 시각화
cell_info %>% 
    ggplot(aes(x=total_counts, y=detected_genes, color=mitoRatio)) + 
    geom_point() + 
    scale_colour_gradient(low = "gray90", high = "black") +
    stat_smooth(method=lm) +
    scale_x_log10() + 
    scale_y_log10() + 
    theme_classic() +
    geom_vline(xintercept = 500) +
    geom_hline(yintercept = 250) +
    facet_wrap(~sample_group)

좋은 셀은 일반적으로 각 셀이 더 많은 유전자와 더 많은 UMI를 갖습니다(图的右上象限). 저품질 셀이 각 셀당 적은 유전자와 UMI를 가지고 있을 수 있으며, 이는 图의 좌하象限에 해당하는 데이터 포인트에 해당합니다. 이를 통해 선의 기울기와 右下象限에 데이터 포인트의 분산 여부를 평가합니다. 이러한 셀은 많은 UMI를 가지고 있지만 소수의 유전자만 있습니다. 이것은 죽어가는 세포일 수 있지만, 저복잡도 세포 유형(즉, 적혈구)의 그룹을 나타낼 수도 있습니다.

미토콘드리아 점수는 특히 낮은 카운트의 셀에서만(더 어두운 색상의 데이터 포인트) 높습니다. 이는 세포질 mRNA가 터진 membrane을 통해 누출된 손상/죽어가는 세포를 나타낼 수 있으며, 따라서 미토콘드리아에 있는 mRNA만 보존됩니다. 이러한 셀은 카운트 및 유전자 수 임계값으로 필터링된 것을 图에서 볼 수 있습니다.

8. 필터링

셀 수준 필터링

이제 다양한 지표를 시각화했으므로 저품질 셀을 제거하는 데 사용할 임계값을 결정할 수 있습니다. 앞서 언급한 제안은 일반적인 지침이며, 구체적인 실험이 선택한 정확한 임계값에 정보를 제공해야 합니다. 다음 임계값을 사용합니다:

  • total_counts > 500
  • detected_genes > 250
  • log10GenesPerUMI > 0.8
  • mitoRatio < 0.2

필터링하려면 Seurat 객체로 돌아가서 subset() 함수를 사용합니다:

# 선택한 임계값을 사용하여 저품질 셀 필터링
filtered_data <- subset(x = sc_data, 
                        subset= (total_counts >= 500) & 
                          (detected_genes >= 250) & 
                          (log10GenesPerUMI > 0.80) & 
                          (mitoRatio < 0.20))

유전자 수준 필터링

데이터에는 카운트가 0인 유전자가 많이 있습니다. 이러한 유전자는 세포의 평균 표현을 크게 낮출 수 있으므로 데이터에서 제거합니다. 먼저 각 셀에서 카운트가 0인 유전자를 확인합니다:

# 카운트 추출
counts <- GetAssayData(object = filtered_data, slot = "counts")

# 각 유전자에 대해 각 셀의 카운트가 0을 초과하는지 指定하는 논리 매트릭스 출력
nonzero_counts <- counts > 0

이제 novelty score에 따라 일부 필터링을 수행합니다. 유전자가 소수의 셀에서만 표현되면, 표현하지 않는 다른 모든 셀의 평균을 여전히 낮추기 때문에 그다지 의미가 없습니다. 10개 이상의 셀에서 표현된 유전자만 유지합니다. 이 필터를 사용하면 모든 셀에서 카운트가 0인 유전자를 효과적으로 제거합니다.

# 모든 TRUE 값을 합산하고, 각 유전자가 10개 이상의 TRUE 값을 가지면 TRUE 반환
genes_to_keep <- Matrix::rowSums(nonzero_counts) >= 10

# 10개 이상의 셀이서 표현된 유전자만 유지
filtered_counts <- counts[genes_to_keep, ]

마지막으로 이러한 필터링된 카운트를 가져와서 다운스트림 분석을 위한 새로운 Seurat 객체를 생성합니다.

# 필터링된 Seurat 객체에 다시 할당
filtered_data <- CreateSeuratObject(filtered_counts, meta.data = filtered_data@meta.data)

9. 재평가

필터링 실행 후 QC 지표를 검토하여 데이터가 예상과 일치하고 다운스트림 분석에 적합한지 확인합니다.

태그: single-cell scRNA-seq Seurat R Bioinformatics

7월 21일 00:16에 게시됨