Кажется, теперь я понимаю, чего вы пытаетесь достичь.
Код
# Step 1
library(magrittr)
suppressMessages(library(dplyr))
library(fuzzyjoin)
# Step 2
df1 <- structure(list(ID = c(437097, 489309, 437103, 437109, 449363, 437127, 437124, 481203, 479825, 437136), pISSN = c(NA, "2366-004X", "0025-5858", "1042-9670", "1093-1139", NA, "0361-3682", "0103-846X", "2153-2184", "0734-2071"), eISSN = c("1530-9932", "2366-0058", NA, "1545-7230", NA, "0949-1775", "1873-6289", "0103-846X", "2153-2192", "1557-7333"), Level = c(1, 1, 1, 1, 0, 1, 2, 1, 0, 2)), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"))
df2 <- structure(list(ID = c(41120, 12249, 261, 12188, 40596, 12129, 769), pISSN = c(NA, NA, NA, "0025-5858", "1042-9670", "0895-4852", "0949-1775"), eISSN = c("2364-9534", "1530-9932", "2366-0058", "1865-8784", "1545-7230", "1936-4709", "1432-0517"), Format = c("E OA S C", "E OF S", "E OF S", "PE OF S", "PE OF S", "PE OF", "PE OF S")), row.names = c(NA, -7L), class = c("tbl_df", "tbl", "data.frame"))
# Step 3
my_match <- function(key1, key2) {
match <- key1 == key2
match[is.na(match)] <- FALSE
return(match)
}
# Step 4
bind_rows(
fuzzy_inner_join(df1, df2,
by = c("pISSN" = "pISSN"),
match_fun = list(my_match)),
fuzzy_inner_join(df1, df2,
by = c("eISSN" = "pISSN"),
match_fun = list(my_match)),
fuzzy_inner_join(df1, df2,
by = c("pISSN" = "eISSN"),
match_fun = list(my_match)),
fuzzy_inner_join(df1, df2,
by = c("eISSN" = "eISSN"),
match_fun = list(my_match))
) %>% # Step 5
mutate(pISSN = coalesce(pISSN.x, pISSN.y),
eISSN = coalesce(eISSN.x, eISSN.y)) %>%
select(-c("pISSN.x", "pISSN.y", "eISSN.x", "eISSN.y")) %>%
select("ID.x", "ID.y", "pISSN", "eISSN", "Level", "Format") -> result
result
#> # A tibble: 6 x 6
#> ID.x ID.y pISSN eISSN Level Format
#> <dbl> <dbl> <chr> <chr> <dbl> <chr>
#> 1 437103 12188 0025-5858 1865-8784 1 PE OF S
#> 2 437109 40596 1042-9670 1545-7230 1 PE OF S
#> 3 437127 769 0949-1775 0949-1775 1 PE OF S
#> 4 437097 12249 <NA> 1530-9932 1 E OF S
#> 5 489309 261 2366-004X 2366-0058 1 E OF S
#> 6 437109 40596 1042-9670 1545-7230 1 PE OF S
Объяснение каждого шага
- Я загружаю некоторые необходимые пакеты,а именно:
magrittr
, для трубного оператора %>%
;dplyr
, для bind_rows
(аналог rbind
), mutate
и select
;и fuzzyjoin
для fuzzy_inner_join
. - Затем я создаю два примера фреймов данных:
df1
и df2
. - Мы определяем функцию
my_match
.Эта функция выполняет сопоставление на основе равенства, но когда задействовано NA
s, она возвращает FALSE
(без совпадения) вместо NA
. - Затем мы используем
fuzzy_inner_join
, чтобы выполнить четыре соединения следующим образомклавиши: (i) df1
"pISSN"
и df2
"pISSN"
;(ii) df1
"eISSN"
и df2
"pISSN"
;(iii) df1
"pISSN"
и df2
"eISSN"
;и (iv) df1
"eISSN"
и df2
"eISSN"
.Это та часть, где мы делаем то, что вы назвали перекрестной проверкой столбцов 2x2 .Затем мы обертываем эти четыре результирующих фрейма данных в bind_rows
, чтобы все эти наблюдения (строки) были объединены в один фрейм данных. - Наконец, мы проводим некоторую обработку данных, чтобы получить фрейм данных в нужной форме: (i) мы используем
mutate
для создания двух новых столбцов pISSN
и eISSN
из столбцов pISSN.x
(первоначально df1
) и pISSN.y
(первоначально df2
) и eISSN.x
(изdf1
) и eISSN.y
(из df2
) соответственно;(ii) и мы используем select
для хранения / удаления столбцов.
Примечание: в отличие от вашего предполагаемого result
, я вывожу два ID
столбца, один из df1
идругой от df2
.В своем посте вы держали только ID
из фрейма данных df1
.Но однозначно, какой из них оставить, поэтому я оставил два.Вы всегда можете отказаться от одного из них с помощью select(-ID.x)
или select(-ID.y)
.