Сравните три (или более) фрейма данных

У меня есть три фрейма данных, которые я хочу сравнить с dplyr.

df1 <- data.frame(
  id = c(1, 2, 3),
  name = c("Smith", "Winter", "Summer"),
  zip = c(12345, 23456, 34567),
  value = c(1, 2, 3)
)

df2 <- data.frame(
  id = c(1, 2, 3, 5),
  name = c("Smith", "Winter", "Summer", "Taylor"),
  zip = c(12345, 23456, 34567, 56789),
  value = c(4, 5, 6, 0)
)

df3 <- data.frame(
  id = c(1, 2, 4),
  name = c("Smith", "Winter", "Miller"),
  zip = c(12345, 23456, 45678),
  value = c(7, 8, 9)
)

Фреймы данных имеют столбцы с одинаковыми значениями (например, id, name, zip) и столбец со случайным числом (value).

Чего я хотел бы добиться, так это кадра данных, который показывает, какие строки столбцов с похожими значениями (id, name, zip) присутствуют в каких кадрах данных (я знаю, что могу удалить столбец value с помощью select, я просто хотел оставьте его, чтобы показать, что набор данных также содержит переменные элементы).

Я ищу что-то вроде этого в конце концов.

идентификатор имя молния present_in_df1 present_in_df2 present_in_df3 1 Смит 12345 истинный истинный истинный 2 Зима 23456 истинный истинный истинный 3 Лето 34567 истинный истинный ЛОЖЬ 4 Миллер 45678 ЛОЖЬ ЛОЖЬ истинный 5 Тейлор 56789 ЛОЖЬ истинный ЛОЖЬ

Конечно, я также открыт для других решений, если есть лучший способ сделать это вместо этого представления в конце.

Спасибо!

Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
3
0
50
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы можете связать свои кадры данных по строке, а затем использовать, например. pivot_wider:

library(dplyr, warn=FALSE)
library(tidyr)

dplyr::lst(df1, df2, df3) |> 
  bind_rows(.id = "df") |> 
  mutate(value = TRUE) |> 
  pivot_wider(names_from = df, values_from = value, names_prefix = "present_in_", values_fill = FALSE)
#> # A tibble: 5 × 6
#>      id name     zip present_in_df1 present_in_df2 present_in_df3
#>   <dbl> <chr>  <dbl> <lgl>          <lgl>          <lgl>         
#> 1     1 Smith  12345 TRUE           TRUE           TRUE          
#> 2     2 Winter 23456 TRUE           TRUE           TRUE          
#> 3     3 Summer 34567 TRUE           TRUE           FALSE         
#> 4     5 Taylor 56789 FALSE          TRUE           FALSE         
#> 5     4 Miller 45678 FALSE          FALSE          TRUE

С reduce и joins:

library(purrr)
library(dplyr)
lst(df1, df2, df3) %>% 
  imap(\(x, y){colnames(x)[4] <- glue::glue("present_in_{y}"); x}) %>% 
  reduce(full_join, by = c("id", "name", "zip")) %>% 
  mutate(across(contains("present"), complete.cases))

  id   name   zip present_in_df1 present_in_df2 present_in_df3
1  1  Smith 12345           TRUE           TRUE           TRUE
2  2 Winter 23456           TRUE           TRUE           TRUE
3  3 Summer 34567           TRUE           TRUE          FALSE
4  5 Taylor 56789          FALSE           TRUE          FALSE
5  4 Miller 45678          FALSE          FALSE           TRUE
library(dplyr)
list(df1,df2,df3) |> purrr::reduce(full_join, by = c("id", "name", "zip"), ) |> 
  mutate(across(contains("value"), ~ifelse(is.na(.x), FALSE, TRUE))) |> 
  rename(present_in_df1 = value.x, 
         present_in_df2 = value.y, 
         present_in_df3 = value)

Соедините их, затем измените форму от длинной к широкой:

library(data.table)

l <- rbindlist(mget(ls(pattern = "^df")), idcol = "df")

dcast(l, id + name + zip ~ df)
#    id   name   zip  1  2  3
# 1:  1  Smith 12345  1  4  7
# 2:  2 Winter 23456  2  5  8
# 3:  3 Summer 34567  3  6 NA
# 4:  4 Miller 45678 NA NA  9
# 5:  5 Taylor 56789 NA  0 NA
Ответ принят как подходящий

Вы можете связать три df вместе, group_by соответствующие столбцы, а затем использовать summarise, чтобы вывести, какая df содержит необходимую информацию.

library(tidyverse)

bind_rows(df1, df2, df3, .id = "df") %>% 
  group_by(id, name, zip) %>% 
  summarize(df = paste(df, collapse = ","))

# A tibble: 5 × 4
     id name     zip df   
  <dbl> <chr>  <dbl> <chr>
1     1 Smith  12345 1,2,3
2     2 Winter 23456 1,2,3
3     3 Summer 34567 1,2  
4     4 Miller 45678 3    
5     5 Taylor 56789 2

Это может быть вашей конечной точкой, если вы найдете вышеуказанный формат полезным. Чтобы извлечь их в три разных столбца, мы можем grepl на номере df.

bind_rows(df1, df2, df3, .id = "df") %>% 
  group_by(id, name, zip) %>% 
  summarize(df = paste(df, collapse = ","), .groups = "drop") %>% 
  mutate(present_in_df1 = grepl("1", df),
         present_in_df2 = grepl("2", df),
         present_in_df3 = grepl("3", df), .keep = "unused")

# A tibble: 5 × 6
     id name     zip present_in_df1 present_in_df2 present_in_df3
  <dbl> <chr>  <dbl> <lgl>          <lgl>          <lgl>         
1     1 Smith  12345 TRUE           TRUE           TRUE          
2     2 Winter 23456 TRUE           TRUE           TRUE          
3     3 Summer 34567 TRUE           TRUE           FALSE         
4     4 Miller 45678 FALSE          FALSE          TRUE          
5     5 Taylor 56789 FALSE          TRUE           FALSE 

Другие вопросы по теме