R语言tidyverse:dplyr/ggplot2/tidyr数据清洗

695 字
3 分钟
R语言tidyverse:dplyr/ggplot2/tidyr数据清洗

生信分析中 80% 的时间不是在跑流程,是在处理数据——读入表达矩阵、过滤低表达基因、合并样本注释、画个 PCA 看看分组。这套活 R + tidyverse 比 Python 快一个量级。

实测环境:Debian 13,R 4.x,tidyverse 2.0。

1. 安装 tidyverse#

install.packages("tidyverse")
library(tidyverse)
# 一次性加载 dplyr, ggplot2, tidyr, readr, stringr, purrr 等

如果用 Conda:

Terminal window
conda install -c conda-forge r-tidyverse -y

2. dplyr——数据操作的灵魂#

生信最常见的数据操作场景:表达矩阵的过滤、排序、分组统计。

# 读入差异表达结果(CSV格式)
degs <- read_csv("DEG_results.csv")
# 筛选 |log2FC|>1 且 padj<0.05 的基因
sig_degs <- degs %>%
filter(abs(log2FoldChange) > 1, padj < 0.05)
# 按log2FC从大到小排列
sig_degs <- sig_degs %>%
arrange(desc(log2FoldChange))
# 只看前10个
top10 <- sig_degs %>% slice_head(n = 10)
# 新增一列:上调/下调/不变
degs <- degs %>%
mutate(
direction = case_when(
log2FoldChange > 1 & padj < 0.05 ~ "Up",
log2FoldChange < -1 & padj < 0.05 ~ "Down",
TRUE ~ "NS"
)
)
# 统计方向分布
degs %>% count(direction)

%>% 管道符: 把左边的输出作为右边函数的第一个参数。让你按”先做什么再做什么”的思维顺序写代码,不用反复嵌套括号。

3. ggplot2——生信绘图常用#

# 火山图
ggplot(degs, aes(x = log2FoldChange, y = -log10(padj), color = direction)) +
geom_point(alpha = 0.5, size = 0.8) +
scale_color_manual(values = c("Up" = "red", "Down" = "blue", "NS" = "grey70")) +
geom_vline(xintercept = c(-1, 1), linetype = "dashed", alpha = 0.3) +
geom_hline(yintercept = -log10(0.05), linetype = "dashed", alpha = 0.3) +
theme_bw() +
labs(title = "Differential Expression", x = "log2 Fold Change", y = "-log10(padj)")
# PCA图
pca <- prcomp(t(expr_matrix), scale. = TRUE)
pca_df <- as.data.frame(pca$x) %>%
mutate(sample = rownames(.))
ggplot(pca_df, aes(x = PC1, y = PC2, color = group)) +
geom_point(size = 3) +
stat_ellipse(level = 0.95) +
theme_minimal() +
labs(x = paste0("PC1 (", round(summary(pca)$importance[2,1]*100), "%)"))

ggplot2 核心语法: ggplot(data, aes(x, y, color)) + geom_xxx() + theme_xxx()。理解了这个”通过+号叠加图层”的哲学,剩下的就是查文档。

4. tidyr——长宽数据转换#

生信数据经常需要在”长格式”和”宽格式”之间切换:

# 宽→长(基因表达矩阵→ggplot友好格式)
expr_long <- expr_matrix %>%
rownames_to_column("gene") %>%
pivot_longer(-gene, names_to = "sample", values_to = "expression")
# 长→宽(合并多列)
sample_info %>%
unite("condition_replicate", condition, replicate, sep = "_") %>%
pivot_wider(names_from = condition_replicate, values_from = expression)

5. readr + stringr#

# 快速读入大文件(比read.csv快5-10倍)
expr <- read_tsv("expression_matrix.txt")
# 字符串处理:提取样本名
sample_names <- colnames(expr) %>%
str_extract("Sample_\\d+") %>%
str_remove_all("Sample_")

6. 实用组合:表达矩阵一键清洗#

clean_matrix <- function(mat, min_expr = 1, min_samples = 3) {
mat %>%
rownames_to_column("gene_id") %>%
filter(rowSums(select(., -gene_id) >= min_expr) >= min_samples) %>%
column_to_rownames("gene_id")
}

7. 踩坑#

坑1:%>%|> 的区别——R 4.1 引入了原生管道 |>,但大部分生信包还是用 %>%。不要混用。

坑2:group_by 后忘记 ungroup——后续操作会按分组继续,导致预期外的结果。

坑3:pivot_longer 列名太多内存溢出——生信矩阵常有 50000 行 × 500 列,转成长格式会暴涨。先过滤再 pivot。


本文于 2025-05-15 实测。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

R语言tidyverse:dplyr/ggplot2/tidyr数据清洗
https://fg.ink/posts/r-tidyverse-bioinfo-basics/
作者
风观
发布于
2025-11-01
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
风观
风有来路,观有所思
分类
标签
站点统计
文章
50
分类
1
标签
29
总字数
61,837
运行时长
0
最后活动
0 天前

文章目录