乐于分享
好东西不私藏

告别 Excel 复制粘贴!R 语言pivot_longer和pivot_wider保姆级图文教程

告别 Excel 复制粘贴!R 语言pivot_longer和pivot_wider保姆级图文教程

刚学 R 语言画图时,大家一定经历过这种绝望: 你手握一份完美的 Excel 表格,第一列是基因名,后面跟着 10 列不同样本的表达量。这在人类眼里看着极其舒服,简直是“高颜值”表格。 然而,当你兴冲冲地把它扔给 ggplot2 想画个多样本表达量箱线图时,却发现代码怎么都敲不对。 为什么?因为人类喜欢看“宽数据 (Wide Data)”,而计算机(尤其是 ggplot2)只认“长数据 (Long Data)”。今天,BioGenius 班就带大家彻底攻克 R 语言新手的终极噩梦——利用 tidyr 包的 pivot_longer() 和 pivot_wider(),实现数据的完美变形!

许多朋友们在文章发送后不能第一时间接收到相关通知,强烈建议您将我们公众号设置为星标,步骤为 :进入公众号BioGenius班主页点击右上角三个点下方第一个选项就是“设置星标”。

核心概念:什么是宽数据与长数据?

在动手敲代码前,我们必须先在脑海里建立直观的画面。

  • 宽数据 (Wide Data): 像我们平常用的 Excel 表。一个变量占一列。比如:一行是一个基因,后面的列分别是 Sample_1Sample_2Sample_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(10158),
  Control_2 = c(12149),
  Treat_1 = c(455060),
  Treat_2 = c(424855)
)

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_1Treat_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群。

——往期推荐——

来开发一个属于自己的R包吧

R语言中的统计建模:20个常见模型及其实现

生物信息学分析中的常见错误与误区:初学者避坑指南

一文讲透微生物组中的绝对丰度和相对丰度!

MetaboAnalyst 6.0代谢组学数据分析超详细教程 | 小白也能轻松上手!

【适合小白】代谢组学理论及流程详解!

R语言 | 数据清洗的20个高效技巧

总结 | 16S rRNA基因测序分析

总结 | 转录组

配色荒?配色难?paletteer包解君愁!

R语言 | 20个高效操作技巧

总结 | 宏基因组分析

R语言 | export包导出图片为PPT

Adobe Illustrator(AI)科研组图排版 | 保姆级教程(内附安装包)

投稿经验 | Frontiers in Microbiology

R更新后R包迁移及一键升级旧包

宏基因组 | 分析策略

总结 | Nature Microbiology文章复现

16S分析(二):测序数据分析

转录组分析(三):DESeq2差异表达

干货 | RNA-seq之R语言富集分析,KEGG、GO和GSEA实战详解

如果对您有帮助,请帮我们点一个在看,或者转发关注哦~这对我们真的很重要