在R中如何依据另一列表为数据框匹配添加对应基因名称新列
实现方案
首先先统一两个数据结构的命名,方便代码复用:
- 2031*2的果蝇-家蚕同源蛋白数据框记为
df_protein,用于匹配的蛋白列列名记为protein_id - 蛋白-基因名对应关系表记为
df_map,包含两列:gene_name(基因名称)、protein_id(对应蛋白ID)
方法1:基础R实现(无需额外安装包)
用match()函数匹配,不会改变原数据框的行顺序:
# 匹配填充新列,未匹配到的默认为NA df_protein$gene_name <- df_map$gene_name[match(df_protein$protein_id, df_map$protein_id)] # 可选:把NA替换为空字符串,和示例效果一致 df_protein$gene_name[is.na(df_protein$gene_name)] <- ""
方法2:dplyr实现(代码更易读)
用left_join关联两个表:
# 加载包 library(dplyr) # 关联填充新列,未匹配到的默认为NA df_protein <- df_protein %>% left_join(df_map, by = "protein_id") %>% # 可选:把NA替换为空字符串 mutate(gene_name = replace(gene_name, is.na(gene_name), ""))
如果两个表用于匹配的列名不同,修改by参数即可,比如df_protein的匹配列叫bombyx_protein,df_map的匹配列叫protein_id,就把by参数改为by = c("bombyx_protein" = "protein_id")。
示例验证
用你给出的示例数据测试,效果完全匹配:
# 模拟示例的List1 df_protein <- data.frame( col1 = c(1,2,3), protein_id = c("a","b","c") ) # 模拟示例的List2 df_map <- data.frame( gene_name = c("A","C"), protein_id = c("a","c") ) # 执行匹配后df_protein输出如下: # col1 protein_id gene_name # 1 1 a A # 2 2 b # 3 3 c C
注意事项
如果存在单个蛋白对应多个基因名的情况:
match()函数只会返回第一个匹配到的基因名,保持原数据框行数不变left_join()会为每个匹配到的基因名生成一行,原数据框行数会增加,按需选择即可。
内容的提问来源于stack exchange,提问作者程劲韬
相关产品推荐
相关产品推荐

