我正在使用一种名为 OrthoFinder 的生物信息学工具,它根据序列相似性将来自不同基因组/物种的基因放入所谓的 Orthogroups 中。
其中一个输出文件会告诉您哪些基因属于哪个 Orthogroup。此处,第一列具有 Orthogroup ID。接下来的三列代表三个基因组。在基因组列中,每行包含适合每个 Orthogroup 的基因 ID。如果每个基因组的 Orthogroup 中有多个基因,则该算法会将基因放入以逗号分隔的列表中。
正交群 | 基因组1 | 基因组2 | 基因组3 |
---|---|---|---|
OG0000001 | 基因1,基因2,基因3 | 基因1 | |
OG0000002 | 基因5,基因6 | 基因4 | |
OG0000003 | 基因7 | 基因7,基因8 |
我想将包含基因 ID 的列中的数据分开,以便每个基因都有自己的行。我找到了有关如何使用
strsplit()
和 tidyr::seperate_longer_delim()
进行操作的信息。
我遇到的问题是每列都有不同数量的基因。在上表中,您可以在第二行 OG0000002 中看到,基因组 1 为 NA。因此,如果我使用基于基因组 1 的
strplit()
,我会丢失 OG0000002,以及基因组 2 和基因组 3 中的基因 ID。
当我尝试时:
separate_longer_delim(c(genome1, genome2, genome3), delim = ",")
我收到这样的错误:
中的错误: !在第 2 行中,无法将大小 2 的输入回收到大小 5。separate_longer_delim()
我需要一种方法来分隔每列中的元素,但如果每行中有不同数量的基因,则不会删除行。换句话说,每个基因在每个基因组中都应该有自己的行。
根据您的示例数据,以下解决方案将有效,并且如果所有列中的数据一致,应该扩展到您的完整数据集。
使用
tidyverse
:
library(dplyr)
library(tidyr)
# Your sample data
df <- data.frame(Orthogroup = c("OG0000001", "OG0000002", "OG0000003"),
genome1 = c("gene1, gene2, gene3", NA, "gene1"),
genome2 = c(NA, "gene5, gene6", "gene4"),
genome3 = c("gene7", "gene7, gene8", NA))
df1 <- df |>
pivot_longer(cols = starts_with("genome"),
names_to = "genome",
values_to = "genes") |>
separate_longer_delim(genes, delim = ", ") |>
mutate(row_id = row_number(), .by = c(Orthogroup, genome)) |>
complete(Orthogroup, genome, row_id) |>
pivot_wider(names_from = genome,
values_from = genes) |>
select(-row_id)
df1
# # A tibble: 9 × 4
# Orthogroup genome1 genome2 genome3
# <chr> <chr> <chr> <chr>
# 1 OG0000001 gene1 NA gene7
# 2 OG0000001 gene2 NA NA
# 3 OG0000001 gene3 NA NA
# 4 OG0000002 NA gene5 gene7
# 5 OG0000002 NA gene6 gene8
# 6 OG0000002 NA NA NA
# 7 OG0000003 gene1 gene4 NA
# 8 OG0000003 NA NA NA
# 9 OG0000003 NA NA NA
或者,您可以使用
cSplit()
包中的 splitstackshape
函数:
library(splitstackshape)
df1 <- data.frame(cSplit(df,
names(df[2:ncol(df)]), # All columns except the first one
",", # Delimiter
"long", # Rowise/long format
type.convert = "as.character")) # Value type