【问题标题】:R - Merge two datasets if ALL values per group matchR - 如果每组的所有值都匹配,则合并两个数据集
【发布时间】:2018-12-02 10:57:45
【问题描述】:

假设我有两个数据框 df1 和 df2 如下:

df1:

EmployeeID     Skill
1                A
1                B
1                C
2                B
2                D
2                C
2                F
3                A
3                J

df2:

Opportunity.ID      Skill
12345               A
12345               B
56788               C
56788               B
56788               F
09988               H

我要做的是创建一个新的数据框,其中包含所有 EmployeeID 的特定 Opportunity.ID 所需的所有技能,而不仅仅是其中一个。这就是为什么简单的合并或左/右连接是不够的。 在我们的例子中,我想要的是:

Opportunity.ID         Employee.ID
12345                  1
56788                  2
09988                  NA

请注意,不应将员工 3 分配到机会 12345,因为他只有所需的两项技能中的一项

任何帮助将不胜感激。

【问题讨论】:

  • 你试过了吗?
  • 员工缺少技能E,因此不应分配给机会56788(除非您指的是E,而不是df1 中的F)。
  • 是的,我尝试进行合并并左连接,但它不起作用,因为当其中一个值存在时它会“匹配”
  • @Jaap 你是对的,我已经编辑了我的问题

标签: r merge group-by


【解决方案1】:

这是使用dplyr 的一种方式-

df2 %>% 
  left_join(df1, by = "Skill") %>% 
  group_by(Opportunity.ID) %>% 
  mutate(test = ave(Skill, EmployeeID, FUN = function(x) all(Skill %in% x))) %>%
  ungroup() %>% 
  filter(test != "FALSE") %>% 
  distinct(Opportunity.ID, EmployeeID)

# A tibble: 3 x 2
  Opportunity.ID EmployeeID
           <int>      <int>
1          12345          1
2          56788          2
3           9988         NA

【讨论】:

    【解决方案2】:

    可能有更好的解决方案,但使用-package 我得出了以下方法:

    library(data.table)  # load the package
    setDT(df1)           # convert 'df1' to a 'data.table'
    setDT(df2)           # convert 'df2' to a 'data.table'
    
    df2[, .(EmployeeID = df1[.SD[, .(Skill, n = .N)], on = .(Skill)
                             ][, .(ne = .N), by = .(EmployeeID, n)
                               ][n == ne, EmployeeID])
        , by = Opportunity.ID]
    

    给出:

       Opportunity.ID EmployeeID
    1:          12345          1
    2:          56788          2
    3:           9988         NA
    

    【讨论】:

    • 嗨@Jaap,感谢您的回答。但是,当我在我的数据集上运行此命令时,它似乎只基于一项技能进行匹配。在这种情况下,这意味着我将让员工 1,2 和 3 与 Opportunity.ID 12345 匹配,因为他们都具有技能 A
    • @AllanLC 不,它会匹配所有技能。您能否在您的问题中包含重现此问题的示例数据?
    猜你喜欢
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 2018-07-24
    相关资源
    最近更新 更多