Menu

Combinar y unir data frames en R (merge, left_join)

Combinar data frames mediante una clave compartida: merge() para joins inner, left, right y full, claves con nombres distintos con by.x/by.y, la familia de joins de dplyr y rbind() para apilar filas.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Dos tablas, una clave

Los datos reales rara vez viven en una sola tabla. Los clientes están en un data frame, sus pedidos en otro, y la pregunta — "¿cuánto gastó cada cliente?" — necesita ambos. Lo que los conecta es una clave: una columna presente en cada tabla que identifica la misma entidad. Combinar tablas mediante una clave es un join (la palabra de SQL) o un merge (la palabra de R base); es la misma operación.

Este es el par de tablas que usa el resto de esta página. Fíjate en que el cliente 5 hizo un pedido pero no está en la tabla de clientes, y los clientes 2 y 4 nunca pidieron nada:

Los desajustes son deliberados: lo que un join hace con las filas sin coincidencia es precisamente lo que distingue los tipos de join.

merge(): inner join por defecto

merge(x, y, by = "clave") empareja las filas con claves iguales y pega sus columnas. Por defecto conserva solo las claves presentes en ambas tablas — un inner join:

Vuelven tres filas. Ana aparece dos veces: tiene dos pedidos, y un join produce una fila de salida por cada par coincidente. Ben y Dana desaparecen (sin pedidos), y también el pedido misterioso del cliente 5 (sin cliente). Un inner join descarta silenciosamente las filas sin coincidencia de ambas tablas — exactamente lo correcto cuando solo te interesan los pares completos, y un bug silencioso de pérdida de datos cuando no.

Joins left, right y full: all.x, all.y, all

Para conservar las filas sin coincidencia, indica qué tabla tiene filas intocables. all.x = TRUE conserva todas las filas de la primera tabla — el left join, el join más usado en la práctica:

Ahora Ben y Dana sobreviven, con NA en amount — "este cliente existe; ningún pedido coincidió". Esos NA son informativos, no basura: is.na(result$amount) es exactamente la lista de clientes que nunca pidieron (el doc de valores faltantes cubre cómo trabajar con ellos). Las variantes restantes son la misma idea apuntando a otro lado: all.y = TRUE conserva todas las filas de la segunda tabla (right join — el pedido del cliente desconocido 5 sobreviviría con NA en name), y all = TRUE lo conserva todo de ambos lados (full join).

Elige preguntándote: ¿qué filas no puedo permitirme perder? Enriquecer una tabla maestra con datos de consulta — left join, la tabla maestra primero. Auditar en ambas direcciones — full join.

Claves con nombres distintos: by.x y by.y

Las tablas rara vez coinciden en los nombres — id en una, customer_id en la otra. No renombres; indica a merge() ambos nombres:

La salida conserva el nombre de la clave de la primera tabla. Relacionado: si las dos tablas comparten nombres de columnas que no son la clave (ambas tienen una date, por ejemplo), merge les añade los sufijos date.x y date.y — renómbralas cuanto antes, se leen fatal.

Los joins de dplyr

dplyr da a cada tipo de join su propio verbo, de modo que la intención está en el nombre de la función y no en argumentos de bandera (estático; el sandbox solo ejecuta R base):

library(dplyr)

left_join(customers, orders, by = "id")
inner_join(customers, orders, by = "id")
full_join(customers, orders, by = "id")
left_join(customers, orders, by = c("id" = "customer_id"))  # different names

Más allá de la legibilidad, left_join() preserva el orden de las filas de la primera tabla (merge() reordena por clave) y avisa a gritos de las coincidencias muchos-a-muchos — consulta la introducción a dplyr para conocer la familia de verbos.

El miembro infravalorado es anti_join(): devuelve las filas de la primera tabla que no tienen coincidencia en la segunda — sin columnas añadidas, solo las que quedaron fuera:

anti_join(customers, orders, by = "id")   # customers who never ordered

Esa pregunta — "¿qué filas no coincidieron?" — surge constantemente en la limpieza de datos (IDs sin pareja, registros huérfanos, búsquedas fallidas), y anti_join() la responde en una sola llamada donde R base necesita customers[!(customers$id %in% orders$id), ].

Apilar filas: rbind()

Hacer un join combina las columnas de dos tablas. Cuando en cambio tienes dos lotes del mismo tipo de filas — los pedidos de enero y los de febrero — los apilas con rbind():

El requisito es estricto: ambos data frames deben tener los mismos nombres de columna (en cualquier orden — rbind empareja por nombre). Una columna que falta o que sobra es un error, no un relleno con NA. Cuando los lotes tienen columnas desalineadas, bind_rows() de dplyr es más tolerante: alinea por nombre y rellena los huecos con NA.

La explosión de claves duplicadas

El accidente clásico del join: claves que creías únicas, pero no lo son — en ambas tablas. Cada coincidencia se empareja con cada coincidencia, multiplicando las filas:

Dos filas unidas a dos filas producen cuatro: cada x emparejada con cada y. Con datos reales, así es como una tabla de 10.000 filas se convierte en 3 millones de filas y en un total de ingresos duplicado. merge() lo hace en silencio. La defensa es un hábito: antes de unir, comprueba la clave que asumes única — anyDuplicated(customers$id) debería ser 0 — y después de unir, contrasta nrow() con lo que esperabas.

Lo que te llevas

  • merge(x, y, by = "clave") es un inner join: las filas sin coincidencia desaparecen en silencio.
  • all.x = TRUE (left), all.y = TRUE (right), all = TRUE (full) conservan las filas sin coincidencia, rellenando con NA.
  • Claves con nombres distintos: by.x / by.y en base, by = c("a" = "b") en dplyr.
  • dplyr nombra cada join; anti_join() — las filas que no coincidieron — es el infravalorado.
  • rbind() apila tablas con la misma forma; las columnas deben coincidir por nombre.
  • Las claves duplicadas multiplican filas en silencio — comprueba anyDuplicated() antes y nrow() después.

A continuación: remodelar entre formatos ancho y largo con pivot_longer() y pivot_wider().

Preguntas frecuentes

¿Cómo combino dos data frames en R?

Usa merge(x, y, by = "clave") con la columna clave compartida. Por defecto realiza un inner join: solo sobreviven las filas cuya clave aparece en ambos data frames. Añade all.x = TRUE para un left join, all.y = TRUE para un right join, o all = TRUE para un full join.

¿Cómo hago un left join en R?

R base: merge(x, y, by = "clave", all.x = TRUE) conserva todas las filas de x y rellena las columnas de y con NA donde no hay coincidencia. dplyr: left_join(x, y, by = "clave") - mismo resultado, y además preserva el orden original de las filas de x, cosa que merge() no hace.

¿Cómo combino data frames cuando las columnas clave tienen nombres distintos?

Indica a merge() ambos nombres: merge(x, y, by.x = "id", by.y = "customer_id"). En dplyr el equivalente es left_join(x, y, by = c("id" = "customer_id")), o con el helper moderno, by = join_by(id == customer_id).

¿Cuál es la diferencia entre merge y rbind en R?

Combinan en dimensiones distintas. merge() empareja las filas de dos tablas por una clave y combina sus columnas: un join. rbind() apila las filas de una tabla debajo de las de otra: ambas deben tener los mismos nombres de columna. Archivos mensuales con columnas idénticas piden rbind(); clientes-más-pedidos pide merge().

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR