Skip to content

세 번째 수업: 한 샘플의 발현량 행렬 읽기: 실습 리뷰와 아웃라이어 유전자 탐색

This content is not available in your language yet.

두 번째 수업에서 우리는 조직에서 뽑은 RNA가 FASTQ → 품질관리 → 트리밍 → 정렬 → 정량(TPM) 을 거쳐 발현량 행렬이 되는 파이프라인을 개념으로 훑었습니다. 이번 수업은 그 파이프라인을 실제로 돌린 결과물을 로그·파일 단위로 리뷰하고, 거기서 나온 딱 한 명의 발현량 벡터 하나로 무엇을 할 수 있는지, 비정상적으로 튀는 유전자를 어떻게 골라내는지, 를 다룹니다.

오늘의 목표: ① 실습에서 실제로 쓴 STAR·RSEM·featureCounts 명령과 결과 파일을 열어 “잘 만들어진 데이터인지” 판별하는 법을 익히고, ② 샘플이 하나뿐일 때 공개 레퍼런스(GTEx·PCAWG)와 나란히 놓고 아웃라이어 유전자를 찾는 지표(백분위·z-score·fold change·max 비교)와 기능 분석까지 한 번에 꿴다. 지난 시간이 데이터 생성 편이었다면, 이번 시간은 RNA analysis (2): 해석 편입니다.


지난 시간에 개념으로 본 순서를, 이번엔 실제 명령을 붙여 끝까지 돌렸습니다.

FastQC → Trim Galore! → FastQC → STAR → (RSEM · featureCounts) → 후반 분석

  • 앞의 다섯 단계가 발현량 행렬을 만드는 과정,
  • 마지막 후반 분석이 이번 수업의 본론: 만들어진 행렬을 공개 데이터와 비교해 특이 신호를 잡는 과정입니다.

FastQC: 트리밍 전/후, 그리고 두 회사 데이터

섹션 제목: “FastQC: 트리밍 전/후, 그리고 두 회사 데이터”

이번 샘플은 같은 T0 종양을 두 시퀀싱 회사(Tempus, BostonGene)에 각각 맡긴 데이터입니다: 같은 검체를 재현성·검증 목적으로 두 곳에 보낸 것으로 보입니다.

FastQC를 트리밍 전(왼쪽)·후(오른쪽) 로 각각 돌려 비교했더니:

  • 트리밍 후 total read 수가 소폭 감소: 너무 짧은 read가 걸러졌기 때문.
  • 말단(3′ 끝) 품질이 개선: 품질 낮은 꼬리 부분이 잘려 나가서.
  • 원래 품질이 좋았고 어댑터 오염도 크지 않아, 이 데이터는 큰 보정 없이 통과. (일부 데이터에서 흔히 보이는 read 앞부분 어댑터 절단 이슈는 여기선 없었습니다.)

요지: FastQC의 결과는 “몇 점 이상 통과”가 아니라, 트리밍이 의도대로 저품질·어댑터를 걷어냈는지를 눈으로 확인하는 용도입니다. → 각 항목을 어떻게 읽는지는 QC(FastQC) 레퍼런스.

2. STAR: 실제로는 이런 명령을 썼다

섹션 제목: “2. STAR: 실제로는 이런 명령을 썼다”

지난 시간 슬라이드의 STAR 명령은 최소 입력만 담은 단순한 형태였습니다:

Terminal window
STAR --genomeDir ./ref \
--readFilesIn sample_R1_val_1.fq.gz sample_R2_val_2.fq.gz \
--runThreadN 8 --outSAMtype BAM SortedByCoordinate

그런데 실제 Sid 케이스의 로그를 참고하니 훨씬 더 정교한 옵션 세트를 쓰고 있었습니다. 핵심만 추리면:

Terminal window
STAR --runMode alignReads --runThreadN 16 \
--genomeDir .../STAR_genome_GRCh38_noALT_noHLA_noDecoy_v47_oh75 \
--readFilesIn boston/..._1_val_1.fq.gz boston/..._2_val_2.fq.gz \
--readFilesCommand zcat \
--twopassMode Basic \ # 새 splice junction 탐지 향상
--quantMode TranscriptomeSAM GeneCounts \ # RSEM용 transcriptome BAM 생성
--chimSegmentMin 15 --chimJunctionOverhangMin 15 \ # fusion transcript 탐지
--chimOutType Junctions WithinBAM SoftClip \
--alignSoftClipAtReferenceEnds Yes \ # breakpoint·fusion read 정렬 향상
--outFilterMultimapNmax 20 --outFilterMismatchNoverLmax 0.1 \
--alignIntronMin 20 --alignIntronMax 1000000 \
--outSAMtype BAM Unsorted --outSAMunmapped Within

대부분은 정렬 정확도를 높이는 조절값(mismatch 허용 비율, intron 길이 범위, score 최소 기준 등)이라, 옵션마다 논문을 찾을 필요는 없고 STAR 매뉴얼에 각 옵션의 기본값과 역할이 정리돼 있습니다. 다만 의미상 꼭 짚어야 할 네 가지가 있습니다:

옵션목적
--twopassMode Basic1차 정렬에서 발견한 splice junction을 참고해 2차로 다시 정렬 → 새 junction 탐지 향상
--chim* (chimeric 계열)fusion transcript 탐지: 종양 조직에는 insertion·deletion 등 구조 변이가 많아, 서로 다른 유전자가 이어 붙은 융합 전사체가 생김. 이를 잡기 위한 종양 특이 옵션
--quantMode TranscriptomeSAM뒤에서 RSEM이 TPM을 계산할 때 필요한 transcriptome 정렬 BAM을 추가로 생성
--alignSoftClipAtReferenceEnds Yesbreakpoint·fusion read의 끝부분을 soft-clip 허용 → 정렬 향상

STAR가 내놓는 것: 두 개의 BAM과 로그

섹션 제목: “STAR가 내놓는 것: 두 개의 BAM과 로그”

STAR는 중간 파일을 여럿 만들지만, 실제로 뒤에서 쓰이는 핵심 산출물은 세 가지입니다:

파일내용다음 단계
~.Aligned.out.bam게놈에 정렬된 기본 결과: read ID가 몇 번 염색체 어느 위치에 붙었는지featureCounts
~.Aligned.toTranscriptome.out.bam전사체(transcriptome)에 정렬된 결과RSEM
~.Log.final.out정렬 품질 요약 통계→ 품질 확인

💡 RSEM 단계에서 막힌다면 여기부터 의심하세요. RSEM은 게놈 BAM이 아니라 Aligned.toTranscriptome.out.bam을 입력으로 받습니다. STAR에 --quantMode TranscriptomeSAM을 주지 않으면 이 파일이 아예 안 만들어져서, RSEM이 넘어가지 않습니다. (실습 중 RSEM에서 하루 종일 헤맨 사례가 바로 이 지점일 가능성이 큽니다.)

STAR 로그 읽는 법: “잘 정렬됐나?”

섹션 제목: “STAR 로그 읽는 법: “잘 정렬됐나?””

정렬이 잘 됐는지는 Log.final.out 요약으로 판단합니다.

STAR Log.final.out 요약: Uniquely mapped reads % 95.27%, multi-mapping 3.73%, unmapped(too short) 0.25% 등

이 실습 샘플(BostonGene)의 STAR 요약. 입력 read 약 7,431만 개 중 Uniquely mapped 95.27%, multiple loci 3.73%, too-short unmapped 0.25%. splice·mismatch·chimeric 통계도 함께 보고된다.

주로 보는 세 수치:

지표좋은 기준이 데이터
Uniquely mapped reads %보통 ≥ 80% 면 양호95.27%: read 대부분이 게놈의 한 자리에 깔끔히 붙음
Multi-mapping %RNA-seq에서 5~15% 는 정상3.73%: 오히려 낮음
Unmapped %< 5% 권장합쳐도 1% 미만
  • Uniquely mapped가 높다는 건, read가 유래한 게놈 위치를 모호함 없이 특정했다는 뜻입니다. 이 데이터는 95% 이상이라 매우 깨끗합니다.
  • 만약 이 수치들이 나쁘게 나오면 → 트리밍을 조절해 대응합니다. 과하게 잘라 정렬이 안 되면 덜 자른 버전으로, 저품질이 남아 안 붙으면 더 자르는 식으로.

⏱️ 트리밍을 바꾸면 정렬을 처음부터 다시 해야 합니다. read 세트가 바뀌면 재정렬이 불가피하고, 이 데이터에서 정렬 한 번에 2~5시간이 걸렸습니다. 스레드(--runThreadN)를 늘리면 빨라지지만 장비 코어 수에 한계가 있습니다.

RSEM은 transcriptome BAM을 받아 TPM을 계산하는 도구입니다. 정확도 향상 옵션(--estimate-rspd 등)을 붙여 실행하면 두 개의 결과 파일이 나옵니다.

Terminal window
rsem-calculate-expression --alignments --paired-end \
--estimate-rspd --append-names -p 16 \
boston.Aligned.toTranscriptome.out.bam \
.../rsem_reference_GRCh38_gencode47/rsem_reference boston

~.genes.results: 유전자 수준 결과. 유전자마다 expected_count(read 카운트에 해당) · TPM · FPKM을 계산해 줍니다.

RSEM genes.results: gene_id, transcript_id(s), length, effective_length, expected_count, TPM, FPKM 컬럼

RSEM genes.results. 가운데 transcript_id(s) 컬럼이 그 유전자에 속한 모든 트랜스크립트를 콤마로 이어 붙여 놓아 길고 지저분해 보이므로, 여기서는 cut으로 그 컬럼을 잘라 gene_id · expected_count · TPM · FPKM만 보여준다.

~.isoforms.results: 트랜스크립트(아이소폼) 수준 결과. 같은 유전자라도 개별 아이소폼별로 카운트를 나눠 줍니다.

4. featureCounts: 나중을 위한 raw count

섹션 제목: “4. featureCounts: 나중을 위한 raw count”

TPM(RSEM) 은 지금처럼 한 샘플을 공개 레퍼런스와 비교할 때 쓰고, featureCountsraw count(정규화 전 원시 카운트) 행렬을 만드는 용도입니다.

Terminal window
featureCounts -T 16 -p -t exon -g gene_id --extraAttributes gene_name \
-a gencode.v47.annotation.gtf \
-o boston.featureCounts.txt boston.Aligned.out.bam
# 헤더·주석 정리해서 gene_id · gene_name · count 3컬럼으로
grep -v "^#" boston.featureCounts.txt \
| awk 'BEGIN{OFS="\t"} NR==1{print "gene_id","gene_name","count"} \
NR>1{print $1,$7,$NF}' > boston.gene_counts.tsv
  • 입력이 RSEM과 다릅니다. featureCounts는 게놈 정렬 BAM(Aligned.out.bam)과 GTF(유전자 위치 파일)를 받아, 각 gene_id에 속한 엑손 위치에 붙은 read를 셉니다. 별도 인덱스를 만들 필요 없이 GTF를 바로 씁니다.
  • 지금 당장은 raw count를 쓰지 않지만, 나중에 차등발현(DEG) 분석을 할 때 필요합니다: DESeq2 같은 도구가 “raw count를 달라” 고 못 박아 두었기 때문입니다(정규화를 자기가 직접 하려고).

💡 정리: Aligned.out.bam → featureCounts → raw count, Aligned.toTranscriptome.out.bam → RSEM → TPM. 같은 STAR 결과지만 어느 BAM을 먹이느냐로 갈립니다. → 발현량 행렬 형식

여기까지가 지난 시간에 예고한 “read에서 발현량 행렬까지” 를 실제로 완주한 부분입니다. 이제 그 행렬로 무엇을 할지가 남았습니다.


5. 후반 분석: 샘플이 딱 하나일 때

섹션 제목: “5. 후반 분석: 샘플이 딱 하나일 때”

지금까지 만든 것은 환자 한 명의 종양 조직 RNA-seq 프로파일 하나 입니다. 유전자 수만 개(주석 기준 약 6만 개) 각각의 발현량(TPM 또는 raw count)이 담긴 벡터 하나.

그래서… 이 중 뭐가 중요한가? 발현량 6만 줄을 눈으로 다 볼 수는 없습니다. 필요한 질문은 하나로 좁혀집니다:

“이 종양에서, 정상 조직이나 다른 암과 비교했을 때, 비정상적으로 발현이 튀는 유전자는 무엇인가?”

이 질문에 답하는 작업이 아웃라이어 유전자(outlier gene) 탐색입니다.

아웃라이어 개념: PCAWG 전체 암 분포에서 MDM2가 index tumor에서 크게 튀고, 대조로 ACTB는 분포 한가운데에 위치

아이디어. 가로축은 한 유전자의 발현량(TPM), 세로축은 그 발현량을 가진 샘플 수. 대부분의 종양(All tumors)은 MDM2가 낮게 몰려 있는데, 이 환자(Index tumor) 는 저 멀리 오른쪽: 육종(Sarcoma) 샘플들과 비교해도 튄다. 오른쪽 작은 그림의 ACTB(housekeeping 유전자)는 대조로, 누구에게나 높아 분포 한가운데 위치한다: 이런 건 아웃라이어가 아니다.

튄다고 곧 원인은 아니다: 해석의 함정

섹션 제목: “튄다고 곧 원인은 아니다: 해석의 함정”

발현량이 높게 튀는 걸 발견해도, 그 자체로 “이 유전자가 암을 일으켰다”고 말할 수는 없습니다. 높은 발현은 다음 중 무엇이든 될 수 있습니다:

성격의미
원인(cause)종양 발생·진행에 직접 기여
결과(consequence)종양 관련 pathway가 켜지면서 부차적으로 함께 오른 발현
상태(state)종양 미세환경 변화(저산소·영양 부족·전이 능력 획득 등)에 적응하며 바뀐 발현

지금 데이터에서 확실히 아는 건 “발현이 튄다” 뿐입니다. 인과를 밝히려면 아래가 함께 필요합니다:

WGS 변이 분석 + pathway 분석 + 문헌조사: 예컨대 과발현이 이 유전자 자체의 변이 때문인지, 아니면 변이는 없는데 다른 조절 유전자의 영향으로 튀는 것인지를 가르고, 후자라면 그 조절 고리를 끊는 접근을 생각해 볼 수 있습니다. 여기에 다른 오믹스(예: 전사인자·효소가 붙을 수 있는 열린 자리를 보는 ATAC-seq)를 얹어 층층이 확인합니다.

그럼에도 아웃라이어 탐색이 유용한 이유는, 정상·타 환자 대비 변화가 분명한 유전자를 추려 표적 치료 후보·후보 약물 탐색의 출발점으로 삼을 수 있기 때문입니다: Sid 케이스가 MDM2 과발현을 표적으로 잡은 것처럼.

한 샘플을 “비교”하려면 기준이 될 공개 레퍼런스가 필요합니다. Sid가 쓴 것과 같은, 바로 받아 쓸 수 있는 TPM 수준의 두 데이터를 썼습니다:

레퍼런스규모성격
GTEx74,628 genes · 19,616 샘플 (31 조직)정상 조직 발현
PCAWG (EBI 경유)56,717 genes · 1,350 샘플 (27 암종)다른 암 환자 발현

세 데이터셋(내 샘플 + GTEx + PCAWG)에 모두 존재하는 공통 유전자 45,698개만 추려서 비교했습니다.

🧩 실습에서 암 레퍼런스는 EBI(유럽 생물정보학 연구소) 의 Expression Atlas에서 받은 PCAWG 데이터를 써서, 그림·표에 ebi 라는 라벨로 표기했습니다. 지난 수업에서 소개한 PCAWG와 같은 계열입니다.

본론에 들어가기 전에, 만든 count가 믿을 만한지 먼저 봅니다. 같은 검체를 두 회사에 맡긴 데이터이므로, 둘의 발현량은 비슷한 분포여야 합니다.

Boston Gene(y) vs Tempus(x) 종양 TPM 산점도: 대각선을 따라 강한 상관, MDM2·PANX3는 오른쪽 위, FAP는 중간

같은 환자·같은 시점(T0)을 두 회사에서 시퀀싱한 결과의 log2(TPM+1) 산점도. 완전한 직선은 아니지만 대각선을 따라 강한 상관을 보여, 발현량 정량이 재현성 있게 만들어졌음을 확인. 뒤에서 다룰 후보 유전자(MDM2·PANX3·FAP)의 위치도 표시돼 있다.

검증 ②: 이미 알려진 유전자가 실제로 튀는가

섹션 제목: “검증 ②: 이미 알려진 유전자가 실제로 튀는가”

Sid 케이스에서 질병 관련 유전자로 명시됐던 것들이, 내 데이터에서도 같은 패턴으로 튀는지 봅니다.

FAP 유전자의 TPM 분포: GTEx(정상, 파랑)와 EBI(암, 초록) 분포 위에 종양 값(주황 점선 Tumor=52.8)이 오른쪽에 위치

한 플롯이 유전자 하나에 대응한다. 가로축은 log2(TPM+1), 세로축은 샘플 수. 파란색은 GTEx(정상), 초록색은 EBI(암) 분포이고, 주황 점선이 내 종양 값이다. FAP는 원래 싱글셀 데이터에서 찾아낸 표적이라 total RNA에서는 신호가 아주 도드라지진 않지만(그래도 과발현 쪽), 주요 표적으로 거론된 다른 유전자들은 분포를 한참 벗어나 찍힌다.

읽는 법: 대부분의 샘플은 히스토그램 중심 근처에 발현량이 몰려 있고, 내 샘플(주황 선)이 그 중심에서 얼마나 오른쪽으로 벗어났는지가 곧 “튀는 정도”입니다. 이건 Sid가 공개 뷰어에서 보여준 그림과 같은 형식입니다.

유전자 4.5만 개를 눈으로 다 볼 수는 없으니, 수치로 아웃라이어를 추리는 지표가 필요합니다. 종양 TPM을 레퍼런스 분포와 견주는 네 가지를 씁니다.

지표무엇을 보나기준 예시
백분위 순위(percentile)내 TPM이 레퍼런스 분포에서 상위 몇 % 인가max · 상위 1% · 5% 등
Z-score레퍼런스 평균에서 표준편차 몇 배 떨어졌나∣Z∣ ≥ 2
Fold change레퍼런스 중앙값(median)의 몇 배 인가log2FC ≥ 2 → 4배 이상
Max comparison정상에서 관찰된 최댓값보다도 종양이 높은가True / False (직접 비교)
  • Z-score가 특히 유용한 이유: 샘플이 하나뿐이라 p-value를 직접 구하긴 어렵습니다. 대신 레퍼런스 분포를 평균 0·표준편차 1로 표준화하고 내 값을 그 위에 찍으면, “분포에서 얼마나 극단인지”를 한 숫자로 표현할 수 있습니다.

  • Fold change는 로그2 스케일로 봅니다:

    log2FC=log2 ⁣(tumor TPM+1median reference TPM+1)\text{log2FC} = \log_2\!\left(\frac{\text{tumor TPM} + 1}{\text{median reference TPM} + 1}\right)

    log2FC = 2 면 4배, = 9 면 512배입니다. (+1은 TPM이 0인 유전자에서 로그가 발산하지 않게 하는 보정.)

  • Max comparison은 논문에 자주 등장하는 정식 지표는 아니지만, Sid 케이스가 GTEx의 조직별 max TPM 과 직접 비교한 방식이라 재현 차원에서 넣었습니다. 수치가 아니라 True/False: “정상 최댓값조차 넘겼나?” 를 봅니다.

실제 계산: 알려진 표적 유전자들

섹션 제목: “실제 계산: 알려진 표적 유전자들”

암(EBI/PCAWG) 레퍼런스로 계산한 결과의 일부입니다. ebi_median·ebi_max는 암 환자 약 1,350명의 그 유전자 발현량의 중앙값·최댓값입니다.

genetumor TPMebi medianebi maxz-scorelog2FC≈ 배수
PANX3619.430.13819.849.14≈ 560×
MDM21235.724.95427314.475.32≈ 40×
FAP52.762.03011.973.75≈ 13×
  • PANX3를 보면: 암 환자 중앙값이 0.138인데 내 종양은 619.43. 백분위로 최댓값마저 넘고, z-score는 19.84(평균에서 표준편차 20배 거리!), 중앙값 대비 약 560배(log2FC 9.14) 발현입니다. 교과서적인 아웃라이어죠.
  • MDM2는 Sid가 실제 표적으로 삼은 유전자로, 종양 TPM 1235.72: 공개 뷰어에서는 1500 언저리로 표시되는 값입니다.
  • FAP는 신호가 상대적으로 약합니다(z ≈ 2). total RNA에서는 도드라지지 않는, 싱글셀에서 잡힌 표적이라는 점과 일치합니다.

1차 필터: 정상/암 최댓값 대비 2배 선

섹션 제목: “1차 필터: 정상/암 최댓값 대비 2배 선”

여러 지표를 조합해 후보를 좁힙니다. 예컨대 종양 TPM을 EBI 암 max TPM과 직접 산점도로 놓고, 대각선(y=x)과 그 2배 선(log2 기준 +1)을 그으면:

Boston 종양 TPM(y) vs EBI 암 max TPM(x) 산점도: y=x 대각선과 2배 선 위로 PANX3·MDM2가 크게 벗어나 있음

점 하나가 유전자 하나(27개 암종·1,350 샘플의 max 기준). 대각선(y=x)은 “암 최댓값과 같음”, 위쪽 점선은 그 2배 선. PANX3·MDM2처럼 2배 선을 넘어 위로 벗어난 유전자가 1차 아웃라이어 후보다. max 기준이라 종양에서만 튀는 완벽한 그림은 아니고(샘플 간 변이가 있어), 그래서 여러 지표를 함께 본다.

이렇게 레퍼런스 max·중앙값 대비 2배 이상 벗어난 유전자를 1차 아웃라이어로 추려 냅니다. 한 지표로 순위를 매길 수도, 여러 지표를 조합할 수도 있습니다.

8. 그다음: 기능 분석과 문헌조사

섹션 제목: “8. 그다음: 기능 분석과 문헌조사”

아웃라이어 유전자 목록(예: 상위 100개)을 얻었으면, 이들이 어떤 생물학적 기능에 얽혀 있는지 봅니다.

g:Profiler / NetworkAnalyst 같은 기능 강화(enrichment) 분석 도구는, 유전자 리스트를 입력받아 “이 목록 안에 어떤 pathway·GO term에 속한 유전자가 많이 들어 있는지” 를 통계적으로(p-value와 함께) 알려 줍니다.

g g 결과: GO receptor-mediated endocytosis, GO cytoskeleton, KEGG의 HIF-1 signaling pathway 등이 유의하게 강화됨

상위 100개 아웃라이어를 g:Profiler에 넣은 결과. HIF-1 신호(저산소 적응·악성화), cytoskeleton(세포 이동·전이), receptor-mediated endocytosis(신호 수용체 체내화·증폭) 등 종양과 맞닿은 term이 유의하게 떴다.

아쉬운 점도 솔직히: 골육종·암 term이 직접 뜨길 기대했지만 그렇게 선명하진 않았습니다. 그래도 이 유전자들이 주로 관여하는 pathway를 알면, 표적을 찾는 탐색 범위를 좁히는 나침반이 됩니다. 여기에 문헌조사(기존 약물·다른 질환에서의 표적 활용 여부)와 멀티오믹스(변이 탐색으로 과발현의 원인이 변이인지 확인 → 변이 표적 약물 설계)를 얹어 인과에 다가갑니다.

  • HISAT2 + StringTie 조합 실습 보완 (STAR+RSEM의 대안 경로)
  • 컨벤셔널 bulk RNA-seq 분석: 차등발현 유전자 분석(DEG, DESeq2), 그리고 GO / GSEA 기능 분석·시각화. (다른 public sample이 추가로 필요해 진행 여부는 논의)
  • 못다 한 추가 실습은 각자 이어서 돌려 보시면 좋습니다.

오늘은 발현량 행렬을 실제로 만든 뒤, 그것으로 무엇을 하는지를 끝까지 따라갔습니다:

STAR 로그로 정렬 품질 확인 → RSEM(TPM)·featureCounts(count) 산출 → 한 샘플을 GTEx·PCAWG와 비교 → 백분위·z-score·fold change·max로 아웃라이어 추출 → 기능(pathway) 분석

핵심은, 샘플이 하나뿐이어도, 잘 고른 레퍼런스 분포 위에 내 값을 얹기만 하면, “비정상적으로 튀는 신호”를 정량적으로 집어낼 수 있다는 점입니다. Sid가 표적을 찾은 길이 바로 이것이었습니다. 다만 튄다 ≠ 원인이라는 것, 그래서 변이·pathway·문헌이 함께 가야 한다는 것을 잊지 않기로 합니다.