R - объединить два фрейма данных?

Учитывая два фрейма данных a и b:

> a
           a           b           c
1 -0.2246894 -1.48167912 -1.65099363
2  0.5559320 -0.87898575 -0.15634590
3  1.8469466 -0.01487524 -0.53098215
4 -0.6875051  0.23880967  0.01824621
5 -0.6735163  0.75485292  0.44154092


> b
           a          c
1  0.4287284 -0.3295925
2  0.5201492  0.3341251
3 -2.6355570  1.7916780
4 -1.3645337  1.3642276
5 -0.4954542 -0.6660001

Есть ли простой способ объединить их, чтобы вернуть новый фрейм данных в форме ниже?

> new
           a                   b           c
1  -0.2246894   -1.48167912106676 -1.65099363
2   0.5559320  -0.878985746842256 -0.15634590
3   1.8469466 -0.0148752354840942 -0.53098215
4  -0.6875051   0.238809666690982  0.01824621
5  -0.6735163   0.754852923524198  0.44154092
6   0.4287284                  NA -0.32959248
7   0.5201492                  NA  0.33412510
8  -2.6355570                  NA  1.79167801
9  -1.3645337                  NA  1.36422764
10 -0.4954542                  NA -0.66600006

Я хочу объединить фреймы данных, сопоставить заголовки и вставить NA для позиций в фрейме данных b, где отсутствует заголовок.


person Darren J. Fitzpatrick    schedule 17.11.2011    source источник
comment
Полагаю, вы уже пробовали merge()? Почему это не работает?   -  person Andrie    schedule 17.11.2011
comment
Я не Андри - так что +1 ты за то, что заставил меня пойти дох!   -  person Darren J. Fitzpatrick    schedule 17.11.2011
comment
Я запутался. Операция Даррена не является соединением - декартово произведение не существует. Скорее, это прямая конкатенация. Так как же объединение помогает?   -  person dfrankow    schedule 03.12.2011


Ответы (5)


Вы хотите «рибинд».

b$b <- NA
new <- rbind(a, b)

rbind требует, чтобы фреймы данных имели одинаковые столбцы.

Первая строка добавляет столбец b к фрейму данных b.

Полученные результаты

> a <- data.frame(a=c(0,1,2), b=c(3,4,5), c=c(6,7,8))
> a
  a b c
1 0 3 6
2 1 4 7
3 2 5 8
> b <- data.frame(a=c(9,10,11), c=c(12,13,14))
> b
   a  c
1  9 12
2 10 13
3 11 14
> b$b <- NA
> b
   a  c  b
1  9 12 NA
2 10 13 NA
3 11 14 NA
> new <- rbind(a,b)
> new
   a  b  c
1  0  3  6
2  1  4  7
3  2  5  8
4  9 NA 12
5 10 NA 13
6 11 NA 14
person dfrankow    schedule 03.12.2011
comment
Если вы получаете объединение более двух фреймов данных, вы можете использовать Reduce(rbind, list_of_data_frames), чтобы смешать их все вместе! - person Yourpalal; 14.08.2015
comment
если вы rbind прилетаете с базы по какой-то странной причине: я использовал rbind.data.frame - person Boern; 02.05.2018

Попробуйте пакет plyr:

rbind.fill(a,b,c)
person Rnoob    schedule 15.08.2013
comment
Избегайте использования внешних пакетов для простых задач. - person Fernando; 21.01.2016
comment
Понятнее и проще, чем взламывать лишние столбцы только для того, чтобы убрать привязку; это правильный путь вперед. Избегать чрезвычайно распространенных пакетов, таких как plyr, когда они предлагают правильные инструменты для работы, просто неразумно. - person Jack Aidley; 05.06.2017
comment
Эта функция автоматически выполняет слияние факторов. Это значительно лучше принятого ответа. plyr - ужасно распространенный пакет. - person SmallChess; 28.11.2017

вы можете использовать функцию

bind_rows(a,b)

из библиотеки dplyr

person Adam Lee Perelman    schedule 15.02.2017
comment
В отличие от cbind (rbind), эта функция не изменяет тип всех столбцов (строк) на factor, если присутствует вектор символов. - person Azim; 12.04.2018

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

По какой-то причине это возвращает НАМНОГО быстрее для больших наборов данных, чем при использовании функции merge.

fastmerge <- function(d1, d2) {
  d1.names <- names(d1)
  d2.names <- names(d2)

  # columns in d1 but not in d2
  d2.add <- setdiff(d1.names, d2.names)

  # columns in d2 but not in d1
  d1.add <- setdiff(d2.names, d1.names)

  # add blank columns to d2
  if(length(d2.add) > 0) {
    for(i in 1:length(d2.add)) {
      d2[d2.add[i]] <- NA
    }
  }

  # add blank columns to d1
  if(length(d1.add) > 0) {
    for(i in 1:length(d1.add)) {
      d1[d1.add[i]] <- NA
    }
  }

  return(rbind(d1, d2))
}
person Mike Monteiro    schedule 23.08.2015
comment
Эта маленькая функция - динамит. - person Dirk; 10.07.2017
comment
Отлично. Я просто хотел опубликовать тот же ответ :-). Одно улучшение: @Anton в своем ответе поставил NA на double. Было бы неплохо, если бы тип нового столбца был того же типа, что и тип существующего столбца в другом фрейме данных. Может через mode(d2[d2.add[i]]) <- mode(d1[d2.add[i]]). Но я не уверен, что это правильный способ. - person daniel.heydebreck; 09.08.2017

Вы можете использовать rbind, но в этом случае вам нужно иметь одинаковое количество столбцов в обеих таблицах, поэтому попробуйте следующее:

b$b<-as.double(NA) #keeping numeric format is essential for further calculations
new<-rbind(a,b)
person Anton    schedule 02.12.2013