#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. Спасибо, чувак, это сработало отлично, как ты сказал, я получил точное количество строк