如何修复stringr正则代码中的mutate()报错?
解决Trinotate输出中提取GO术语的问题
错误原因分析
你的代码有两个核心问题:
- 调用
str_replace_all时传入了整个数据框practice,而不是目标列GOX——str_replace_all需要处理向量(单一列),传入数据框会触发类型转换警告,行数变化时还会出现长度不匹配错误。 - 正则表达式
\\w是匹配字母数字下划线,你用它做替换会把所有字母数字都删掉,完全违背了保留GO术语的需求。
正确解决方案
我们用str_extract_all提取所有符合GO:\\d+模式的内容(GO术语的标准格式是GO:+数字),结合dplyr和tidyr处理关联关系:
1. 模拟测试数据
先构造和你数据结构一致的测试集:
library(dplyr) library(stringr) library(tidyr) practice <- tibble( Gene = c("TRINITY_DN142883_c0_g1", "TRINITY_DN12345_c1_g2"), GOX = c("GO:0005737 (cytoplasm); GO:0005829 (cytosol); GO:0000166 (nucleotide binding)", "GO:0003677 (DNA binding); GO:0005634 (nucleus)") )
2. 提取并展开GO术语(每行一个术语+对应基因)
这是最常用的格式,方便后续分析:
practice %>% select(Gene, GOX) %>% # 提取GOX中所有符合GO:数字的术语,返回列表列 mutate(GO_terms = str_extract_all(GOX, "GO:\\d+")) %>% # 把列表列展开成多行,每个术语对应一行基因 unnest(GO_terms)
输出结果:
# A tibble: 5 × 3 Gene GOX GO_terms <chr> <chr> <chr> 1 TRINITY_DN142883_c0_g1 GO:0005737 (cytoplasm); GO:0005829 (cytosol); GO:0000166 (nucleo… GO:0005737 2 TRINITY_DN142883_c0_g1 GO:0005737 (cytoplasm); GO:0005829 (cytosol); GO:0000166 (nucleo… GO:0005829 3 TRINITY_DN142883_c0_g1 GO:0005737 (cytoplasm); GO:0005829 (cytosol); GO:0000166 (nucleo… GO:0000166 4 TRINITY_DN12345_c1_g2 GO:0003677 (DNA binding); GO:0005634 (nucleus) GO:0003677 5 TRINITY_DN12345_c1_g2 GO:0003677 (DNA binding); GO:0005634 (nucleus) GO:0005634
3. 合并GO术语为字符串(每个基因一行,术语用分隔符连接)
如果需要把单个基因的所有GO术语放在同一列:
practice %>% select(Gene, GOX) %>% mutate(GO_terms = sapply(str_extract_all(GOX, "GO:\\d+"), paste, collapse = ", "))
输出结果:
# A tibble: 2 × 3 Gene GOX GO_terms <chr> <chr> <chr> 1 TRINITY_DN142883_c0_g1 GO:0005737 (cytoplasm); GO:0005829 (cytosol); GO:0000166 (nucleo… GO:0005737, GO:0005829, GO:0000166 2 TRINITY_DN12345_c1_g2 GO:0003677 (DNA binding); GO:0005634 (nucleus) GO:0003677, GO:0005634
补充说明
- 正则
GO:\\d+可以精准匹配所有标准GO术语,如果你的数据里有更长的数字段(比如GO:0000001),这个表达式依然有效。 - 如果GOX列的格式有特殊符号(比如非分号分隔),可以调整正则或者先做字符串分割,比如用
str_split(GOX, "; ")再提取术语。
内容的提问来源于stack exchange,提问作者Seth
相关产品推荐
相关产品推荐

