Suele ser habitual que los conjuntos de datos con los que trabajamos no se encuentren en una única tabla. Por ejemplo, los datos que identifican al cliente y las operaciones que este ha realizado. Una forma puede ser unirlos en una base de datos mediante un comando SQL. Aunque también se pueden combinar dataframes en R directamente, usando para ello la función merge()
.
Conjunto de datos de ejemplo
Para poder combinar dataframes en R vamos a crear primero dos conjuntos de datos. Un primer conjunto llamado clients
en el que se guardaran los datos de cada uno de los clientes: id, nombre y edad. Además de este dataframe, también se creará un segundo con los datos de facturación que son: id de la factura, id del cliente y cantidad. Datos que se van a crear con el siguiente código.
clients <- data.frame( id = c(1, 2, 3, 4, 5), first_name = c('Oralie' ,'Imojean' ,'Michele', 'Ailbert', 'Stevy'), last_name = c('Fidgeon' ,'Benet' ,'Woodlands', 'Risdale', 'MacGorman'), age = c(30 ,21 ,29 ,22, 24)) invoices <- data.frame( invoice_id = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), client_id = c(3, 2, 7, 2, 7, 3, 1, 4 ,2, 3, 6, 2), amount = c(77.91, 24.36, 74.65, 19.75, 27.46, 17.13, 45.77, 81.7, 14.41, 52.69, 32.03, 12.78))
Estos son los mismos datos que hemos utilizado en su ocasión para explicar cómo combinar datos en Python.
Combinación básica de los datos
Ahora nos podemos plantear como combinar ambos dataframes en uno que contenga los datos de clientes y facturas. Conservando únicamente los clientes que han comprado y las facturas que tienen un cliente. Para lo que se puede hacer una unión de ambos mediante la función merge()
.
merge(x = clients, y = invoices, by.x = 'id', by.y = 'client_id')
Expresión en la que se indica que se unan los datos clients
con los datos de invoices
usando para ello la clave id
en el primer objeto y client_id
en el segundo. Si el identificador tuviese el mismo nombre en ambos objetos se podría usar únicamente la propiedad by
para indicarlo. Pudiendo omitir en este caso by.x
y by.y
. Al ejecutar esta línea de código se obtiene el siguiente resultado
id first_name last_name age invoice_id amount 1 1 Oralie Fidgeon 30 7 45.77 2 2 Imojean Benet 21 2 24.36 3 2 Imojean Benet 21 4 19.75 4 2 Imojean Benet 21 9 14.41 5 2 Imojean Benet 21 12 12.78 6 3 Michele Woodlands 29 6 17.13 7 3 Michele Woodlands 29 1 77.91 8 3 Michele Woodlands 29 10 52.69 9 4 Ailbert Risdale 22 8 81.70
En la que se puede ver que solamente han comprado cuatro clientes. No hay una factura para el cliente 5. Además de comprobar que solo 9 de las doce facturas tienen un cliente registrado.
Incluir todos los clientes (Left Join)
Puede ser que para nuestro análisis queramos incluir todos los clientes, aunque no exista una factura asociada a estos. Lo que se puede hacer mediante una operación "Left Join". Para esto existe hay que asignar el valor verdadero al parámetro all.x
de merge()
. Lo que se puede hacer con la siguiente línea
merge(x = clients, y = invoices, by.x = 'id', by.y = 'client_id', all.x = TRUE)
Con lo que se obtiene el siguiente resultado.
id first_name last_name age invoice_id amount 1 1 Oralie Fidgeon 30 7 45.77 2 2 Imojean Benet 21 2 24.36 3 2 Imojean Benet 21 4 19.75 4 2 Imojean Benet 21 9 14.41 5 2 Imojean Benet 21 12 12.78 6 3 Michele Woodlands 29 6 17.13 7 3 Michele Woodlands 29 1 77.91 8 3 Michele Woodlands 29 10 52.69 9 4 Ailbert Risdale 22 8 81.70 10 5 Stevy MacGorman 24 NA NA
Ahora se puede ver que el resultado incluye todos los clientes. Aunque para el cliente cinco los valores de la tabla invoices
son nulos.
Incluir todas las facturas (Right Join)
Si lo que necesitamos es incluir todas las facturas solamente tenemos que recurrir a una operación tipo "Right Join". Operación que de forma análoga a la anterior se puede realizar asignando el valor verdadero al parámetro all.x
. Esto es, como se muestra a continuación
merge(x = clients, y = invoices, by.x = 'id', by.y = 'client_id', all.y = TRUE)
Con lo que se obtienen los siguientes resultados
id first_name last_name age invoice_id amount 1 1 Oralie Fidgeon 30 7 45.77 2 2 Imojean Benet 21 2 24.36 3 2 Imojean Benet 21 4 19.75 4 2 Imojean Benet 21 9 14.41 5 2 Imojean Benet 21 12 12.78 6 3 Michele Woodlands 29 6 17.13 7 3 Michele Woodlands 29 1 77.91 8 3 Michele Woodlands 29 10 52.69 9 4 Ailbert Risdale 22 8 81.70 10 6 NA NA NA 11 32.03 11 7 NA NA NA 5 27.46 12 7 NA NA NA 3 74.65
Al igual que el el caso anterior los registros que no tienen valores son nulos en el cruce.
Incluir todos los registros
Finalmente, también se puede incluir todos los registros asignando el valor verdadero a la propiedad all
. Esto es, se puede incluir todos los clientes, aunque no tengan factura y todos los clientes, aunque no exista un cliente ejecutando el siguiente código
merge(x = clients, y = invoices, by.x = 'id', by.y = 'client_id', all = TRUE)
Lo que nos da el resultado esperado
id first_name last_name age invoice_id amount 1 1 Oralie Fidgeon 30 7 45.77 2 2 Imojean Benet 21 2 24.36 3 2 Imojean Benet 21 4 19.75 4 2 Imojean Benet 21 9 14.41 5 2 Imojean Benet 21 12 12.78 6 3 Michele Woodlands 29 6 17.13 7 3 Michele Woodlands 29 1 77.91 8 3 Michele Woodlands 29 10 52.69 9 4 Ailbert Risdale 22 8 81.70 10 5 Stevy MacGorman 24 NA NA 11 6 NA NA NA 11 32.03 12 7 NA NA NA 5 27.46 13 7 MA NA NA 3 74.65
Conclusiones
En esta ocasión hemos visto cómo se puede usar la función merge()
para combinar dataframes en R. Una operación que es muy habitual y, gracias a esta función, se puede hacer dentro de nuestras sesiones de R.
Image by Ulrike Leone from Pixabay