Phyloseq로 마이크로바이옴 분석하기 — QIIME2 결과를 R에서 다양성·조성으로 시각화

이 글에서 만들 것 — 앞선 QIIME2 글에서 만든 .qza 결과를 R의 phyloseq로 가져와, 마이크로바이옴 분석의 대표 그림 세 가지(알파 다양성 박스플롯 · 베타 다양성 PCoA · 분류군 조성 막대그래프)를 직접 그립니다. QIIME2가 데이터를 만드는 단계라면, phyloseq는 그걸 R에서 자유롭게 분석·시각화하는 단계입니다. 설치부터 그림까지 코드 한 줄마다 한글 설명을 붙였습니다.
🔗 관련 글 · 데이터 만들기(앞 단계): QIIME2로 시작하는 16S rRNA 분석 · 기본 개념: 마이크로바이옴 입문
1. phyloseq가 뭔가요?
phyloseq는 마이크로바이옴 데이터를 R에서 다루는 사실상 표준 패키지입니다(McMurdie & Holmes, 2013). 핵심은 흩어진 네 가지 정보를 하나의 객체로 묶는다는 점입니다.
| 구성요소 | 함수 | 내용 |
|---|---|---|
| OTU/ASV 테이블 | otu_table() | 시료 × ASV 개수 행렬(누가 얼마나 있나) |
| 분류표 | tax_table() | ASV별 분류(Kingdom…Species) |
| 시료 메타데이터 | sample_data() | 시료 정보(부위·시점·그룹 등) |
| 계통수 | phy_tree() | ASV 간 진화적 거리(UniFrac에 필요) |
이 넷이 한 객체(ps) 안에 들어 있으니, 시료를 거르거나 분류 수준을 바꾸면 네 정보가 항상 같이 움직입니다. 행과 이름을 일일이 맞추던 수작업이 사라지는 게 phyloseq의 진짜 이점입니다.
QIIME2와의 분업도 분명합니다. QIIME2가 원시 FASTQ를 ASV 테이블·계통수·분류까지 만들어 주면, phyloseq는 그 결과를 받아 ggplot2 기반의 유연한 그림과 통계로 잇습니다. R 시각화라는 점에서, 앞서 다룬 Volcano plot 글과 같은 ggplot2 계열입니다.
2. 사전 준비 — 설치
phyloseq는 CRAN이 아니라 Bioconductor에 있습니다. R(또는 RStudio)에서 한 번만 설치하면 됩니다.
# 1) Bioconductor에서 phyloseq 설치 (최초 1회)
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("phyloseq")
# 2) qiime2R: QIIME2 .qza를 phyloseq로 변환 (GitHub 배포)
if (!requireNamespace("remotes", quietly = TRUE))
install.packages("remotes")
remotes::install_github("jbisanz/qiime2R")
# 3) 함께 쓰면 좋은 패키지 (통계·그림)
install.packages(c("vegan", "ggplot2"))
왜 Bioconductor인가요? Bioconductor는 생물정보 R 패키지의 전용 저장소입니다.install.packages()(CRAN)로는 phyloseq가 안 깔리니, 반드시BiocManager::install()을 쓰세요.
3. 단계별 실행
QIIME2 글의 산출물 네 개(table.qza, rooted-tree.qza, taxonomy.qza, sample-metadata.tsv)가 한 폴더에 있다고 가정합니다. 그 폴더에서 R을 띄우세요.
STEP 1 — QIIME2 결과를 phyloseq로 가져오기
qiime2R::qza_to_phyloseq() 한 번으로 네 파일이 하나의 phyloseq 객체가 됩니다.
library(phyloseq); library(qiime2R); library(ggplot2)
ps <- qza_to_phyloseq(
features = "table.qza", # ASV 테이블 (시료 × ASV)
tree = "rooted-tree.qza", # 계통수
taxonomy = "taxonomy.qza", # 분류
metadata = "sample-metadata.tsv" # 시료 메타데이터
)
ps
STEP 2 — 객체 들여다보기
phyloseq 객체는 "몇 개 ASV × 몇 개 시료"로 요약됩니다. 본격 분석 전에 구조부터 확인합니다.
ps # 요약: ASV 수 × 시료 수 + 보유 구성요소
ntaxa(ps) # ASV 개수
nsamples(ps) # 시료 개수
rank_names(ps) # 분류 수준 (Kingdom … Species)
sample_variables(ps) # 메타데이터 열 이름 (body-site 등)
otu_table(ps)[1:5, 1:5] # ASV 테이블 일부 미리보기
STEP 3 — 전처리·필터링
분류가 안 됐거나 극히 드문 ASV는 잡음입니다. 솎아내고, 조성 그림용 상대풍부도 사본도 만들어 둡니다.
# 0) 메타데이터 열 이름 정리 (하이픈 등 → R 친화적: body-site → body.site)
colnames(sample_data(ps)) <- make.names(colnames(sample_data(ps)))
# 1) Phylum이 비었거나 미분류인 ASV 제거
ps <- subset_taxa(ps, !is.na(Phylum) & Phylum != "")
# 2) 저빈도 ASV 제거: 전체 합이 5 미만이면 버림
ps <- prune_taxa(taxa_sums(ps) >= 5, ps)
# 3) 상대풍부도(비율)로 변환한 사본 (조성·오디네이션용)
ps_rel <- transform_sample_counts(ps, function(x) x / sum(x))
왜 상대풍부도인가요? 시료마다 총 read 수가 달라서, 개수를 그대로 비교하면 깊게 읽은 시료가 무조건 커 보입니다. 합을 1(=100%)로 맞추면 비로소 구성 비율을 비교할 수 있습니다.
STEP 4 — 알파 다양성 (한 시료 안의 다양성)
plot_richness() 한 줄이면 시료 부위별 다양성 박스플롯이 나옵니다.
plot_richness(ps, x = "body.site", color = "body.site",
measures = c("Observed", "Shannon")) +
geom_boxplot(alpha = 0.6) +
theme_bw()
# 통계 검정: Shannon 다양성이 부위별로 다른가? (비모수)
rich <- estimate_richness(ps, measures = c("Observed", "Shannon"))
meta <- data.frame(sample_data(ps))
kruskal.test(rich$Shannon ~ meta$body.site)
Observed는 관측된 ASV 수(풍부도), Shannon은 종 수와 균등도를 함께 본 지표입니다. 부위별로 분포가 갈리면, 크러스컬-월리스 검정의 p값으로 그 차이가 우연인지 가늠합니다.
STEP 5 — 베타 다양성·오디네이션 (시료들 사이의 차이)
베타 다양성은 시료 간 군집 거리를 2차원으로 펼쳐 봅니다. 가장 흔한 조합이 Bray-Curtis 거리 + PCoA입니다.
# Bray-Curtis 거리 → PCoA 좌표
ord <- ordinate(ps_rel, method = "PCoA", distance = "bray")
plot_ordination(ps_rel, ord, color = "body.site") +
geom_point(size = 3) +
stat_ellipse() + # 그룹별 신뢰타원
theme_bw()
# 군집 차이 통계 검정: PERMANOVA
library(vegan)
bray <- phyloseq::distance(ps_rel, method = "bray")
adonis2(bray ~ body.site, data = data.frame(sample_data(ps_rel)))

PCoA에서 같은 부위 점들이 모이고 다른 부위와 떨어지면, 군집이 부위에 따라 다르다는 뜻입니다. 그 분리가 통계적으로 유의한지는 PERMANOVA(adonis2)의 p값으로 확인합니다. 그림과 검정을 짝으로 보고하는 게 표준입니다.
STEP 6 — 분류군 조성 막대그래프
"무엇이 얼마나 있나"는 막대그래프로 봅니다. 잘게 쪼개지지 않도록 문(Phylum) 수준으로 합쳐 그립니다.
# 문(Phylum) 수준으로 합치기
ps_phylum <- tax_glom(ps_rel, taxrank = "Phylum")
plot_bar(ps_phylum, x = "body.site", fill = "Phylum") +
geom_bar(stat = "identity", position = "stack") +
labs(y = "상대 풍부도") +
theme_bw()

tax_glom은 같은 문에 속한 ASV를 하나로 묶어, 막대가 수백 조각으로 부서지는 걸 막아 줍니다. 속(Genus) 수준이 보고 싶으면 taxrank = "Genus"로 바꾸고, 상위 몇 개만 남기면 더 읽기 쉽습니다.
4. 자주 발생하는 에러와 해결법
| 증상 | 원인 / 해결 |
|---|---|
qza_to_phyloseq 오류 | .qza 경로·이름 확인. QIIME2 버전 차이로 막히면 remotes::install_github("jbisanz/qiime2R")로 최신화. |
body.site 열을 못 찾음 | R이 하이픈을 .로 바꿉니다. STEP 3의 make.names()를 먼저 돌리고, sample_variables(ps)로 실제 이름을 확인하세요. |
| PCoA 점이 다 겹침 | 상대풍부도(ps_rel)로 거리 계산했는지 확인. 시료 수가 너무 적으면 분리가 약합니다. |
| 막대가 수백 조각으로 부서짐 | tax_glom으로 상위 수준(Phylum·Genus)에서 합치고, 상위 N개만 표시하세요. |
| UniFrac 거리 오류 | 계통수가 없어서입니다. import에 rooted-tree.qza를 넣었는지 확인. 없으면 Bray-Curtis 같은 비계통 거리를 쓰세요. |
| 그림 저장 시 한글 깨짐 | ggsave()에서 device = cairo_pdf를 쓰거나 한글 폰트를 지정하세요. |
5. 확장 / 응용
① microViz — 더 쉬운 현대적 래퍼 — phyloseq를 감싼 microViz(2021~)는 ord_explore()로 오디네이션을 인터랙티브하게 탐색하고, comp_barplot()으로 조성 그림을 깔끔하게 뽑습니다. 입문자에게 특히 편합니다.
② 차등 풍부도 — 조성 데이터의 함정 — "어떤 균이 그룹 간에 유의하게 다른가"는 일반 검정으로 다루면 안 됩니다. 마이크로바이옴은 합이 1인 조성(compositional) 데이터라서요. phyloseq_to_deseq2()로 DESeq2에 넘기거나, QIIME2 글에서 본 ANCOM-BC를 씁니다.
③ rarefaction 논쟁 — 시료마다 깊이를 통일하는 rarefying은 McMurdie & Holmes(2014)가 "정보를 버린다"며 비판했지만, 알파·베타 다양성에서는 여전히 흔히 씁니다. 정답보다는 분석 목적에 맞춰 택하는 영역입니다.
④ 차세대 객체 — mia / TreeSummarizedExperiment — Bioconductor는 phyloseq의 뒤를 잇는 TreeSummarizedExperiment 생태계(mia 패키지)로 옮겨 가는 중입니다. makeTreeSummarizedExperimentFromPhyloseq()로 변환해 양쪽을 오갈 수 있습니다.
6. References
- McMurdie, P. J., & Holmes, S. (2013). phyloseq: An R package for reproducible interactive analysis and graphics of microbiome census data. PLoS ONE, 8(4), e61217.
- McMurdie, P. J., & Holmes, S. (2014). Waste not, want not: why rarefying microbiome data is inadmissible. PLoS Computational Biology, 10(4), e1003531.
- Bisanz, J. E. (2018). qiime2R: Importing QIIME2 artifacts and associated data into R sessions. GitHub: jbisanz/qiime2R.
- Oksanen, J., et al. vegan: Community Ecology Package (R). (PERMANOVA /
adonis2) - Barnett, D. J. M., Arts, I. C. W., & Penders, J. (2021). microViz: an R package for microbiome data visualization and statistics. Journal of Open Source Software, 6(63), 3201.
- Bolyen, E., et al. (2019). Reproducible, interactive, scalable and extensible microbiome data science using QIIME 2. Nature Biotechnology, 37, 852–857.
Pipette & Pipeline · A bio portfolio journal — bridging research, data, and industry.
'Code Bench > Microbiome Tools' 카테고리의 다른 글
| QIIME2로 시작하는 16S rRNA 마이크로바이옴 분석 — Docker 설치부터 Diversity까지 (0) | 2026.05.28 |
|---|


