Изменение количества при объединении двух фреймов данных в r

#r #dplyr

#r #dplyr

Вопрос:

Мне нужно обновить сведения о DOB и поле в моей подтаблице (1797655 строк) из основного df (793145 строк), используя совпадающие идентификаторы.

df1 — (Подтаблица)

  ID
    123
    123
    122
    122
    124
    124
    121
    121
  

df2 — (Главная таблица)

 ID  DOB         SEX
123 22-04-1996  M
122 16-06-1994  M
124 25-05-1990  F
121 13-12-1993  F 

Я использовал приведенный ниже код для обновления этих двух столбцов.

 df3 <- merge(df1,df2,by="ID",all.x = TRUE)
  

Он успешно обновил DOB и gender, но дополнительно добавил 266 строк во вложенную таблицу, почему? (т. Е. после кода слияния количество строк в вложенной таблице стало 1797921. (1797921 — 1797655 = 266))
Я проверил дополнительные строки с точки зрения дубликатов (удалено 50 строк), я не могу найти оставшиеся 216 строк в данных.

Пожалуйста, предложите код / альтернативный метод для решения проблемы, заранее спасибо!

Ответ №1:

Удалите дубликаты из df1 . Попробуйте :

 df3 <- merge(unique(df1), df2, by= 'ID', all.x = TRUE)
  

Когда у вас есть дубликаты в df1 , они создают строки со всеми строками одного и того же ID в df2 , что резко увеличивает количество строк в конечных данных.

В dplyr вы можете сделать это как :

 library(dplyr)
df3 <- df1 %>% distinct(ID, .keep_all = TRUE) %>% left_join(df2, by = 'ID')
  

После обсуждения с @Edo я думаю, что также могут быть случаи, когда в df1 также df2 могут быть дубликаты, и в этом случае вы можете взять distinct строки из обоих фреймов данных, прежде чем присоединять их.

 df3 <- df1 %>% 
        distinct(ID, .keep_all = TRUE) %>% 
        left_join(df2 %>% 
                  distinct(ID, .keep_all = TRUE), by = 'ID')
  

Комментарии:

1. Даже если в df1 нем есть дубликаты, он все равно должен получить одинаковое количество строк в конце (поскольку df1 это left фрейм данных). Проблема должна быть связана с дубликатами ID в df2

2. Я думаю, что дубликаты в любом фрейме данных могут привести к увеличению количества строк.

3. Нет дубликатов: df1<-data.frame(a=1:4);df2<-data.frame(a=1:4);nrow(merge(df1,df2,by='a'))==nrow(df1)#TRUE Дубликаты в df1: df1<-data.frame(a=c(1:4, 1));df2<-data.frame(a=1:4);nrow(merge(df1,df2,by='a'))==nrow(df1)#TRUE Дубликаты в df2: df1<-data.frame(a=1:4);df2<-data.frame(a=c(1:4,1)):nrow(merge(df1,df2,by='a'))==nrow(df1)#FALSE

4. Дубликаты в df1 и df2 : df1<-data.frame(a=c(1:4, 1)); df2<-data.frame(a=c(1:4, 1));nrow(merge(df1,df2,by='a')) == nrow(df2) #FALSE . Таким образом, дубликаты могут присутствовать в обоих фреймах данных.

5.Мой предыдущий комментарий был немного неточным. Чтобы быть более конкретным, поскольку вопрос касается левого соединения: df1<-data.frame(a=1:4);df2<-data.frame(a=1:4);nrow(merge(df1,df2,by='a',all.x=TRUE))==nrow(df1)#TRUE df1<-data.frame(a=c(1:4, 1));df2<-data.frame(a=1:4);nrow(merge(df1,df2,by='a',all.x=TRUE))==nrow(df1)#TRUE df1<-data.frame(a=1:4);df2<-data.frame(a=c(1:4,1));nrow(merge(df1,df2,by='a',all.x=TRUE))==nrow(df1)#FALSE . Таким образом, если наша цель — сохранить одинаковое количество строк для df1 , проблема должна быть связана с df2

Ответ №2:

Проблема в том, что у вас есть дубликаты ID в df2 .

Посмотрите на пример ниже:

 library(dplyr)

df1 <- data.frame(ID = c(123,123,122,122,124,124,121,121))
df2 <- read.table(text = "ID  DOB         SEX
                          123 22-04-1996  M
                          122 16-06-1994  M
                          124 25-05-1990  F
                          121 13-12-1993  F",
                          header = TRUE)


left_join(df1, df2, by = "ID") %>% nrow
#> 8



df2 <- read.table(text = "ID  DOB         SEX
                          123 22-04-1996  M
                          123 22-04-1996  F
                          122 16-06-1994  M
                          124 25-05-1990  F
                          121 13-12-1993  F",
                          header = TRUE)

left_join(df1, df2, by = "ID") %>% nrow
#> 10
  

Дубликаты в df1 не имеют значения.

Сделайте это, чтобы найти дубликаты в df2 :

 df2 %>%
  arrange(ID) %>% 
  group_by(ID) %>%
  filter(n()>1) %>% 
  ungroup()
  

Вам нужно решить, какой из них правильный. Может быть, ошибка в подготовке данных ..?

Комментарии:

1. Всем привет, спасибо за вашу заботу, я попробовал предложенные вами методы и получил такое же количество дубликатов. Да, в обоих фреймах данных есть дубликаты, но мне нужно обновить только мою вспомогательную таблицу из главной таблицы, но я сталкиваюсь с увеличением количества и дубликатов. Помогите мне другим способом

2. Как я уже сказал, вам нужно выяснить, почему у вас есть дубликаты в главной таблице, и вам нужно решить, как исключить дубликаты в главной таблице (т. Е. Всегда сохранять самые последние ..?). Удалите дубликаты из главной таблицы, и тогда ваше объединение пройдет так, как ожидалось.

3. Спасибо, чувак, это сработало отлично, как ты сказал, я получил точное количество строк