如何将列内的峰位值转为列名,用dplyr/tidyr生成0/1峰存在矩阵?
基于dplyr/tidyr的实现方案
核心转换流程
通过两个标准tidyr函数即可完成全流程转换,自动保留物种与峰位的对应关系,不会残留肽段列信息:
- 一次性将所有肽段格式的列值拉成长表,剔除空值
- 基于长表结构转宽表,自动生成0/1存在性标记
可直接复现的代码
首先加载依赖包,构造与示例完全一致的参考数据库:
library(tidyverse) ref_db <- tibble( Species = c("cow", "sheep", "goat"), peptide1 = c(1110, 1111, NA), peptide2 = c(1112, 1112, 1113), peptide3 = c(NA, NA, 1114) )
全流程链式转换代码:
ref_result <- ref_db |> # 把所有peptide开头的肽段列转为长格式,丢弃肽段列名,只保留峰位值 pivot_longer( cols = starts_with("peptide"), names_to = NULL, values_to = "peak_pos" ) |> # 删除无峰位的空值行 drop_na(peak_pos) |> # 给存在的峰位赋值1,作为二进制标记的基础 mutate(peak_present = 1) |> # 转宽表:以Species为行标识,峰位为列名,缺失值自动补0 pivot_wider( id_cols = Species, names_from = peak_pos, values_from = peak_present, values_fill = 0 )
结果对齐调整
转换完成后如果需要和现有样本数据集的列顺序完全匹配,只需按样本的峰位顺序调整列即可:
# 替换为实际样本里的峰位列顺序 sample_peak_order <- c(1110, 1111, 1112, 1113, 1114) ref_result_final <- ref_result |> select(Species, all_of(as.character(sample_peak_order)))
转换后的结果和示例中的期望输出完全一致。
适配说明
- 流程中使用的
pivot_wider即提到的spread的新版替代函数,对多列批量场景的支持更完善,无需手动逐列处理即可适配所有肽段列。 - 整个转换过程自动保留物种与峰位的原始对应关系,不存在映射错配。
- 无需手动拆分长表/宽表,两个pivot函数即可完成全流程转换,全程不会保留肽段列的冗余信息。
内容的提问来源于stack exchange,提问作者Mulligan
相关产品推荐
相关产品推荐

