【问题标题】:Check if at least two values per group of one df match in another one检查每组一个df是否至少有两个值与另一组匹配
【发布时间】:2018-11-07 14:31:53
【问题描述】:

假设我有一个看起来像这样的数据框。

df1:

ID      Skill        Community
1       IT              X
1       Analytics       X
1       ERP             X
2       Analytics       X
2       ERP             X
2       CRM             X
2       Finance         X

还有一个像这样的数据框:

df2:

ID        Skill
3         Public Speaking
3         IT
3         Management
3         ERP
4         HR
4         Finance
...

我的目标基本上是说如果一个特定的人(用其 ID 标识)与 df1 的某个人至少有 2 项共同技能,那么他应该也被分配到社区 X。

在上面的示例中,ID nº3 也应该分配给社区 X(因为他的技能是 IT 和 ERP,就像 ID nº1 一样),但是不是 ID nº4,因为他只有与 ID nº2(财务)匹配的技能。

对于 df2,我的预期输出应该如下所示:

ID      Skill                 Community
3       Public Speaking          X
3       IT                       X
3       Management               X
3       ERP                      X
4       HR                      NULL
4       Finance                 NULL
.....

目前,我仅将命令 %in% 与 df2[df2&Skill %in% df1$Skill,] 一起使用,但这仅检查 一项特定技能,不按ID处理。

您对我应该如何解决这个问题有任何想法吗?

任何帮助将不胜感激。

【问题讨论】:

  • @RonakShah,刚刚做到了:)
  • 如果 A 与 B 共享两个技能,并且与 C 共享两个技能,但 B 和 C 共享的技能少于两个怎么办?什么是 A 的社区?
  • 那么 A 应该被分配到 B 和 C 的社区。但是 B 不会被分配到 C 的社区
  • 好的,所以每个人分配的社区数量没有限制。
  • 确实,每个人分配的社区数量没有限制

标签: r group-by match conditional-statements lookup


【解决方案1】:

请在您的真实数据集上进行测试,看看以下是否有效。

library(dplyr)
library(tidyr)

df3 <- df2 %>%
  left_join(df1, by = "Skill") %>%
  drop_na(ID.y) %>%
  count(ID.x, ID.y) %>%
  filter(n > 1) %>%
  distinct(ID.x) %>%
  mutate(Community = "X") %>%
  select(ID = ID.x, Community) %>%
  left_join(df2, ., by = "ID")
df3
#   ID           Skill Community
# 1  3 Public Speaking         X
# 2  3              IT         X
# 3  3      Management         X
# 4  3             ERP         X
# 5  4              HR      <NA>
# 6  4         Finance      <NA>

数据

df1 <- read.table(text = "ID      Skill        Community
1       IT              X
                  1       Analytics       X
                  1       ERP             X
                  2       Analytics       X
                  2       ERP             X
                  2       CRM             X
                  2       Finance         X",
                  header = TRUE, stringsAsFactors = FALSE)

df2 <- read.table(text = "ID        Skill
3         'Public Speaking'
3         IT
3         Management
3         ERP
4         HR
4         Finance",
                  header = TRUE, stringsAsFactors = FALSE)

【讨论】:

  • 它看起来正在工作!我已经手动检查了两个示例。我会检查更多,让你知道。无论如何,非常感谢!
【解决方案2】:

另一种选择

library(data.table)
setDT(df2)

df2[, Community := 
        'X'[any(tapply(df1$Skill, df1$ID, function(x) sum(Skill %in% x)) >= 2)]
    , by = ID]

df2

#    ID           Skill Community
# 1:  3 Public_Speaking         X
# 2:  3              IT         X
# 3:  3      Management         X
# 4:  3             ERP         X
# 5:  4              HR      <NA>
# 6:  4         Finance      <NA>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多