检查一个 df 的每组是否至少有两个值与另一个 df 匹配

Check if at least two values per group of one df match in another one

假设我有一个如下所示的数据框。

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
...

我的目标是基本上说 if 一个特定的人(用其 ID 标识)至少有 2 个技能与 df1,那么他也应该被分配到社区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对待。

你知道我应该如何解决这个问题吗?

如有任何帮助,我们将不胜感激。

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

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)

另一种选择

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>