R语言中按Protein.ID合并Version列并解决键重复错误
解决蛋白质组学数据中合并同一蛋白对应软件版本的问题
首先来解释你遇到的错误:
Error: Each row of output must be identified by a unique combination of keys. Keys are shared for 5311 rows:
这个错误的核心原因是:你使用的分组/转换操作依赖的键(比如你用的Protein.ID)无法唯一确定输出行。具体来说:
- 用
spread()时,这个函数的作用是把列的取值转成新的列(比如把Version 1.1和1.2变成两列),但你的数据中同一个Protein.ID对应多个Version值,导致spread无法为每个Protein.ID生成唯一的一行,因此报错。 - 你之前的
summarise和aggregate只按Protein.ID分组,如果你的实际数据里存在同一个Protein.ID对应不同Protein name的情况,或者分组时没把Protein name纳入(毕竟它和Protein.ID是一一对应的),就会导致分组内的行无法被唯一标识,触发相同的错误。
接下来是针对你需求的正确解决方案:
你的目标是把同一个蛋白(对应唯一的Protein.ID和Protein name)的所有Version合并成逗号分隔的字符串,同时去重,所以需要同时按Protein.ID和Protein name分组,再合并Version。
方案1:使用dplyr(tidyverse)
library(dplyr) # 假设你的原始数据框名为allver.ids allver.mergeVerID <- allver.ids %>% # 同时按Protein.ID和Protein name分组,确保每组是唯一的蛋白 group_by(Protein.ID, `Protein name`) %>% # 先对Version去重,再用toString合并成逗号分隔的字符串 summarise(Version = toString(unique(Version)), .groups = "drop") # 合并后取消分组状态
方案2:使用base R
如果你不想加载额外包,用base R的aggregate也能实现:
allver.mergeVerID <- aggregate(Version ~ Protein.ID + `Protein name`, data = allver.ids, # 自定义函数:去重后合并 FUN = function(x) toString(unique(x)))
验证示例数据
用你给出的简化测试数据:
allver.ids <- data.frame( Version = c("1.1", "1.2", "1.1", "1.2"), Protein.ID = c("A", "A", "B", "B"), `Protein name` = c("name 1", "name 1", "name 2", "name 2") )
运行上面的代码后,会得到你期望的结果:
| Protein.ID | Protein name | Version |
|---|---|---|
| A | name 1 | 1.1, 1.2 |
| B | name 2 | 1.1, 1.2 |
另外补充一点:如果你之前用paste时没去重,是因为直接用paste(..., collapse = ", ")不会自动去重,加上unique()就能解决重复Version的问题。
内容的提问来源于stack exchange,提问作者Ryandcalvert
相关产品推荐
相关产品推荐

