Связывание строк двух фреймов данных (объединение по именам столбцов) с дублированными именами столбцов - PullRequest
0 голосов
/ 07 февраля 2019

Я хотел бы связать строки двух df по именам столбцов, если столбец не существует во 2-й df, сначала должны быть NA.К сожалению, dplyr::bind_rows имеет проблему с дублированными именами столбцов.Не могли бы вы помочь мне решить эту проблему?

Что я сделал до сих пор?

Сначала некоторые воспроизводимые данные:

df1 <- data.frame(replicate(6,sample(0:1,10,rep=TRUE)))
df2 <- data.frame(replicate(3,sample(0:1,10,rep=TRUE)))
colnames(df1) <- c('A','A','A','B','C','E')
colnames(df2) <- c('A','B','C')

df1
   A A A B C E
1  0 1 0 1 1 1
2  1 1 1 0 0 0
3  0 0 1 1 0 1
4  0 0 1 0 1 1
5  0 1 0 1 1 0
6  1 0 1 1 1 1
7  0 0 1 1 1 0
8  0 1 0 1 1 0
9  0 1 0 0 1 0
10 1 1 0 1 1 0

df2
   A B C
1  1 1 0
2  0 1 1
3  1 1 0
4  1 0 0
5  0 0 1
6  0 0 1
7  0 1 1
8  0 0 0
9  0 0 1
10 0 1 1

Что я хотел бы получить?

   A A A B C E
1  0 1 0 1 1 1
2  1 1 1 0 0 0
3  0 0 1 1 0 1
4  0 0 1 0 1 1
5  0 1 0 1 1 0
6  1 0 1 1 1 1
7  0 0 1 1 1 0
8  0 1 0 1 1 0
9  0 1 0 0 1 0
10 1 1 0 1 1 0
11 1 1 1 1 0 NA
12 0 0 0 1 1 NA
13 1 1 1 1 0 NA
14 1 1 1 0 0 NA
15 0 0 0 0 1 NA
16 0 0 0 0 1 NA
17 0 0 0 1 1 NA
18 0 0 0 0 0 NA
19 0 0 0 0 1 NA
20 0 0 0 1 1 NA

Я решил использовать bind_rows из dplyr, но:

result <- bind_rows(mutate_all(df1, as.character), mutate_all(df2, as.character))
Error: Columns `A`, `A` must have unique names
Call `rlang::last_error()` to see a backtrace

Заранее спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Другим вариантом может быть преобразование информационного кадра в список объектов, а затем cbind их с использованием cbind.fill из rowr пакета с fill = NA

library(rowr)

new_df <- do.call(cbind.fill, c(mapply(c, as.list(df1),
         as.list(df2)[match(names(df1), names(df2))]), fill = NA))

, но при этом теряются имена столбцов, которые вы можете датьэто от df1.

names(new_df) <-  names(df1)
new_df

#   A A A B C  E
#1  0 1 0 0 1  0
#2  0 1 0 0 0  0
#3  0 0 1 1 1  1
#4  0 0 1 0 1  0
#5  1 0 0 0 0  0
#6  0 0 1 0 1  1
#7  0 1 0 0 1  0
#8  0 1 0 0 0  0
#9  0 1 1 0 1  1
#10 1 1 1 0 1  1
#11 0 0 0 1 0 NA
#12 1 1 1 0 0 NA
#13 1 1 1 1 0 NA
#14 0 0 0 1 0 NA
#15 0 0 0 1 1 NA
#16 1 1 1 1 0 NA
#17 0 0 0 1 1 NA
#18 1 1 1 0 0 NA
#19 1 1 1 0 1 NA
#20 1 1 1 0 1 NA
0 голосов
/ 07 февраля 2019

Опция, использующая rbindlist из data.table

library(data.table)
cols <- names(df1)[names(df1) %in% names(df2)]
out <- setDF(rbindlist(list(df1, setNames(df2[cols], cols)), fill = TRUE))
out
#   A A A B C  E
#1  0 1 0 1 1  0
#2  1 1 1 0 1  0
#3  0 1 1 0 1  0
#4  0 0 1 0 1  0
#5  1 0 0 1 0  1
#6  1 1 1 1 0  1
#7  0 0 0 1 0  0
#8  0 0 0 1 0  0
#9  1 1 0 1 0  0
#10 0 1 0 1 1  0
#11 0 0 0 1 1 NA
#12 1 1 1 1 0 NA
#13 0 0 0 0 1 NA
#14 0 0 0 0 1 NA
#15 0 0 0 0 1 NA
#16 1 1 1 1 1 NA
#17 0 0 0 0 0 NA
#18 1 1 1 1 1 NA
#19 0 0 0 1 0 NA
#20 0 0 0 1 1 NA

Часть df2[cols] приведет к следующему кадру данных с уникальными именами

#   A A.1 A.2 B C
#1  0   0   0 1 1
#2  1   1   1 1 0
#3  0   0   0 0 1
# ...

Вот почему мы вызываем setNames(df2[cols], cols) чтобы сразу переименовать столбцы.setDF гарантирует, что результатом будет data.frame, а не data.table.


Используя bind_rows, вы получите только четыре столбца

head(bind_rows(df1, setNames(df2[cols], cols)), 3)
#  A B C E
#1 1 1 0 0
#2 0 0 0 0
#3 0 0 1 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...