刚学 R 语言画图时,大家一定经历过这种绝望: 你手握一份完美的 Excel 表格,第一列是基因名,后面跟着 10 列不同样本的表达量。这在人类眼里看着极其舒服,简直是“高颜值”表格。 然而,当你兴冲冲地把它扔给
ggplot2想画个多样本表达量箱线图时,却发现代码怎么都敲不对。 为什么?因为人类喜欢看“宽数据 (Wide Data)”,而计算机(尤其是ggplot2)只认“长数据 (Long Data)”。今天,BioGenius 班就带大家彻底攻克 R 语言新手的终极噩梦——利用tidyr包的pivot_longer()和pivot_wider(),实现数据的完美变形!
许多朋友们在文章发送后不能第一时间接收到相关通知,强烈建议您将我们公众号设置为星标,步骤为 :进入公众号BioGenius班主页→点击右上角三个点→下方第一个选项就是“设置星标”。
核心概念:什么是宽数据与长数据?
在动手敲代码前,我们必须先在脑海里建立直观的画面。
宽数据 (Wide Data): 像我们平常用的 Excel 表。一个变量占一列。比如:一行是一个基因,后面的列分别是 Sample_1,Sample_2,Sample_3的表达量。适合人眼阅读,适合做 PCA、相关性热图。长数据 (Long Data): 把原本平铺的列,全部“压缩”成两列:一列叫“名字 (Name)”,一列叫“数值 (Value)”。比如:所有样本名都被塞进一列叫 Condition,所有表达量都被塞进一列叫Expression。这是ggplot2画图的唯一指定格式!
魔法一:宽变长 pivot_longer()
使用场景: 你手上的数据是基因表达矩阵、多组临床指标,你需要把它们融合在一起,丢给 ggplot2 画箱线图、小提琴图或折线图。
口诀: 把指定的宽列,捏成“名字”和“数值”两根柱子。
# 加载必备神包
library(tidyr)
library(dplyr)
# 1. 模拟一个常见的生信“宽数据”矩阵
wide_df <- tibble(
Gene = c("TP53", "BRCA1", "MYC"),
Control_1 = c(10, 15, 8),
Control_2 = c(12, 14, 9),
Treat_1 = c(45, 50, 60),
Treat_2 = c(42, 48, 55)
)
print("这就是人类爱看的宽数据:")
print(wide_df)
# 2. 施展魔法:变长!
long_df <- wide_df %>%
pivot_longer(
cols = -Gene, # 选中你要折叠的列(除了 Gene 列以外的所有列)
names_to = "Sample_Group", # 把原来的列名,统一放到一个叫 "Sample_Group" 的新列里
values_to = "Expression"# 把原来的数值,统一放到一个叫 "Expression" 的新列里
)
print("这就是 ggplot2 最爱的长数据:")
print(long_df)
实战 Tips: 在 cols 参数里,你可以用 starts_with("Control"),或者 1:4,甚至 -Gene 这种排除法,极其灵活!
魔法二:长变宽 pivot_wider()
使用场景: 你手里的长数据是从数据库下载的,或者你刚用 ggplot2 画完图,现在导师要求你把每个样本的表达量单独拉成一列,导出一个 Excel 附件表格;或者你需要把数据喂给 cor() 算相关性矩阵。
口诀: 把一根“名字”柱子拆成多列,把“数值”填进去。
# 我们把刚刚变形得到的 long_df,再给它变回去!
wide_again_df <- long_df %>%
pivot_wider(
names_from = Sample_Group, # 从哪一列提取新的列名?
values_from = Expression # 从哪一列提取对应的数值?
)
print("看,数据又变回宽格式了!")
print(wide_again_df)
进阶大招:边变长,边拆分列名!
很多时候,我们的样本命名包含了双重信息,比如 Treat_1, Treat_2,既包含了处理组 (Treat),又包含了重复批次 (1, 2)。pivot_longer 甚至可以帮你在一瞬间完成“变长 + 列名分割”的连招!
# 进阶魔法:直接把 Control_1 拆成 "组别" 和 "重复" 两列
advanced_long_df <- wide_df %>%
pivot_longer(
cols = -Gene,
names_to = c("Treatment", "Replicate"), # 告诉它我要拆成两个新列
names_sep = "_", # 按照下划线 "_" 进行拆分
values_to = "Expression"
)
print("进阶版长数据:自带元数据拆分!")
print(advanced_long_df)
拿到这个 advanced_long_df,你就可以直接 ggplot(aes(x = Treatment, y = Expression, fill = Treatment)),一张完美的差异对比图瞬间诞生。
结语
掌握 pivot_longer 和 pivot_wider,意味着你真正跨越了 R 语言数据处理的门槛。 不再需要纠结如何写繁琐的 for 循环,也不用在 Excel 里痛苦地复制粘贴转置。数据就像你手中的橡皮泥,想捏成什么形状就捏成什么形状。 熟练运用它们,你会发现 tidyverse 的数据哲学真的是一种艺术。
下期内容:字符串处理
此文是在自己的理解和参考网络资料后完成的,若有侵权,请联系删除。

END

加我微信拉你进交流群/VIP群。

——往期推荐——
MetaboAnalyst 6.0代谢组学数据分析超详细教程 | 小白也能轻松上手!
Adobe Illustrator(AI)科研组图排版 | 保姆级教程(内附安装包)
投稿经验 | Frontiers in Microbiology
干货 | RNA-seq之R语言富集分析,KEGG、GO和GSEA实战详解
如果对您有帮助,请帮我们点一个在看,或者转发关注哦~这对我们真的很重要
夜雨聆风