更直接的方法来整理具有两个相似列的数据框?
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)
这很笨拙,我认为使用 tidyr
或 reshape2
有更好的方法,但我没有找到工作示例,我的笨拙方法奏效了。有一个更好的方法吗?一种将其放在一行中的方法?
另外,如果我的标签不好,请让我知道,以便以后发布。
这是我的 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
,它完全符合您的要求:它将一列作为输入,将其中的值分隔为“_”,并在必要时复制该行。
我正在做一个参考 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)
这很笨拙,我认为使用 tidyr
或 reshape2
有更好的方法,但我没有找到工作示例,我的笨拙方法奏效了。有一个更好的方法吗?一种将其放在一行中的方法?
另外,如果我的标签不好,请让我知道,以便以后发布。
这是我的 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
,它完全符合您的要求:它将一列作为输入,将其中的值分隔为“_”,并在必要时复制该行。