如何将数据框中的基因对列转换为按字母排序的新列?
解决基因对按字母排序生成新列的问题
原始数据
现有数据框d如下:
> d gene_pair 1 ABHD4_ABHD5 2 ABL1_ABL2 3 ABR_BCR 4 ACAP2_ACAP3 5 ACTX_ACTR1B 6 ACVR2A_ACVR2B
其dput输出:
> dput(d) structure(list(gene_pair = c("ABHD4_ABHD5", "ABL1_ABL2", "ABR_BCR", "ACAP2_ACAP3", "ACTX_ACTR1B", "ACVR2A_ACVR2B")), row.names = c(NA, 6L), class = "data.frame")
需求与问题
需要新增一列sorted_gene_pair,让每个基因对按字母顺序排列。尝试以下代码时出现atomic错误:
d %>% rowwise() %>% mutate(paste(sort(strsplit(gene_pair, '_')), collapse = '_'))
预期输出的sorted_gene_pair列:
> d sorted_gene_pair 1 ABHD4_ABHD5 2 ABL1_ABL2 3 ABR_BCR 4 ACAP2_ACAP3 5 ACTR1B_ACTX 6 ACVR2A_ACVR2B
错误原因
strsplit()函数返回的是列表类型,直接对列表使用sort()会触发错误,因为sort()只能处理向量类对象,需要先提取列表中的向量元素。
解决方案
方法1:修正rowwise代码
在strsplit后用[[1]]提取列表内的向量,再排序拼接:
library(dplyr) d %>% rowwise() %>% mutate(sorted_gene_pair = paste(sort(strsplit(gene_pair, "_")[[1]]), collapse = "_")) %>% ungroup() # 用完rowwise建议取消分组
方法2:使用tidyr的separate+unite(更直观)
拆分基因对为两列,排序后再合并:
library(dplyr) library(tidyr) d %>% separate(gene_pair, into = c("g1", "g2"), sep = "_") %>% mutate( g1 = pmin(g1, g2), g2 = pmax(g1, g2) ) %>% unite(sorted_gene_pair, g1, g2, sep = "_")
方法3:用purrr处理列表(无需rowwise)
借助purrr::map_chr批量处理每个基因对:
library(dplyr) library(purrr) d %>% mutate(sorted_gene_pair = map_chr(gene_pair, ~paste(sort(strsplit(.x, "_")[[1]]), collapse = "_")))
运行结果
以上方法均可得到预期的sorted_gene_pair列,以方法1为例,输出如下:
> d gene_pair sorted_gene_pair 1 ABHD4_ABHD5 ABHD4_ABHD5 2 ABL1_ABL2 ABL1_ABL2 3 ABR_BCR ABR_BCR 4 ACAP2_ACAP3 ACAP2_ACAP3 5 ACTX_ACTR1B ACTR1B_ACTX 6 ACVR2A_ACVR2B ACVR2A_ACVR2B
内容的提问来源于stack exchange,提问作者Ishan Mehta
相关产品推荐
相关产品推荐

