<- data.frame(ClienteId = c(1:5), Producto = c("Televisión", "Smartphone", "Frigorífico", "Lavadora", "Microondas"))
pedidos
<- data.frame(ClienteId = c(1:8), Nombre = c("Juan", "Jose", "Antonio", "Luis", "Ismael", "David", "Jesús", "Ana"), Ciudad = c("Murcia", "Murcia", "Madrid", "Madrid", "Madrid", "Albacete", "Toledo", "Barcelona")) clientes
Programación en R para Data Science
Uniendo dataframes en R
Introducción
Aunque en R existe la función merge(), vamos a seguir trabajando con la familia de verbos de dplyr Vamos a utilizar 2 data frame sencillos para entender su funcionamiento.
pedidos
ClienteId Producto
1 1 Televisión
2 2 Smartphone
3 3 Frigorífico
4 4 Lavadora
5 5 Microondas
clientes
ClienteId Nombre Ciudad
1 1 Juan Murcia
2 2 Jose Murcia
3 3 Antonio Madrid
4 4 Luis Madrid
5 5 Ismael Madrid
6 6 David Albacete
7 7 Jesús Toledo
8 8 Ana Barcelona
Uniendo tablas por columnas
INNER JOIN
Si la columna de unión tiene el mismo nombre en ambos data frames:
library(dplyr)
Attaching package: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
<- pedidos %>%
pedidos_clientes inner_join(clientes, by = "ClienteId")
pedidos_clientes
ClienteId Producto Nombre Ciudad
1 1 Televisión Juan Murcia
2 2 Smartphone Jose Murcia
3 3 Frigorífico Antonio Madrid
4 4 Lavadora Luis Madrid
5 5 Microondas Ismael Madrid
Ahora la columna Id, no se llama ClienteId
<- data.frame(Id = c(1:8), Nombre = c("Juan", "Jose", "Antonio", "Luis", "Ismael", "David", "Jesús", "Ana"), Ciudad = c("Murcia", "Murcia", "Madrid", "Madrid", "Madrid", "Albacete", "Toledo", "Barcelona"))
clientes clientes
Id Nombre Ciudad
1 1 Juan Murcia
2 2 Jose Murcia
3 3 Antonio Madrid
4 4 Luis Madrid
5 5 Ismael Madrid
6 6 David Albacete
7 7 Jesús Toledo
8 8 Ana Barcelona
Si el nombre de las columnas de unión es distinto:
<- pedidos %>%
pedidos_clientes inner_join(clientes, by = c("ClienteId" = "Id"))
pedidos_clientes
ClienteId Producto Nombre Ciudad
1 1 Televisión Juan Murcia
2 2 Smartphone Jose Murcia
3 3 Frigorífico Antonio Madrid
4 4 Lavadora Luis Madrid
5 5 Microondas Ismael Madrid
LEFT JOIN
<- data.frame(ClienteId = c(1:8), Nombre = c("Juan", "Jose", "Antonio", "Luis", "Ismael", "David", "Jesús", "Ana"), Ciudad = c("Murcia", "Murcia", "Madrid", "Madrid", "Madrid", "Albacete", "Toledo", "Barcelona"))
clientes clientes
ClienteId Nombre Ciudad
1 1 Juan Murcia
2 2 Jose Murcia
3 3 Antonio Madrid
4 4 Luis Madrid
5 5 Ismael Madrid
6 6 David Albacete
7 7 Jesús Toledo
8 8 Ana Barcelona
<- clientes %>%
clientes_pedidos left_join(pedidos, by = c("ClienteId"))
clientes_pedidos
ClienteId Nombre Ciudad Producto
1 1 Juan Murcia Televisión
2 2 Jose Murcia Smartphone
3 3 Antonio Madrid Frigorífico
4 4 Luis Madrid Lavadora
5 5 Ismael Madrid Microondas
6 6 David Albacete <NA>
7 7 Jesús Toledo <NA>
8 8 Ana Barcelona <NA>
RIGHT JOIN
<- pedidos %>%
pedidos_clientes right_join(clientes, by = c("ClienteId"))
pedidos_clientes
ClienteId Producto Nombre Ciudad
1 1 Televisión Juan Murcia
2 2 Smartphone Jose Murcia
3 3 Frigorífico Antonio Madrid
4 4 Lavadora Luis Madrid
5 5 Microondas Ismael Madrid
6 6 <NA> David Albacete
7 7 <NA> Jesús Toledo
8 8 <NA> Ana Barcelona
FULL JOIN
<- data.frame(Producto = c("Televisión", "Smartphone", "Frigorífico", "Lavadora", "Microondas", "Estufa", "Tablet", "Ordenador"), Precio = c(600,500,800,400,80,20,200,1200))
productos productos
Producto Precio
1 Televisión 600
2 Smartphone 500
3 Frigorífico 800
4 Lavadora 400
5 Microondas 80
6 Estufa 20
7 Tablet 200
8 Ordenador 1200
%>%
pedidos full_join(productos, by = c("Producto"))
ClienteId Producto Precio
1 1 Televisión 600
2 2 Smartphone 500
3 3 Frigorífico 800
4 4 Lavadora 400
5 5 Microondas 80
6 NA Estufa 20
7 NA Tablet 200
8 NA Ordenador 1200
%>%
pedidos full_join(productos, by = c("Producto")) %>%
full_join(clientes, by = c("ClienteId"))
ClienteId Producto Precio Nombre Ciudad
1 1 Televisión 600 Juan Murcia
2 2 Smartphone 500 Jose Murcia
3 3 Frigorífico 800 Antonio Madrid
4 4 Lavadora 400 Luis Madrid
5 5 Microondas 80 Ismael Madrid
6 NA Estufa 20 <NA> <NA>
7 NA Tablet 200 <NA> <NA>
8 NA Ordenador 1200 <NA> <NA>
9 6 <NA> NA David Albacete
10 7 <NA> NA Jesús Toledo
11 8 <NA> NA Ana Barcelona
Uniendo tablas por filas
UNION
Combina todas las filas de ambos data frames y elimina las duplicadas. El número de columnas debe coincidir.
<- data.frame(ClienteId = c(1:5), Producto = c("Televisión", "Smartphone", "Frigorífico", "Lavadora", "Microondas"))
pedidos_ayer <- data.frame(ClienteId = c(4:8), Producto = c("Lavadora", "Microondas", "Ordenador", "Estufa", "Tablet")) pedidos_hoy
pedidos_ayer
ClienteId Producto
1 1 Televisión
2 2 Smartphone
3 3 Frigorífico
4 4 Lavadora
5 5 Microondas
pedidos_hoy
ClienteId Producto
1 4 Lavadora
2 5 Microondas
3 6 Ordenador
4 7 Estufa
5 8 Tablet
union(pedidos_ayer, pedidos_hoy)
ClienteId Producto
1 1 Televisión
2 2 Smartphone
3 3 Frigorífico
4 4 Lavadora
5 5 Microondas
6 6 Ordenador
7 7 Estufa
8 8 Tablet
UNION ALL
union_all(pedidos_ayer, pedidos_hoy)
ClienteId Producto
1 1 Televisión
2 2 Smartphone
3 3 Frigorífico
4 4 Lavadora
5 5 Microondas
6 4 Lavadora
7 5 Microondas
8 6 Ordenador
9 7 Estufa
10 8 Tablet
Filtrando filas mediante otras tablas
SEMI JOIN
Sirve para filtrar filas de una tabla que aparecen en otra. No agrega columnas adicionales. Vamos a mostrar la tabla clientes, que han realizado un pedido hoy:
clientes
ClienteId Nombre Ciudad
1 1 Juan Murcia
2 2 Jose Murcia
3 3 Antonio Madrid
4 4 Luis Madrid
5 5 Ismael Madrid
6 6 David Albacete
7 7 Jesús Toledo
8 8 Ana Barcelona
pedidos_hoy
ClienteId Producto
1 4 Lavadora
2 5 Microondas
3 6 Ordenador
4 7 Estufa
5 8 Tablet
<- semi_join(clientes, pedidos_hoy, by=c("ClienteId"))
clientes_activos_hoy clientes_activos_hoy
ClienteId Nombre Ciudad
1 4 Luis Madrid
2 5 Ismael Madrid
3 6 David Albacete
4 7 Jesús Toledo
5 8 Ana Barcelona
ANTI JOIN
Filtra filas de una tabla que NO aparecen en la otra. No agrega columnas adicionales. Vamos a mostrar la tabla clientes, que no hicieron pedido hoy:
<- anti_join(clientes, pedidos_hoy, by=c("ClienteId"))
clientes_inactivos_hoy clientes_inactivos_hoy
ClienteId Nombre Ciudad
1 1 Juan Murcia
2 2 Jose Murcia
3 3 Antonio Madrid
Librería SQLDF
Para los más familiarizados con SQL, existe el paquete sqldf que permite escribir queries SQL “al vuelo” sobre los data frames en R existentes en memoria. No es óptimo para grandes cantidades de datos.
library(sqldf)
sqldf('SELECT * FROM pedidos p INNER JOIN clientes c ON p.ClienteId = c.ClienteId')
ClienteId Producto ClienteId Nombre Ciudad
1 1 Televisión 1 Juan Murcia
2 2 Smartphone 2 Jose Murcia
3 3 Frigorífico 3 Antonio Madrid
4 4 Lavadora 4 Luis Madrid
5 5 Microondas 5 Ismael Madrid