背景:我正在使用 R 来帮助我找出文件 A 中的哪些条目(预期名称)映射到文件 B 中的哪些条目(可能的名称)。 不幸的是,文件 B 有多个具有相同 ID 和不同名称的条目。 有时这些名称与文件 A 中的 ID 完全匹配,但有时它们很接近或被改写。 目前,我正在查找那些直接的 1:1 匹配项,并删除具有相同 ID 的非匹配项。
问题:是否有更干净的方法来删除包含 1:1 匹配的组内的已知非匹配项,同时不删除其他组中的非匹配项?
示例数据:
example <- tribble(
~id, ~expect, ~possible, ~status,
1, "box of forks", "spoon drawer", "review",
1, "box of forks", "box of forks", "match",
1, "box of forks", "cheese knife", "review",
2, "dish washer", "dish washing machine", "review",
2, "dish washer", "oven", "review",
2, "dish washer", "microwave", "review",
)
在此示例中,第 2 行是 1:1 匹配,因此其状态为“匹配”。 我,绝对是一个人,知道第 4 行也是匹配的,因为我可以阅读和理解数据集。 因为我预计会有这样的情况,所以我不能简单地这样做
filter(status == "match")
。 但是,在开始阅读该文件之前,我想删除我现在知道将成为垃圾的行。 因此,我发现我可以做到:
example %>%
group_by(id) %>%
mutate(matches = case_when(
status == "review" ~ 0,
status == "match" ~ 1,
),
total = sum(matches)
) %>%
filter(
!(matches == 0 & total > 0)
)
这给出了正确/预期的结果:
id expect possible status matches total
<dbl> <chr> <chr> <chr> <dbl> <dbl>
1 1 box of forks box of forks match 1 1
2 2 dish washer dish washing machine review 0 0
3 2 dish washer oven review 0 0
4 2 dish washer microwave review 0 0
虽然这有效,但它看起来很笨重,让我很难过。 是否有一种更干净的方法来删除仍处于“审查”状态且存在于至少包含一行“匹配”的组内部的条目?
也许只需使用
all
。
example %>%
filter(all(status=="review") | status=="match", .by=id)
# A tibble: 4 × 4
id expect possible status
<dbl> <chr> <chr> <chr>
1 1 box of forks box of forks match
2 2 dish washer dish washing machine review
3 2 dish washer oven review
4 2 dish washer microwave review
这将保留匹配项或没有匹配项的 id 的所有观察值:
example |>
filter(status == "match" |
!any(status == "match"), .by = id)
结果
id expect possible status
<dbl> <chr> <chr> <chr>
1 1 box of forks box of forks match
2 2 dish washer dish washing machine review
3 2 dish washer oven review
4 2 dish washer microwave review