# EOCRC 실습 2: 발현 후보의 기능과 세포 구성 단서 찾기

> EOCRC 특이 발현 후보의 GO enrichment를 실행하고, bulk RNA-seq에서 계산한 xCell enrichment score가 면역·기질세포 구성에 관해 무엇을 보여 주는지 해석한다.

## 1. 무엇을 실습하나

유전자 목록은 이름만 늘어놓으면 읽기 어렵습니다. 이 실습에서는 [EOCRC 실습 1](/practice/eocrc-vs-locrc/)의 결과를 두 방향으로 요약합니다.

| 입력 | 질문 | 출력 |
| --- | --- | --- |
| EOCRC 특이 후보 목록 | 후보가 어떤 기능에 모이는가? | GO enrichment 결과표 |
| 샘플별 발현 행렬 | 어떤 세포 유형의 signature가 상대적으로 강한가? | 샘플별 xCell enrichment score |

첫 질문은 유전자를 기능별로 묶습니다. 두 번째 질문은 여러 세포가 섞인 bulk RNA-seq 신호에서 면역세포와 기질세포 signature의 상대적 강도를 추정합니다.

:::caution[xCell score는 세포 비율이 아니다]
xCell 출력은 세포를 직접 센 값이 아니라 **enrichment score**입니다. 같은 세포 유형의 score를 여러 샘플에서 비교할 수 있지만, 서로 다른 세포 유형의 score를 실제 세포 비율처럼 직접 비교하면 안 됩니다. 자세한 원리는 [벌크 평균과 싱글셀 해상도](/lessons/single-cell-resolution/#벌크에서-세포-구성을-추정하는-것과-직접-측정은-다르다)에서 설명합니다.
:::

## 2. 논문의 48개 후보와 현재 재현 후보를 구분한다

원 논문은 EOCRC에서 더 두드러진 유전자 48개를 보고했습니다. 22개는 증가했고 26개는 감소했습니다. 그 뒤 paired Wilcoxon 검정을 추가해 8-gene signature를 좁혔습니다.

실습 1의 `outputs/eo-paper-like-candidates.csv`는 현재 PyDESeq2 버전과 현재 필터에서 다시 계산한 목록입니다. 이 목록은 논문의 Supplementary Table S1과 같다고 가정하지 않습니다. 실제로 실습 1의 통일된 조건을 모두 통과한 발표 유전자는 `MSLN` 하나뿐이었습니다.

후보가 한두 개뿐이면 over-representation analysis 결과는 안정적이지 않습니다. 따라서 이 실습은 두 목록을 따로 기록합니다.

1. 논문이 공개한 48개 후보: 논문 결과를 읽는 입력
2. 현재 재현 후보: 같은 절차가 현재 환경에서 무엇을 남겼는지 확인하는 입력

## 3. 48개 후보의 GO enrichment

### 1단계 프롬프트: 48개 후보와 GO enrichment

```text
EOCRC 실습 1의 프로젝트를 유지하고, 논문의 48개 EOCRC 특이 후보에 대한 GO enrichment만 추가해줘.

1. 현재 폴더가 eocrc-locrc 프로젝트이고 outputs/eo-vs-lo-lfc-comparison.csv가 있는지 확인해. 없으면 임의의 결과를 만들지 말고 빠진 파일을 보고한 뒤 멈춰.
2. uv add gprofiler-official을 실행하고 설치된 버전을 기록해.
3. DOI 10.3389/fonc.2024.1365762의 공식 논문 페이지에서 Supplementary Table S1을 내려받아. 검색 결과나 2차 자료가 아니라 논문 출판사가 제공한 파일인지 확인해.
4. Supplementary Table S1에서 EOCRC 특이 후보가 48개이며 upregulated 22개, downregulated 26개인지 검증해. 맞지 않으면 열 이름과 행 수를 보고하고 멈춰.
5. 원본 파일 URL, 다운로드 날짜와 SHA-256을 outputs/source-manifest.txt에 기록해.
6. 48개 전체, up 22개, down 26개를 각각 g:Profiler의 Homo sapiens GO Biological Process over-representation analysis에 넣어.
7. 다중검정 보정 결과를 사용하고 source, native term ID, term name, p_value, intersection_size, query_size, intersection을 보존해.
8. 결과를 outputs/paper-48-go-all.csv, outputs/paper-48-go-up.csv, outputs/paper-48-go-down.csv에 저장해.
9. 상위 term을 단순 나열하지 말고, 같은 유전자 몇 개가 여러 유사 term을 반복해서 만들었는지 확인해.
10. 현재 outputs/eo-paper-like-candidates.csv의 행 수도 함께 출력해. 후보가 5개 미만이면 GO 분석을 억지로 실행하지 말고 표본이 너무 작다고 보고해.
11. uv run python analysis.py로 실행하고 논문 목록과 현재 재현 목록을 섞지 않은 상태로 결과를 한국어로 설명한 뒤 멈춰.
```

[![48개 EOCRC 후보의 GO Biological Process enrichment](/images/practice/eocrc-day7/go-enrichment.png)](/images/practice/eocrc-day7/go-enrichment.png)

*실제 실행 결과: 48개 전체에서는 유의한 GO Biological Process term이 9개였고, 26개 감소 후보만 분석해도 같은 9개가 남았습니다. 22개 증가 후보에서는 유의한 term이 없었습니다. 면역 관련 term들이 일부 면역글로불린 유전자를 반복해 공유하므로 서로 독립적인 발견 9개로 세지 않습니다.*

GO term이 여러 개 유의해도 서로 독립적인 발견 여러 개라는 뜻은 아닙니다. `T-cell activation`, `leukocyte adhesion`, `immune response`처럼 계층적으로 가까운 term은 상당수 유전자를 공유할 수 있습니다. 결과표의 `intersection` 열에서 실제로 어떤 유전자들이 반복되는지 확인합니다.

## 4. xCell 입력을 먼저 감사한다

xCell은 행이 gene symbol, 열이 샘플인 발현 행렬을 받습니다. 공식 구현은 RNA-seq에서 gene length가 반영된 발현량을 요구하고, 한 실험의 샘플을 잘게 나누지 말고 함께 실행할 것을 권합니다.

실습 1의 HTSeq raw count나 VST 값을 이름만 바꿔 xCell 입력으로 사용하지 않습니다. 정확한 gene length와 annotation을 확인할 수 없으면 결과를 **논문 재현**이라고 부르지 않고 탐색적 실행으로 표시합니다.

### 2단계 프롬프트: xCell 입력 감사와 score 계산

```text
GO 분석을 유지하고 xCell 입력 감사와 score 계산을 추가해줘.

1. GSE196006와 GSE251845의 공식 GEO raw count를 내려받고 파일 URL과 SHA-256을 기록해.
2. GENCODE v50 GRCh38 GTF에서 gene별 exon union length를 계산해. 겹치는 exon을 중복 합산하지 말고 annotation 버전을 기록해.
3. raw count를 gene-length-normalized TPM으로 변환하고 Ensembl ID를 gene symbol에 매핑해. 중복 symbol은 TPM을 합치고 빈 symbol과 무한대 값은 제거해.
4. EOCRC 42개와 LOCRC 44개, 총 86개 샘플이 모두 유지되는지 확인해.
5. 공식 xCell 1.1.0 R 패키지를 재현 가능한 Bioconductor Docker 환경에 설치하고 86개 샘플을 한 번에 xCellAnalysis에 넣어. Tumor와 Normal을 별도 실행하지 마.
6. 결과는 행이 cell type, 열이 sample인 outputs/xcell-scores.tsv로 저장해.
7. metadata와 연결해 각 코호트 안의 Tumor와 Normal은 paired 비교하고, EOCRC Tumor 21개와 LOCRC Tumor 22개는 Mann-Whitney U test로 비교해.
8. 모든 cell type에 Benjamini-Hochberg 보정을 적용하고 outputs/xcell-tumour-comparisons.csv에 저장해.
9. score를 percentage, proportion 또는 실제 cell count라고 부르지 마.
10. 현재 annotation과 package로 다시 실행한 탐색적 결과와 논문 보고를 구분해 설명한 뒤 멈춰.
```

[![EOCRC와 LOCRC 종양의 xCell enrichment score](/images/practice/eocrc-day7/xcell-tumour-scores.png)](/images/practice/eocrc-day7/xcell-tumour-scores.png)

*실제 실행 결과: GENCODE v50 exon-union 길이로 raw count를 TPM으로 바꾸고 공식 xCell 1.1.0을 86개 샘플에 함께 실행했습니다. 종양끼리 비교하면 EOCRC에서 MSC, basophil, DC score가 높고 smooth-muscle score가 낮았습니다. 전체 cell type을 보정한 p-value는 각각 0.0090, 0.0420, 0.0486, 0.000094였습니다. Epithelial-cell score 차이는 보정 후 유의하지 않았습니다(p=0.0797).*

### 같은 score라도 비교 방향이 다르다

| 비교 | 짝지음 | 읽을 수 있는 내용 |
| --- | --- | --- |
| EOCRC Tumor 대 같은 환자의 Normal | paired | 암 발생과 함께 해당 signature가 변했는가 |
| LOCRC Tumor 대 같은 환자의 Normal | paired | 후기 발병군에서도 같은 변화가 있는가 |
| EOCRC Tumor 대 LOCRC Tumor | unpaired | 두 환자군의 종양 score가 다른가 |
| 서로 다른 cell type의 score | 직접 비교하지 않음 | 어느 세포가 몇 배 더 많다고 말할 수 없음 |

원 논문은 연구 코호트에서 여러 immune·stromal signature 차이를 관찰했지만 TCGA에서 대부분 재현되지 않았습니다. 이는 xCell이 쓸모없다는 뜻이 아니라, 코호트와 플랫폼에 민감한 결과를 독립 자료에서 다시 확인해야 한다는 뜻입니다.

## 5. 결과를 보고 답할 질문

1. 논문의 48개 목록과 현재 재현 후보를 섞으면 안 되는 이유는 무엇인가?
2. 유사한 GO term 여러 개가 같은 유전자 집합에서 나올 수 있는 이유는 무엇인가?
3. xCell score가 세포 비율이 아닌데도 샘플 비교에 쓸 수 있는 이유는 무엇인가?
4. Tumor와 Normal 비교는 왜 paired 검정을 사용해야 하는가?
5. 연구 코호트에서 보인 차이가 TCGA에서 재현되지 않으면 결론을 어떻게 좁혀야 하는가?

다음 [EOCRC 실습 3](/practice/eocrc-tcga-survival/)에서는 8-gene expression과 환자별 추적 시간을 결합해 Cox risk score와 Kaplan–Meier curve를 만듭니다.

## 6. 출처와 재현 정보

- [EOCRC 원 논문](https://doi.org/10.3389/fonc.2024.1365762)
- [xCell 공식 저장소와 입력·해석 지침](https://github.com/dviraran/xCell)
- [xCell 원 논문](https://doi.org/10.1186/s13059-017-1349-1)
- [g:Profiler API와 공식 Python client](https://biit.cs.ut.ee/gprofiler/page/apis)

재현 기록에는 논문 supplementary 파일의 URL과 checksum, g:Profiler 데이터 버전, xCell 구현·버전, gene annotation, gene-length 정규화 방법과 검정 방법을 남깁니다.