У меня есть две кадры данных, df1 и df2, и хотите знать, может ли что-то вроде следующее (легко) возможно:

Для каждого df1$id, которые соответствует df2$id, я хочу сравнить df1$day против df2$day, и либо классифицирует их как MATCH, либо NO MATCH в новом столбце (df1$matched) В зависимости от того, идентичны ли они или нет.

Дополнительные пояснения:

Если значение в df1$id соответствует / появляется в df2$id, я хочу посмотреть df1$day и df2$day, и df2$day против этого конкретного id. Далее я хочу сравнить значения из df1$day и df2$day, чтобы увидеть, есть ли они одинаковыми или разными. Затем я хочу создать новый столбец (matched), который классифицирует эти значения на основе того, одинаковы они одинаковы. Таким образом, для каждого совпадения id между df1 и {{x10}} и {{x10}}, алгоритм должен выводить что-то подобное:

Пример данных:

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")
  )

Где я ошибаюсь?

0
Mus 7 Июн 2021 в 16:58

2 ответа

Лучший ответ
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

Создано на 2021-06-07 на 2021-06-07 Пакет APPREX (v2.0.0)

3
AnilGoyal 7 Июн 2021 в 14:20

Вот как бы я это сделал:

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
1
ktiu 7 Июн 2021 в 14:27