如何根据匹配的字段值比较两个数据框列之间的值?

时间:2021-06-07 13:58:22

标签: r dataframe match

我有两个数据框,df1df2,我想知道以下内容是否(很容易)可能:

对于每个匹配 df1$iddf2$id,我想将 df1$daydf2$day 进行比较,并将它们归类为 MATCHNO MATCH新列 (df1$matched) 取决于它们是否相同。

进一步说明:

如果 df1$id 中的值匹配 / 出现在 df2$id 中,那么我想针对该特定 df1$day 查看 df2$dayid。接下来,我想比较 df1$daydf2$day 的值,看看它们是相同的还是不同的。然后我想创建一个新列 (matched),根据它们是否相同对这些值进行分类。因此,对于 iddf1 之间的每个 df2 匹配,算法应该输出如下内容:

示例数据:

df1$id    df1$day
001       2
002       2
003       8
004       2
005       8
006       8

df2$id    df2$day
004       2
005       2
006       8
007       2
008       8

输出:

df1$id    df2$id    df1$day    df2$day    df1$match
004       004       2          2          MATCH
005       005       8          2          NO MATCH
006       006       8          8          MATCH

注意,结果可以存储在新的数据框中;只要它以这种方式(或类似方式)呈现数据就可以了。

我的第一个想法是这样的,但它需要很长时间来处理(df1 是 844,000 行深,df2 是 101,610,所以不是真正巨大的数据帧)只是最终失败,所以我显然做错了什么:

df1 %>% 
  filter(id %in% df2$id) %>% 
  mutate(
    matched = if_else(day == df2$day, "MATCH", "NO MATCH")
  )

我哪里出错了?

2 个答案:

答案 0 :(得分:3)

df1 <- read.table(text = 'id    day
001       2
002       2
003       8
004       2
005       8
006       8', header = T)

df2 <- read.table(header = T, text = 'id    day
004       2
005       2
006       8
007       2
008       8')

library(dplyr)


df1 %>% inner_join(df2, by = 'id') %>%
  mutate(match_yn = c('no_match', 'match')[1 + (day.x == day.y)])
#>   id day.x day.y match_yn
#> 1  4     2     2    match
#> 2  5     8     2 no_match
#> 3  6     8     8    match

reprex package (v2.0.0) 于 2021 年 6 月 7 日创建

答案 1 :(得分:1)

我会这样做:

df1 <- structure(list(id = c(1, 2, 3, 4, 5, 6),
                      day = c(2, 2, 8, 2, 8, 8)),
                 row.names = c(NA, -6L),
                 class = c("tbl_df", "tbl", "data.frame"))

df2 <- structure(list(id = c(4, 5, 6, 7, 8),
                      day = c(2, 2, 8, 2, 8)),
                 row.names = c(NA, -5L),
                 class = c("tbl_df", "tbl", "data.frame"))

left_join(df1, df2, by = "id", suffix = c("", "_m")) %>%
  transmute(id, day, match = ifelse(is.na(day_m), "NO MATCH", "MATCH"))

返回:

# A tibble: 6 x 3
     id   day match
  <dbl> <dbl> <chr>
1     1     2 NO MATCH
2     2     2 NO MATCH
3     3     8 NO MATCH
4     4     2 MATCH
5     5     8 MATCH
6     6     8 MATCH