Fusionar marcos de datos en R: coincidencia total y parcial

⚡ Resumen inteligente

La fusión de data frames en R une dos tablas mediante una o más columnas clave compartidas. La función merge() abarca uniones internas, izquierdas, derechas y completas, y este tutorial muestra tanto una unión completa como una parcial.

  • 🔑 Columnas clave: merge() une por by, o por by.x y by.y cuando la clave tiene un nombre diferente en cada fotograma.
  • 🔗 Partido completo: La unión interna predeterminada conserva solo las filas cuya clave aparece en ambos marcos de datos.
  • 🧩 Coincidencia parcial: Al establecer all.x = TRUE, se conservan todas las filas del primer fotograma y se rellenan los huecos con NA.
  • 📐 Comprobación de dimensiones: Compare dim() antes y después de una fusión para detectar filas perdidas o duplicadas por la unión.
  • ⚙️ Unirse al control: Las banderas all, all.x y all.y seleccionan el comportamiento interior, izquierdo, derecho o exterior completo.
  • 🛠️ Alternativa moderna: dplyr nombra cada unión en el propio verbo y conserva el orden original de las filas.

Fusionar marcos de datos en R

Muy a menudo disponemos de datos de múltiples fuentes. Para realizar un análisis es necesario unir dos marcos de datos junto con uno o más variables clave comunes.

Tipos de fusión (join) en R

Antes de analizar los ejemplos, conviene saber que la función merge() realiza todos los tipos de unión que un usuario de SQL espera. Su comportamiento se controla mediante los argumentos all, all.x y all.y, en lugar de mediante un nombre de función diferente.

Tipo de unión Filas mantenidas llamada merge() equivalente de dplyr
Unión interna (predeterminada) Solo las claves presentes en ambos marcos fusionar(x, y, por = “k”) unión_interna(x, y, por = “k”)
Izquierda combinación externa Todas las filas de x, NA donde y no tiene coincidencia fusionar(x, y, por = “k”, todos.x = VERDADERO) left_join(x, y, by = “k”)
Unión exterior derecha Todas las filas de y, NA donde x no tiene coincidencia fusionar(x, y, por = “k”, todo.y = VERDADERO) right_join(x, y, by = “k”)
Unión externa completa Cada fila de ambos marcos fusionar(x, y, por = “k”, todo = VERDADERO) full_join(x, y, por = “k”)
Unión cruzada Cada combinación de filas fusionar(x, y, por = NULL) unión_cruzada(x, y)

Hay dos detalles que conviene recordar antes de la primera llamada:

  • Si se omite la opción "by", R realiza una fusión en función de cada nombre de columna que comparten los dos marcos, lo cual rara vez es lo que se desea.
  • merge() ordena el resultado por la columna clave; pase sort = FALSE para mantener el orden de entrada.

Partido completo

Una coincidencia exacta devuelve solo los valores que tienen un equivalente en la tabla de destino. Las filas sin coincidencia se eliminan del nuevo marco de datos. En cambio, una coincidencia parcial conserva esas filas y rellena las columnas faltantes con NA.

Veremos una sencilla unión interna. La palabra clave de unión interna selecciona registros que tienen valores coincidentes en ambas tablas. Para unir dos conjuntos de datos, podemos usar la función merge(). Usaremos tres argumentos:

merge(x, y, by.x = x, by.y = y)

Arguments:
-x: The origin data frame
-y: The data frame to merge
-by.x: The column used for merging in x data frame. Column x to merge on
-by.y: The column used for merging in y data frame. Column y to merge on

Ejemplo:

Crear el primer conjunto de datos con variables

  • apellido
  • nacionalidad

Crear un segundo conjunto de datos con variables

  • apellido
  • películas

La variable clave común es el apellido. Podemos fusionar ambos. marcos de datos y compruebe que la dimensionalidad sea 7×3.

Agregamos stringsAsFactors=FALSE en el marco de datos porque no queremos R para convertir las cadenas en una factorLa variable debe seguir siendo un vector de caracteres. Desde R 4.0.0, este es el comportamiento predeterminado para data.frame(), por lo que el argumento es opcional en el código nuevo e inofensivo en el código antiguo.

# Create origin dataframe(

producers <- data.frame(   
    surname =  c("Spielberg","Scorsese","Hitchcock","Tarantino","Polanski"),    
    nationality = c("US","US","UK","US","Poland"),    
    stringsAsFactors=FALSE)

# Create destination dataframe
movies <- data.frame(    
    surname = c("Spielberg",
		"Scorsese",
                "Hitchcock",
              	"Hitchcock",
                "Spielberg",
                "Tarantino",
                "Polanski"),    
    title = c("Super 8",
    		"Taxi Driver",
    		"Psycho",
    		"North by Northwest",
    		"Catch Me If You Can",
    		"Reservoir Dogs","Chinatown"),                
     		stringsAsFactors=FALSE)

# Merge two datasets
m1 <- merge(producers, movies, by.x = "surname")
m1
dim(m1)

Salida:

surname		nationality		title
1 Hitchcock		UK		Psycho
2 Hitchcock		UK		North by Northwest
3 Polanski		Poland		Chinatown
4 Scorsese		US		Taxi Driver
5 Spielberg		US		Super 8
6 Spielberg		US		Catch Me If You Can
7 Tarantino		US		Reservoir Dogs

Fusionemos marcos de datos cuando las variables clave comunes tengan nombres diferentes.

Cambiamos el apellido por el nombre en el marco de datos de las películas. Usamos la función idéntica (x1, x2) para verificar si ambos marcos de datos son idénticos.

# Change name of ` movies ` dataframe
colnames(movies)[colnames(movies) == 'surname'] <- 'name'
# Merge with different key value
m2 <- merge(producers, movies, by.x = "surname", by.y = "name")
# Print head of the data
head(m2)

Salida:

##surname     nationality		title
## 1 Hitchcock          UK		Psycho
## 2 Hitchcock          UK		North by Northwest
## 3 Polanski          Poland		Chinatown
## 4 Scorsese           US		Taxi Driver
## 5 Spielberg          US		Super 8
## 6 Spielberg          US		Catch Me If You Can
# Check if data are identical
identical(m1, m2)

Salida:

## [1] TRUE

Esto demuestra que la operación de combinación se realiza incluso si los nombres de las columnas son diferentes.

Coincidencia parcial

La unión interna anterior descartó silenciosamente todo lo que no tuviera una contraparte. No es sorprendente que dos dataframes no tengan las mismas variables clave comunes. En el coincidencia completa, el marco de datos regresa único filas encontradas en el marco de datos x e y. Con fusión parcial, es posible mantener las filas que no coincidan en el otro marco de datos. Estas filas tendrán NA en aquellas columnas que normalmente se llenan con valores de y. Podemos hacerlo configurando all.x= TRUE.

Por ejemplo, podemos agregar un nuevo productor, Lucas, al marco de datos de productores sin las referencias a películas en el marco de datos de películas. Si establecemos all.x = FALSE, R unirá solo los valores coincidentes en ambos conjuntos de datos. En nuestro caso, el productor Lucas no se agregará al resultado, ya que no está presente en uno de los conjuntos de datos.

Veamos la dimensión de cada salida cuando especificamos all.x= TRUE y cuando no lo hacemos.

# Create a new producer
add_producer <-  c('Lucas', 'US')
#  Append it to the ` producer` dataframe
producers <- rbind(producers, add_producer)
# Use a partial merge 
m3 <-merge(producers, movies, by.x = "surname", by.y = "name", all.x = TRUE)
m3

Salida:

La salida de la consola que se muestra a continuación muestra la fila adicional de Lucas, donde NA representa el título de la película que falta.

Salida de la consola de la fusión parcial que muestra a Lucas con NA en la columna del título.

# Compare the dimension of each data frame
dim(m1)

Salida:

## [1] 7 3
dim(m2)

Salida:

## [1] 7 3
dim(m3)

Salida:

## [1] 8 3

Como podemos ver, el nuevo marco de datos es de 8×3, en comparación con 7×3 para m1 y m2. R rellena la columna de título con NA para Lucas, el productor que no tiene una fila coincidente en el marco de datos de películas.

merge() frente a dplyr: Uniones en R

R base resuelve cada unión con una función y un conjunto de indicadores. dplyr En cambio, el paquete asigna a cada unión su propio verbo, lo que muchos equipos encuentran más fácil de leer en un flujo de trabajo.

Criterios Fusión base() dplyr se une
Elegir la unión todas.x / todas.y / todas las banderas Nombrados en el verbo: left_join(), full_join()
Orden de filas Ordenado por clave a menos que sort = FALSE Se conserva el orden de la mesa izquierda.
Velocidad en cuadros grandes Más lento Generalmente más rápido
Columna clave faltante Falla tarde o se fusiona en las columnas incorrectas. Errores inmediatamente
Dependencias Base R, no hay nada que instalar Requiere el paquete dplyr.

Las dos fusiones mostradas arriba se traducen directamente en verbos dplyr:

library(dplyr)
# Same inner join as merge(producers, movies, by.x = "surname", by.y = "name")
m4 <- inner_join(producers, movies, by = c("surname" = "name"))
# Same partial merge as all.x = TRUE
m5 <- left_join(producers, movies, by = c("surname" = "name"))

La función merge() básica es la opción más segura dentro de un paquete que no debería tener dependencias. dplyr es la mejor opción en un análisis interactivo, donde la legibilidad y la velocidad son más importantes.

Errores comunes de fusión en R y cómo solucionarlos

La mayoría de los problemas de fusión se manifiestan como un recuento de filas inesperado en lugar de un mensaje de error, por lo que comprobar dim() después de cada unión es un hábito que vale la pena adquirir.

  • El resultado tiene más filas que cualquiera de las entradas. Una clave que se repite en ambos marcos produce una unión de muchos a muchos, y R devuelve todas las combinaciones. Inspeccione las claves con table(duplicated(x$k)) antes de fusionarlas.
  • El resultado está vacío. Las columnas clave suelen ser de tipo diferente o una de ellas contiene espacios en blanco al final. Ejecute str() en ambos marcos y limpie la clave con trimws() antes de la fusión.
  • Las columnas se devuelven como title.x y title.y. Ambos marcos contienen una columna no clave con el mismo nombre. Pase suffixes = c(“_producer”, “_film”) para que el origen sea obvio.
  • Las filas ya no están en su orden original. merge() ordena por clave de forma predeterminada. Agregue sort = FALSE o utilice un tipo explícito después.
  • Una comparación clave falla por varios factores. Compara caracteres, no niveles de factores: envuelve la clave en as.character() antes de fusionar marcos creados con configuraciones predeterminadas de R anteriores.

Cuando la misma fusión tiene que ejecutarse repetidamente, envuélvala en un función definida por el usuario de esta forma, los argumentos no pueden variar entre ejecuciones.

Preguntas Frecuentes

R realiza la fusión basándose en cada nombre de columna que comparten los dos marcos. Si hay una columna compartida, esto resulta conveniente; si hay varias, reduce el resultado silenciosamente, y si no hay ninguna, devuelve una combinación cruzada. Nombrar la clave explícitamente evita estas tres sorpresas.

No en una sola llamada a merge(). Encadena las llamadas o pliega una lista con Reduce(function(x, y) merge(x, y, by = “k”), list(df1, df2, df3)). Verifica el número de filas después de cada paso, ya que las claves duplicadas se acumulan rápidamente.

Ambos marcos contenían una columna no clave con el mismo nombre, por lo que R los desambigua. Pase suffixes = c(“_producer”, “_film”) para dar nombres significativos a las copias, o elimine la columna redundante antes de fusionarlas.

No. merge() ordena el resultado por la columna clave por defecto. Pase sort = FALSE para mantener el orden de entrada, o utilice un dplyr unir, lo que conserva el orden del marco izquierdo.

Proporcione un vector: merge(x, y, by = c(“apellido”, “año”)). Cuando los apellidos sean diferentes, pase los vectores correspondientes a by.x y by.y. Ambos vectores deben listar las columnas en el mismo orden.

Utilice `by = “row.names”` o la forma abreviada `by = 0`. R vuelve a agregar los nombres de las filas como una columna llamada `Row.names`, que normalmente querrá renombrar o eliminar antes de continuar el análisis.

Describe los dos marcos y el número de filas, y un asistente de IA señalará las claves duplicadas como la causa probable y sugerirá una comprobación con `duplicated()`. Confirma el diagnóstico con tus propios datos antes de modificar la unión.

Sí. RStudio La versión de escritorio 2023.09.0 y posteriores incluye una opción de suscripción. Copiloto de GitHub Integración que crea una fusión a partir de un comentario. Verifica el tipo de unión que selecciona, ya que un indicador incorrecto cambia silenciosamente el número de filas.

Resumir este post con: