Функция R для выявления дубликатов между различными столбцами и строками

#r #duplicates

#r #дубликаты

Вопрос:

Я хотел бы определить строки в таблице, где существует дублирование между двумя наборами столбцов:

таблица

На всякий случай, если изображение не отображается, вот небольшой псевдокод таблицы:

 data.frame(ind = 1:4,
           f_name   = c("a", "b", "c", "g"),
           l_name   = c("y", "y", "d", "h"),
           s_f_name = c( NA, "a", "a",  NA),
           s_l_name = c( NA, "y", "y",  NA))
 

Например, я хочу показать, что строки 1 и 2 имеют дублирование между именем / фамилией И вторичным именем / фамилией независимо от строки (записи), в которой они находятся.

Я бы искал результат: TRUE TRUE TRUE FALSE.

Я использую эту duplicated() функцию, и я использую duplicated(...)|duplicated(..., fromLast = TRUE) ее для учета любых значений, которые имеют дублирование, независимо от начального индекса.

Ответ №1:

Попробуйте использовать логические флаги, а затем объединить с вашими исходными данными, вот код, использующий некоторые tidyverse функции:

 library(tidyverse)
#Data
df <- data.frame(ind=1:4,
                 f_name=c('A','B','C','G'),
                 l_name=c('Y','Y','D','H'),
                 s_f_name=c('','A','A',''),
                 s_l_name=c('','Y','Y',''),stringsAsFactors = F)
#Split data
newdf <- df %>% 
  left_join(
    df %>% select(c(ind,f_name,l_name)) %>%
      bind_rows(df %>% select(c(ind,s_f_name,s_l_name)) %>%
                  rename(f_name=s_f_name,l_name=s_l_name)) %>%
      filter(f_name!='') %>%
      mutate(id=paste(f_name,l_name),
             Flag1=duplicated(id,fromLast = T),
             Flag2=duplicated(id),
             Flag3=ifelse(Flag1 | Flag2,T,F)) %>%
      filter(Flag3) %>%
      select(c(ind,Flag3))
  ) %>% replace(is.na(.),F) %>%
  rename(Dup=Flag3)
 

Вывод:

   ind f_name l_name s_f_name s_l_name   Dup
1   1      A      Y                    TRUE
2   2      B      Y        A        Y  TRUE
3   3      C      D        A        Y  TRUE
4   4      G      H                   FALSE