【问题标题】:Is there a possibility to merge 2 dataframes in R, keeping only unique results with one of the columns as the dependency for which results are kept是否有可能在 R 中合并 2 个数据帧,只保留具有其中一列的唯一结果作为保留结果的依赖项
【发布时间】:2021-07-22 06:15:47
【问题描述】:

我知道这个问题令人困惑,但我不知道如何更好地表述它。我有 11 个包含 GOTerm IDS 格式的 xls 列表

ID   Category   Colour

这些列表总共包含大约 130k IDS,但其中只有 26k 是唯一的。

我按类别对 11 个列表进行了排名。我现在需要的是一种将 List 11 与 List 10 合并的方法,对于两个列表中的任何 ID,我希望将 ID 保留为较低的类别编号(在本示例中为类别 10)和匹配的颜色。

最好我想在一个脚本/所有列表的组合代码行中执行此操作。

例子

列表11

ID Category colour
1 Category11 red
2 Category11 red
3 Category11 red

列表10

ID Category colour
1 Category10 blue
2 Category10 blue
4 Category10 blue

我理想的合并结果应该是这样的:

ID Category colour
1 Category10 blue
2 Category10 blue
3 Category11 red
4 Category10 blue

然后对于新列表与列表 9 相同的事情,结果与列表 8 等等

【问题讨论】:

  • 问题确实令人困惑。无论如何,您是要在所有列表中仅保留 column10,还是在将其与 list9 和儿子合并时将其更改为 category9?
  • 如果一个 ID 在列表 11 10 和 9 中,而不是在最终列表中,则应显示类别 9

标签: r join merge


【解决方案1】:

这是您的问题的data.table 方法。代码的功能解释在代码的cmets中。

在这个解决方案中,没有合并不同的表。相反,它们是行绑定在一起的,并且每个 ID 只保留最先出现的行。

我不知道你是如何阅读你的 excels 的,但如果你用 L <- lapply(myexcelfiles, readxl::read_excel) 之类的东西阅读你的 excels,那么你的 excel 文件已经在一个列表中,你可以跳过下面的一些行并开始行DT <- rbindlist(L, id = "ListId")

library(data.table)
# Sample data
List11 <- fread("ID     Category    colour
1   Category11  red
2   Category11  red
3   Category11  red")
List10 <- fread("ID     Category    colour
1   Category10  blue
2   Category10  blue
4   Category10  blue")

# Add the items (in order!) to a list
L <- list(List10, List11)
# Put the list in one large data.table
# Get a ListId from the position in the list
DT <- rbindlist(L, id = "ListId")
#    ListId ID   Category colour
# 1:      1  1 Category10   blue
# 2:      1  2 Category10   blue
# 3:      1  4 Category10   blue
# 4:      2  1 Category11    red
# 5:      2  2 Category11    red
# 6:      2  3 Category11    red
# Only keep rows with the minimum ListId by ID
# and drop the ListId column afterward and order on ID
final <- setorder(DT[ , .SD[which.min(ListId)], by = ID][, ListId := NULL], ID)
#    ID   Category colour
# 1:  1 Category10   blue
# 2:  2 Category10   blue
# 3:  3 Category11    red
# 4:  4 Category10   blue

【讨论】:

    【解决方案2】:

    让我分享这个示例,它应该让您了解使用基本 R 的步骤。

    首先,让我们创建这两个数据框。 (list 在 R 中有所不同。)

    list11 <- data.frame(id = c(1, 2, 3),
                         category = "Category11",
                         colour = "red")
    list10 <- data.frame(id = c(1, 2, 4),
                         category = "Category10",
                         colour = "blue")
    

    这会导致:

    > list11
      id   category colour
    1  1 Category11    red
    2  2 Category11    red
    3  3 Category11    red
    > list10
      id   category colour
    1  1 Category10   blue
    2  2 Category10   blue
    3  4 Category10   blue
    

    接下来,您可以通过 ID 连接两个数据框:

    joined <- merge(x = list10, y = list11, by = "id", all = TRUE)
    

    这会给你:

    > joined
      id category.x colour.x category.y colour.y
    1  1 Category10     blue Category11      red
    2  2 Category10     blue Category11      red
    3  3       <NA>     <NA> Category11      red
    4  4 Category10     blue       <NA>     <NA>
    

    我们的想法是我们采用 x 列中存在的所有内容。只有当什么都没有时(=&lt;NA&gt;),我们才检查 y 列。这就是我们使用is.na()function 所做的:

    new10 <- joined[!is.na(joined$category.x), c("id", "category.x", "colour.x")]
    new11 <- joined[is.na(joined$category.x), c("id", "category.y", "colour.y")]
    > new10
      id category.x colour.x
    1  1 Category10     blue
    2  2 Category10     blue
    4  4 Category10     blue
    > new11
      id category.y colour.y
    3  3 Category11      red
    

    上面的merge 函数为我们提供了新的列名,所以我们必须重新设置它们:

    colnames(new10) <- c("id", "category", "colour")
    colnames(new11) <- c("id", "category", "colour")
    

    现在两个数据框都有相同的列名,我们可以使用:

    > final <- rbind(new10, new11)
    > final
      id   category colour
    1  1 Category10   blue
    2  2 Category10   blue
    4  4 Category10   blue
    3  3 Category11    red
    

    如果我们想这样做,我们终于可以排序了:

    > final <- final[order(final$id), ]
    > final
      id   category colour
    1  1 Category10   blue
    2  2 Category10   blue
    3  3 Category11    red
    4  4 Category10   blue
    

    要处理所有 XLS,您可以围绕它创建一个循环,或者使用数据框列表和 apply 覆盖它。

    【讨论】:

      猜你喜欢
      • 2018-01-29
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 1970-01-01
      相关资源
      最近更新 更多