R: ¿Concatenar dos marcos de datos?

129

Dados dos marcos de datos ay 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

¿Hay una manera simple de concatenarlos para devolver un nuevo marco de datos del siguiente formulario?

> 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

Quiero fusionar los marcos de datos, hacer coincidir los encabezados e insertar NA posiciones en el marco de datos bdonde falta el encabezado.

Darren J. Fitzpatrick
fuente
3
Supongo que ya lo has intentado merge(). ¿Por qué eso no funciona?
Andrie
2
No lo hice, Andrie, ¡así que haré +1 en ti por hacerme ir muy bien!
Darren J. Fitzpatrick
16
Estoy confundido. La operación de Darren no es una combinación: no hay un "producto cartesiano". Más bien, es una concatenación directa. Entonces, ¿cómo ayudan las uniones?
dfrankow

Respuestas:

225

Quieres "rbind".

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

rbind requiere que los marcos de datos tengan las mismas columnas.

La primera línea agrega la columna b al marco de datos b.

Resultados

> 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
dfrankow
fuente
9
Si obtiene la unión de más de 2 marcos de datos, ¡puede usarlos Reduce(rbind, list_of_data_frames)para unirlos todos!
Yourpalal
1
si rbindvienes de la base por alguna extraña razón: solíarbind.data.frame
Boern
34

Prueba el paquete plyr :

rbind.fill(a,b,c)
Rnoob
fuente
9
Evite el uso de paquetes externos para tareas simples.
Fernando
24
Más claro y fácil que piratear columnas adicionales solo para complacer; Este es el camino correcto a seguir. Evitar paquetes extremadamente comunes como plyrcuando ofrece las herramientas adecuadas para el trabajo simplemente no es sensato.
Jack Aidley
2
Esta función realiza automáticamente la fusión de factores. Es significativamente mejor que la respuesta aceptada. plyrEs un paquete común horrible.
HelloWorld
23

puedes usar la función

bind_rows(a,b)

de la biblioteca dplyr

Adam Lee Perelman
fuente
2
A diferencia de cbind ( rbind), esta función no cambia el tipo de todas las columnas (filas) factorsi hay un vector de caracteres.
Azim
11

Aquí hay una pequeña función simple que unirá dos conjuntos de datos después de detectar automáticamente qué columnas faltan en cada uno y agregarlos con todos los NAs.

Por alguna razón, esto devuelve MUCHO más rápido en conjuntos de datos más grandes que el uso de la mergefunción.

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))
}
Mike Monteiro
fuente
1
Esta pequeña función es dinamita.
Dirk
Agradable. Solo quería publicar la misma respuesta :-). Una mejora: @Anton lanzó el NAto doubleen su respuesta. Sería bueno cuando el tipo de la nueva columna fuera del mismo tipo que la columna existente en el otro marco de datos. Tal vez a través de mode(d2[d2.add[i]]) <- mode(d1[d2.add[i]]). Pero no estoy seguro de si esta es la forma adecuada.
daniel.heydebreck
3

Puede usar, rbindpero en este caso necesita tener el mismo número de columnas en ambas tablas, así que intente lo siguiente:

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