【问题标题】:How to merge data.table with potential matches in different columns?如何将 data.table 与不同列中的潜在匹配项合并?
【发布时间】:2021-04-16 23:23:24
【问题描述】:

我正在尝试使用data.table 合并使用多列的两个数据表。

一个数据集的不同名称记录在不同的列中。例如:

records <- data.table(name1 = c("Apple25", "Banana20", "PassionFruit97", "junk4", "sdfd", "dbfg", "sdeg", "sdgwe", "wegd"),
                      name2 = c("abxd", "dseg", "degd", "apple200", "banana5132", "PassionFroot", "jusd", "sged", "egsd"),
                      name3 = c("jefds", "sdefsd", "dgeds", "dbsed", "sdfd", "dbfg", "Apel", "BNNA", "PF"))

我知道这些是三种水果(苹果、香蕉和百香果)的记录,但这些信息可能在三列中的任何一列中。

我有另一个映射数据集,其中records 中每一列的特定名称链接到一个标准化的水果名称:

mapping <- data.table(std_name = c("apple", "banana", "passion fruit", "apple", "banana", "passion fruit", "apple", "banana", "passion fruit"),
                      name1 = c("Apple25", "Banana20", "PassionFruit97", NA, NA, NA, NA, NA, NA),
                      name2 = c(NA, NA, NA, "apple200", "banana5132", "PassionFroot", NA, NA, NA),
                      name3 = c(NA, NA, NA, NA, NA, NA, "Apel", "BNNA", "PF"))

现在,首先我有兴趣查看映射文件中有哪些记录(在本例中为 100%),我这样做了:

records[, mapped := tolower(name1) %in% na.omit(tolower(mapping$name1)) |
          tolower(name2) %in% na.omit(tolower(mapping$name2)) |
          tolower(name3) %in% na.omit(tolower(mapping$name3))]

(在有大小写差异的情况下使用 tolower)。

接下来,我有兴趣合并到mapping 以获得标准化的水果名称。一种方法是管道合并语句:

records_mapped <- merge(records, mapping[, .(name1, std_name)], all.x = T, by.x = "name1", by.y = "name1") %>%
  merge(., mapping[, .(name2, std_name)], all.x = T, by.x = "name2", by.y = "name2") %>%
  merge(., mapping[, .(name3, std_name)], all.x = T, by.x = "name3", by.y = "name3")

但这会导致重复的列,然后我必须合并它们。在 data.table 中执行此操作的优雅方法是什么?

【问题讨论】:

    标签: r merge data.table


    【解决方案1】:

    您可以获取长格式的数据,然后执行连接。

    library(data.table)
    dt1 <- melt(records, measure.vars = names(records))
    dt2 <- melt(mapping, id.vars = "std_name")
    records_mapped <- merge(dt1, dt2, all.x = T, by = "value")
    

    如果需要,您可以使用dcast 获取宽格式数据。

    【讨论】:

    • merge 方法只是将 join 与 [ 包裹起来,这样部分就可以简化为 dt2[dt1, on="value"]
    猜你喜欢
    • 1970-01-01
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    相关资源
    最近更新 更多