更直接的方法来整理具有两个相似列的数据框?

More direct way to tidy a data frame with two similar columns?

我正在做一个参考 table 以便在标识符和这些标识符的不同版本之间轻松转换。我有一个合并的 table 与包含来自多个版本数据库的 ID 的多个列(ipi_id.x & ipi_id.y,下面测试 df

    protein_id    ipi_id.x numbers      ensembl_id hgnc_number hgnc_symbol entrez_id    ipi_id.y uniprot
    1       ATP6 IPI00552036       3 ENSG00000198899        7414     MT-ATP6      4508 IPI00954924  P00846
    2       ATP6 IPI00552036       3 ENSG00000198899        7414     MT-ATP6      4508 IPI00743734  P00846
    3       ATP6 IPI00552036       3 ENSG00000198899        7414     MT-ATP6      4508 IPI00654820  P00846
    4       COX2 IPI00916440       1 ENSG00000198712        7421      MT-CO2      4513 IPI00930721  P00403
    5       COX2 IPI00916440       1 ENSG00000198712        7421      MT-CO2      4513 IPI00017510  P00403

两列 ipi_id.x 和 .y 对于相同的条目具有不同的版本标识符,我希望它们位于同一列中,但添加的行包含其余信息,以便每个 ipi_id 有自己的一行。结果df如下:

    protein_id    ipi_id   numbers      ensembl_id hgnc_number hgnc_symbol entrez_id   uniprot
    1       ATP6 IPI00552036       3 ENSG00000198899        7414     MT-ATP6      4508   P00846
    2       ATP6 IPI00552036       3 ENSG00000198899        7414     MT-ATP6      4508   P00846
    3       ATP6 IPI00552036       3 ENSG00000198899        7414     MT-ATP6      4508   P00846
    4       ATP6 IPI00954924       3 ENSG00000198899        7414     MT-ATP6      4508   P00846
    5       ATP6 IPI00743734       3 ENSG00000198899        7414     MT-ATP6      4508   P00846
    6       ATP6 IPI00654820       3 ENSG00000198899        7414     MT-ATP6      4508   P00846
    7       COX2 IPI00916440       1 ENSG00000198712        7421      MT-CO2      4513   P00403
    8       COX2 IPI00916440       1 ENSG00000198712        7421      MT-CO2      4513   P00403
    9       COX2 IPI00930721       1 ENSG00000198712        7421      MT-CO2      4513   P00403
    10      COX2 IPI00017510       1 ENSG00000198712        7421      MT-CO2      4513   P00403 

我通过复制数据框,删除重复数据框之一中的 .x 或 .y 列,重命名该列,然后使用 rbind 将两个重复数据框重新组合在一起并使用 unique() 删除重复的行。

df2 <- df
#remove ipi_id.X  IPI ids from one DF
df$ipi_id.x <- NULL
colnames(df)[7] <- "ipi_id"
#remove ipi_id.y  IPI ids from the other DF
df2$ipi_id.y <- NULL
colnames(df2)[2] <- c("ipi_id")
#combine the dataframes
df3 <- rbind(df, df2)
df3 <- unique(df3)

这很笨拙,我认为使用 tidyrreshape2 有更好的方法,但我没有找到工作示例,我的笨拙方法奏效了。有一个更好的方法吗?一种将其放在一行中的方法?

另外,如果我的标签不好,请让我知道,以便以后发布。

这是我的 df 的 dput 变量版本:

    df <- structure(list(
    protein_id = structure(c(1L, 1L, 1L, 2L, 2L), .Label = c("ATP6", "COX2"), class = "factor"), 
    ipi_id.x = structure(c(1L, 1L, 1L, 2L, 2L), .Label = c("IPI00552036", "IPI00916440"), class = "factor"), 
    numbers = c(3L, 3L, 3L, 1L, 1L), 
    ensembl_id = structure(c(2L, 2L, 2L, 1L, 1L), .Label = c("ENSG00000198712", "ENSG00000198899"), class = "factor"), 
    hgnc_number = c(7414L, 7414L, 7414L, 7421L, 7421L), hgnc_symbol = structure(c(1L, 1L, 1L, 2L, 2L), .Label = c("MT-ATP6", "MT-CO2"), class = "factor"), 
    entrez_id = c(4508L, 4508L, 4508L, 4513L, 4513L), ipi_id.y = structure(c(5L, 3L, 2L, 4L, 1L), .Label = c("IPI00017510", "IPI00654820", "IPI00743734", "IPI00930721", "IPI00954924"), class = "factor"), 
    uniprot = structure(c(2L, 2L, 2L, 1L, 1L), .Label = c("P00403", "P00846"), class = "factor")),
    .Names = c("protein_id", "ipi_id.x", "numbers", "ensembl_id", "hgnc_number", "hgnc_symbol", "entrez_id", "ipi_id.y", "uniprot"), class = "data.frame", 
    row.names = c(NA, -5L))

好了:

df %>% 
  unite(ipi_id, ipi_id.x, ipi_id.y, sep = "_") %>% 
  separate_rows(ipi_id, sep = "_")

它有什么作用?

unite 将 ipi_id.x 和 ipi_id.y 放在由“_”分隔的一列中,并删除原始变量 ipi_id.x 和 ipi_id.y。然后我们使用 tidyr 的 separate_rows,它完全符合您的要求:它将一列作为输入,将其中的值分隔为“_”,并在必要时复制该行。