Los datos que ocuparemos para está demostración contienen características que determinan un posible precio ($). Los datos fueron obtenidos de Link
Contrastar algunas funciones de R base vs Tidyverse para el manejo de datos en R.
El conjunto de datos tiene por nombre test.csv y contiene:
SalePrice - el precio de venta de la propiedad en dólares. Esta es la variable de destino que está tratando de predecir.
MSSubClass: La clase de construcción
MSZoning: La clasificación general de zonificación
LotFrontage: Pies lineales de calle conectados a la propiedad
LotArea: Tamaño del lote en pies cuadrados
Street: Tipo de acceso por carretera
Alley: Tipo de acceso al callejón
LotShape: Forma general de la propiedad.
LandContour: Llanura de la propiedad
Utilities:Tipo de utilidades disponibles
LotConfig: Configuración de lotes
LandSlope: Pendiente de la propiedad Vecindario: ubicaciones físicas dentro de los límites de la ciudad de Ames
Condition1: Proximidad a carretera principal o vía férrea
Condition2: Proximidad a la carretera principal o vía férrea (si hay una segunda presente)
BldgType: tipo de vivienda
HouseStyle: Estilo de vivienda
: Material general y calidad de acabado.
OverallCond: Calificación de condición general
YearBuilt: Fecha original de construcción
YearRemodAdd: Fecha de remodelación
RoofStyle: tipo de techo
RoofMatl: Material del techo
Exterior1st: Revestimiento exterior de la casa
Exterior2nd: Revestimiento exterior de la casa
MasVnrType: Tipo de chapa de mampostería
MoSold: Meses de edad
YrSold: Año vendido
SaleType: tipo de venta
SaleCondition: Condición de venta
entre otras variables.
Comenzamos por cargar los datos
df <- read.csv("train.csv", encoding = "UTF-8", header = TRUE)
head(df, 5)
## Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape LandContour
## 1 1 60 RL 65 8450 Pave <NA> Reg Lvl
## 2 2 20 RL 80 9600 Pave <NA> Reg Lvl
## 3 3 60 RL 68 11250 Pave <NA> IR1 Lvl
## 4 4 70 RL 60 9550 Pave <NA> IR1 Lvl
## 5 5 60 RL 84 14260 Pave <NA> IR1 Lvl
## Utilities LotConfig LandSlope Neighborhood Condition1 Condition2 BldgType
## 1 AllPub Inside Gtl CollgCr Norm Norm 1Fam
## 2 AllPub FR2 Gtl Veenker Feedr Norm 1Fam
## 3 AllPub Inside Gtl CollgCr Norm Norm 1Fam
## 4 AllPub Corner Gtl Crawfor Norm Norm 1Fam
## 5 AllPub FR2 Gtl NoRidge Norm Norm 1Fam
## HouseStyle OverallQual OverallCond YearBuilt YearRemodAdd RoofStyle RoofMatl
## 1 2Story 7 5 2003 2003 Gable CompShg
## 2 1Story 6 8 1976 1976 Gable CompShg
## 3 2Story 7 5 2001 2002 Gable CompShg
## 4 2Story 7 5 1915 1970 Gable CompShg
## 5 2Story 8 5 2000 2000 Gable CompShg
## Exterior1st Exterior2nd MasVnrType MasVnrArea ExterQual ExterCond Foundation
## 1 VinylSd VinylSd BrkFace 196 Gd TA PConc
## 2 MetalSd MetalSd None 0 TA TA CBlock
## 3 VinylSd VinylSd BrkFace 162 Gd TA PConc
## 4 Wd Sdng Wd Shng None 0 TA TA BrkTil
## 5 VinylSd VinylSd BrkFace 350 Gd TA PConc
## BsmtQual BsmtCond BsmtExposure BsmtFinType1 BsmtFinSF1 BsmtFinType2
## 1 Gd TA No GLQ 706 Unf
## 2 Gd TA Gd ALQ 978 Unf
## 3 Gd TA Mn GLQ 486 Unf
## 4 TA Gd No ALQ 216 Unf
## 5 Gd TA Av GLQ 655 Unf
## BsmtFinSF2 BsmtUnfSF TotalBsmtSF Heating HeatingQC CentralAir Electrical
## 1 0 150 856 GasA Ex Y SBrkr
## 2 0 284 1262 GasA Ex Y SBrkr
## 3 0 434 920 GasA Ex Y SBrkr
## 4 0 540 756 GasA Gd Y SBrkr
## 5 0 490 1145 GasA Ex Y SBrkr
## X1stFlrSF X2ndFlrSF LowQualFinSF GrLivArea BsmtFullBath BsmtHalfBath FullBath
## 1 856 854 0 1710 1 0 2
## 2 1262 0 0 1262 0 1 2
## 3 920 866 0 1786 1 0 2
## 4 961 756 0 1717 1 0 1
## 5 1145 1053 0 2198 1 0 2
## HalfBath BedroomAbvGr KitchenAbvGr KitchenQual TotRmsAbvGrd Functional
## 1 1 3 1 Gd 8 Typ
## 2 0 3 1 TA 6 Typ
## 3 1 3 1 Gd 6 Typ
## 4 0 3 1 Gd 7 Typ
## 5 1 4 1 Gd 9 Typ
## Fireplaces FireplaceQu GarageType GarageYrBlt GarageFinish GarageCars
## 1 0 <NA> Attchd 2003 RFn 2
## 2 1 TA Attchd 1976 RFn 2
## 3 1 TA Attchd 2001 RFn 2
## 4 1 Gd Detchd 1998 Unf 3
## 5 1 TA Attchd 2000 RFn 3
## GarageArea GarageQual GarageCond PavedDrive WoodDeckSF OpenPorchSF
## 1 548 TA TA Y 0 61
## 2 460 TA TA Y 298 0
## 3 608 TA TA Y 0 42
## 4 642 TA TA Y 0 35
## 5 836 TA TA Y 192 84
## EnclosedPorch X3SsnPorch ScreenPorch PoolArea PoolQC Fence MiscFeature
## 1 0 0 0 0 <NA> <NA> <NA>
## 2 0 0 0 0 <NA> <NA> <NA>
## 3 0 0 0 0 <NA> <NA> <NA>
## 4 272 0 0 0 <NA> <NA> <NA>
## 5 0 0 0 0 <NA> <NA> <NA>
## MiscVal MoSold YrSold SaleType SaleCondition SalePrice
## 1 0 2 2008 WD Normal 208500
## 2 0 5 2007 WD Normal 181500
## 3 0 9 2008 WD Normal 223500
## 4 0 2 2006 WD Abnorml 140000
## 5 0 12 2008 WD Normal 250000
Regularmente, necesitamos condiciones para filtrar dataframes. Estas condiciones pueden ser expresiones lógicas construidas mediante los operadores relacionales y lógicos.
Hay varias funciones que nos permiten filtrar dataframes y son (las cuales se explicarán en las secciones siguientes):
Función corchete.
Función subset.
Función sample.
Función filter de la base de R.
Función filter del paquete dplyr.
Una opción es ejecutando datosCompleto[i,j], donde i y j son las filas y columnas que se va a utilizar o quitar, respectivamente.
Si escribimos datosCompleto[ , j] (sin información para la fila i), indicaremos que queremos construir un dataframe que tenga en cuenta todas las filas (observaciones), pero solo la columna (variable) j.
Si escribimos datosCompleto[i, ] (sin información para la columna j), indicaremos que queremos construir un dataframe que tenga en cuenta solo la fila (observación) i, pero con todas las columnas (variables).
Las expresiones -i, -j (con el signo menos), indicarán quitar la fila i y/o la columna j.
Lo anterior también es válidos para vectores.
Supongamos que solo necesito un dataframe que contenga solo las observaciones de 1 a 4, con las columnas 2 a 5. Para ello, podemos utilizar la función corchete [] y la función dos puntos :.
# A) Un nuevo data frame:
Muestra1 <- df[1:4, 2:5]
Muestra1
## MSSubClass MSZoning LotFrontage LotArea
## 1 60 RL 65 8450
## 2 20 RL 80 9600
## 3 60 RL 68 11250
## 4 70 RL 60 9550
Muestra1[3, 2] # A) Solo la fila 3 y la columna 2
Muestra1[, 2] # B) Todas las filas (por el espacio en blanco) y solo la columna 2
Muestra1[3, ] # C) Solo la fila 3 y todas las columnas (por el espacio en blanco)
Muestra1[-5, ] # D) Quitar la fila 5 (por eso el signo menos) y dejar todas las columnas
Muestra1[,-2] # E) Todas las filas, pero sin la columna 2 (por eso, el signo menos)
Muestra1[, 2:5] # F) Todas las filas, pero solo columnas de 2 a 5 (por eso, dos puntos)
Muestra1[, c(2,5)] # G) Todas las filas, pero solo columnas 2 y (*c* representa un vector)
Muestra1[1:4, 2:5] # H) Solo las filas de 1 a 4, con las columnas 2 a 5
Muestra1[1:4, c(2,5)] # I) Solo las filas de 1 a 4, con las columnas 2 y 5
Muestra1[c(1,5), c(2,4)]# J) Solo las filas 1 y 5, con las columnas 2 y 4
Muestra1[1:5, -c(2,5)] # K) Solo las filas de 1 a 5, quitando las columnas 2 y 5
Muestra1[-3, -c(2,5)] # L) Quitar la fila 3, y las columnas 2 y 5
La función subset es otra manera utilizada para seleccionar variables, observaciones y/o niveles de una variables.
En el siguiente ejemplo construimos una nueva base de datos que contiene solo las variables ID, SalePrice y SaleType.
# A) Una nueva base de datos
Muestra2 <- subset(df, select = c(Id,SalePrice, SaleType))
head(Muestra2, 5)
## Id SalePrice SaleType
## 1 1 208500 WD
## 2 2 181500 WD
## 3 3 223500 WD
## 4 4 140000 WD
## 5 5 250000 WD
En este otro ejemplo construimos otra base de datos seleccionando todas las filas que tienen un precio mayor o igual que $20,000,00.00, pero sin las columnas ID y SaleType (por eso, el signo menos).
# B) Otra base de datos
Muestra3 <- subset(df, SalePrice >= 2000, select = -c(Id,SaleType))
Construiremos otra base de datos seleccionando todas las filas que tienen una precio menor o igual que 20000 o mayor que 21000, pero sin las columnas Id y SaleType. Se utilizará el símbolo | para el conectivo lógico o.
# C) Otra base de datos
Muestra4 <- subset(df, SalePrice <= 20000 | SalePrice > 21000, select = -c(Id, SaleType))
La función sample se utiliza para tomar una muestra aleatoria de tamaño n de un conjunto de datos. El muestreo se puede hacer con reemplazo o sin reemplazo. Es importante resaltar que, cada vez que llamamos sample, se generan muestras aleatorias diferentes. Pero, si antes fijamos una semilla de R (con set.seed), con un número específico como argumento, obtendremos los mismos resultados cada vez que se ejecute el comando.
# A) Numero de filas totales de nuestro dataframe
f <- nrow(df)
# B) Tamaño de la nueva muestra aleatoria.
n <- 2
# C) Tomeremos dos numeros aleatorios del intervalo de
# numeros enteros [1, f] sin reemplazo
i <- sample(1:f, n, replace=FALSE)
#D) La nueva muestra aleatoria: seleccionaremos dos filas
# de manera aleatoria y las columnas 1 y 2
Muestra7 <- df[i, c(1, 2)]
Muestra7
## Id MSSubClass
## 471 471 120
## 986 986 190
La función filter nos permite filtrar filas según una condición. Es muy similar a las funciones anteriores.
Muestra10a <- filter(df, df$LotArea >= 200)
Muestra10b <- filter(df, df$LotArea >= 200 & df$Id < 60)
Muestra10c <- filter(df[, 2:4], df$LotArea >= 200 & df$Street == "RL")
Muestra10c
## [1] MSSubClass MSZoning LotFrontage
## <0 rows> (or 0-length row.names)
La librería dplyr proporciona un conjunto de funciones para la manipulación y operaciones con data frames.
Concatenar múltiples operaciones.
Escribir una secuencia de operaciones de izquierda a derecha en una única pipeline (tubería).
En general, la instrucción básica de escritura es alguna de las dos opciones (Nuevo_nombre es el nombre del nuevo data frame):
# Primera opción:
"data.frame" %>% filter("condiciones") -> "Nuevo_nombre"
# Segunda opción
"Nuevo_nombre" <- "data.frame" %>% filter("condiciones")
# Comenzamos cargando la libreria que ocuparemos
library("dplyr")
# A) La nueva base de datos. Utilizaremos un filtro
df_pave <- df %>% filter(Street=="Pave")
# Veamos el dataframe anterior pero solo las
# columnas 1 y 6
head(df_pave[, c(1, 6)], 5)
## Id Street
## 1 1 Pave
## 2 2 Pave
## 3 3 Pave
## 4 4 Pave
## 5 5 Pave
donde básicamente df %>% filter(Street=="Pave")
se
le como: del dataframea df, filtra las filas para los cuales la
calle sea Pave.
Cuando trabajemos con una matriz o un data frame en R, podemos ordenar los datos por filas o por columnas.
# Consideremos el siguiente dataframe
mi_df <- df[, c(2, 3, 4)]
head(mi_df)
## MSSubClass MSZoning LotFrontage
## 1 60 RL 65
## 2 20 RL 80
## 3 60 RL 68
## 4 70 RL 60
## 5 60 RL 84
## 6 50 RL 85
y ordenemos por columna utlizando dos posibles caminos: R base: Supongamos que queremos ordenar el data frame por la columna LotFrontage en orden ascendente. Para ese propósito podemos escribir:
df_ordenado <- mi_df[order(mi_df$LotFrontage), ]
# Primeras filas
head(df_ordenado, 10)
## MSSubClass MSZoning LotFrontage
## 76 180 RM 21
## 226 160 RM 21
## 228 160 RM 21
## 233 160 RM 21
## 236 160 RM 21
## 364 160 RM 21
## 431 160 RM 21
## 435 180 RM 21
## 490 180 RM 21
## 501 160 RM 21
Nótese que en caso de empate, el orden se basa en el índice de las filas.
En caso de que necesitemos ordenar el data frame por varias columnas, especificamos más columnas dentro de la función order. Esto es muy útil cuando la columna principal que estamos ordenando tiene empates.
df_ordenado <- mi_df[order(mi_df$MSSubClass, mi_df$LotFrontage), ]
# Primeras filas
head(df_ordenado)
## MSSubClass MSZoning LotFrontage
## 848 20 RL 36
## 1177 20 RL 37
## 207 20 RL 40
## 1389 20 RL 42
## 214 20 RL 43
## 983 20 RL 43
La función arrange() se utiliza para ordenar las filas de un data frame de acuerdo a una o varias columnas/variables.
Por defecto arrange() ordena las filas por orden ascendente:
arrange(df, MSSubClass)[1:5, c(1,2)]
## Id MSSubClass
## 1 2 20
## 2 7 20
## 3 11 20
## 4 13 20
## 5 14 20
Si las queremos ordenar de forma descendente lo haremos del siguiente modo:
arrange(df, desc(MSSubClass))[1:5, c(1, 2)]
## Id MSSubClass
## 1 10 190
## 2 49 190
## 3 94 190
## 4 126 190
## 5 166 190
Podemos ordenar las filas según varias variables
arrange(df, SalePrice, LotArea)
Para esté apartado generaremos un DataFrame, para esto procedemos de la siguiente manera.
# Creando Vectores.
# Primero fijamos una semilla
set.seed(5)
edad <- sample(10:30, size = 100, replace = TRUE)
sexo <- sample(c("Masculino","Femenino"), size = 100, replace = TRUE)
ingresos <- sample(1000:5000, size = 100, replace = TRUE)
# Creamos el dataframe a partir de los vectores
# anteriores
datos <- data.frame(edad, sexo, ingresos)
head(datos)
## edad sexo ingresos
## 1 11 Femenino 2568
## 2 20 Masculino 1396
## 3 24 Femenino 3936
## 4 20 Femenino 1184
## 5 18 Masculino 2380
## 6 30 Masculino 2879
Para esta parte, usaremos lo aprendido en la guía de matrices y en la guía de operaciones lógicas.
Si sólo deseamos extraer todas las observaciones que tengan como sexo a Masculino. Usamos la siguiente sintaxis.
datos[datos$sexo=="Masculino", ][1:5,] # Para extraer todas las observaciones que son de sexo masculino. Solo elegimos las primeras 5 columnas
## edad sexo ingresos
## 2 20 Masculino 1396
## 5 18 Masculino 2380
## 6 30 Masculino 2879
## 7 16 Masculino 2193
## 14 25 Masculino 1780
donde datos[datos$sexo=="Masculino", ]
estamos
seleccionando todas aquellas filas que cumplen con la condición dada,
asimismo, estamos seleccionando todas las columnas del dataframe.
Continuando
head(datos[datos$sexo=="Femenino" & datos$ingresos >= 4000, ]) # Para extraer las observaciones de sexo femenino y con ingresos mayores iguales a 4000.
## edad sexo ingresos
## 9 12 Femenino 4322
## 11 24 Femenino 4332
## 17 19 Femenino 4610
## 18 30 Femenino 4549
## 42 28 Femenino 4437
## 65 11 Femenino 4585
Por ejemplo, si sólo se desea seleccionar de las primeras 20 filas, a las personas que son de 24 años o más y que tienen ingresos mayores o iguales a 4000:
datos[1:20, ][datos$edad >= 24 & datos$ingresos >= 4000, ] # Para extraer las observaciones con edad mayor igual a 24 años, pero sólo de las primeras 20 filas.
## edad sexo ingresos
## 11 24 Femenino 4332
## 18 30 Femenino 4549
## NA NA <NA> NA
## NA.1 NA <NA> NA
## NA.2 NA <NA> NA
## NA.3 NA <NA> NA
## NA.4 NA <NA> NA
## NA.5 NA <NA> NA
Ahora sí podemos realizar los filtros. Pero es primordial conocer su sintaxis.
select("data.frame", "starts_with o ends_with o contains"
:
Donde select es el comando para filtrar, en data.frame irá el
nombre del data frame en cuestión, y se podrán usar tres opciones
starts_with(), ends_with() o contains() para indicar si
empieza, si finaliza o contiene las características deseadas,
respectivamente.Si nos interesa solo las variables que empiezan con “e”. Usaríamos la siguiente sintaxis.
head(select(datos, starts_with("e"))) # Para extraer variables que empiecen con la letra e.
## edad
## 1 11
## 2 20
## 3 24
## 4 20
## 5 18
## 6 30
Ahora veamos si deseamos filtrar las variables que terminan en “O”.
head(select(datos, ends_with("O"))) # Para extraer variables que terminan con la letra O.
## sexo
## 1 Femenino
## 2 Masculino
## 3 Femenino
## 4 Femenino
## 5 Masculino
## 6 Masculino
Si deseamos incluir una columna nueva al data frame, usaremos el comando cbind().
Veamos un ejemplo:
# Se crea el vector casa de elementos "si" y "no".
set.seed(6)
casa <- sample(c("si","no"), size = 100, replace = TRUE)
Una vez creado lo agregamos al data frame datos
datos <- cbind(datos, casa) # Agregando la columna o variable casa.
Ahora generemos una nueva columna egresos:
egresos <- sample(1000:5000, size = 100, replace = TRUE)
datos <- cbind(datos,egresos)
datos[1:5, ]
## edad sexo ingresos casa egresos
## 1 11 Femenino 2568 si 3681
## 2 20 Masculino 1396 no 3402
## 3 24 Femenino 3936 si 4461
## 4 20 Femenino 1184 no 1658
## 5 18 Masculino 2380 no 2660
Y veamos si sus ingresos son mayores que sus egresos
datos$salud_fin <- datos$ingresos - datos$egresos
datos[1:5, ]
## edad sexo ingresos casa egresos salud_fin
## 1 11 Femenino 2568 si 3681 -1113
## 2 20 Masculino 1396 no 3402 -2006
## 3 24 Femenino 3936 si 4461 -525
## 4 20 Femenino 1184 no 1658 -474
## 5 18 Masculino 2380 no 2660 -280
Si se desea agregar filas, tendremos que usar el comando rbind. Pero primero se tendrá que crear un data.frame con las filas que se desea agregar.
Primero creamos un data frame con las filas que deseamos agregar.
z <- data.frame(edad=c(20, 24),
sexo=c("Femenino", "Femenino"),
ingresos=c(3000, 5000),
casa=c("si", "si"),
egresos = c(26564, 46),
salud_fin = c(-554, 6648)) # Creando un DF con las nuevas oservaciones.
Como se puede observar hemos tenido que crear el data frame z en donde se indica que tiene 2 filas. Una vez creado lo agregamos a nuestra base de datos con el comando rbind().
datos<-rbind(datos, z) # Uniendo los nuevos dataframe.
tail(datos)
## edad sexo ingresos casa egresos salud_fin
## 97 28 Femenino 4141 si 3227 914
## 98 30 Masculino 1072 si 4172 -3100
## 99 18 Masculino 4903 no 4745 158
## 100 13 Masculino 1879 si 3451 -1572
## 101 20 Femenino 3000 si 26564 -554
## 102 24 Femenino 5000 si 46 6648
Con la función mutate() podemos computar tranformaciones de variables en un data frame. A menudo, tendremos la necesidad de crear nuevas variables que se calculan a partir de variables existentes, mutate() nos proporciona una interfaz clara para realizar este tipo de operaciones.
Así, por ejemplo pensemos que queremos calcular el precio de las casa en pesos mexicanos. Consideremos el tipo de cambio del día de hoy 19.95
A continuación podemos crear una nueva variable precio_pesos con SalePrice y el tipo de cambio:
mutate(df, precio_pesos = SalePrice * 19.95)[1:5, c(81, 82)]
así, lo que hicimos antes fue crear una columna nueva y rellenar la información de dicha columna a partir de información que ya teníamos en nuestro dataframe
La función mutate() nos permite encadenar varias expresiones en una misma sentencia, para esto consideremos otra conversión, ahora veamos como pasar de pies a metros.
df_2 <- mutate(df, precio_pesos = SalePrice * 19.95, metros = LotArea * 0.3048)
df_2[1:5, c(82, 83)]
## precio_pesos metros
## 1 4159575 2576
## 2 3620925 2926
## 3 4458825 3429
## 4 2793000 2911
## 5 4987500 4346
donde agregamos ahora dos columnas de manera simultánea.
Calcular ciertas métricas u obtener valores sumarizados para ciertos grupos es uno de procedimientos más comunes, para esto procedemos usando la función:
Data frame aggregate(x, # Objeto de R
by, # Lista de variables (elementos que forman los grupos)
FUN, # Función a ser aplicada para crear el resumen estadístico
..., # Argumentos adicionales a ser pasados a FUN
simplify = TRUE, # Simplificar el resultado lo máximo posible (TRUE) o no (FALSE)
drop = TRUE) # Deshechar las combinaciones no usadas de grupos (TRUE) o no
(FALSE).
Formula aggregate(formula, # Fórmula de entrada
data, # Lista o data frame donde se encuentran las variables
FUN, # Función a ser aplicada para crear el resumen estadístico
..., # Argumentos adicionales a ser pasados a FUN
subset, # Observaciones a ser usadas (opcional)
na.action = na.omit) # Cómo tratar valores NA
Serie de tiempo aggregate(x, # Serie temporal nfrequency = 1, # Observaciones por unidad de tiempo (submúltiplo de x)
FUN = sum, # Función a ser aplicada para crear el resumen estadístico
ndeltat = 1, # Fracción entre dos observaciones consecutivas
ts.eps = getOption("ts.eps"), # Tolerancia para determinar si 'nfrequency' es un submúltiplo de la frecuencia de x
...) # Argumentos adicionales a ser pasados a FUN
Supongamos que queremos calcular el precio medio de las casas según su condición. Para esto tengamos en cuenta que para usar la función aggregate para calcular la media por grupos en R, deberemos especificar la variable numérica en el primer argumento, la categórica (como una lista) en el segundo y la función que se aplicará (en este caso mean) en el tercero. Una alternativa es especificar una fórmula de la forma: numérica ~ categórica.
# variable numerica | variable categorica
group_mean <- aggregate(df$SalePrice, list(df$SaleCondition), mean)
# Equivalente
group_mean <- aggregate(SalePrice ~ SaleCondition, data = df, mean)
group_mean
## SaleCondition SalePrice
## 1 Abnorml 146527
## 2 AdjLand 104125
## 3 Alloca 167377
## 4 Family 149600
## 5 Normal 175202
## 6 Partial 272292
donde calculamos el precio promedio de las casas por cada tipo.
Ocupando tydiverse, podemos hacer una mezcla de condiciones más interesante, por ejemplo
df %>% filter(SalePrice <= 40000) %>% group_by(SaleCondition) %>% summarise(media = mean(SalePrice))
## # A tibble: 2 x 2
## SaleCondition media
## <chr> <dbl>
## 1 Abnorml 36037
## 2 Normal 39650
donde primero realizaremos un filtro para aquellos precios de las
casas que son menores a 40000, después agruparemos a partir de las
categorías de la columna SaleCondition
y finalmente creamos
una columna nueva denominada media
para calcular el
promedio de los precios de las casas, ya filtrados, de acuerdo a cada
categoría agrupada.
Antes de saltar a los códigos R, echemos un vistazo a los diferentes tipos de uniones que usaremos en este documento. Tendremos principalmente 4 tipos de uniones: inner, left, right, and full joins.
Estos cuatro tipos diferentes de uniones se pueden resumir de la siguiente manera:
Unión interna: conserve solo los ID que están contenidos en ambos conjuntos de datos.
Unión izquierda: conserva solo los ID que están contenidos en el primer conjunto de datos.
Unión derecha: mantenga solo los ID que están contenidos en el segundo conjunto de datos.
Unión completa: mantenga todas las identificaciones.
# Creamos un dataframe
data_A <- data.frame(ID = paste0("ID_", 1:6),
x1 = 1:6,
x2 = letters[1:6])
data_A
## ID x1 x2
## 1 ID_1 1 a
## 2 ID_2 2 b
## 3 ID_3 3 c
## 4 ID_4 4 d
## 5 ID_5 5 e
## 6 ID_6 6 f
# Creamos otro dataframe
data_B <- data.frame(ID = paste0("ID_", 4:9),
y1 = 104:109,
y2 = LETTERS[4:9])
data_B
## ID y1 y2
## 1 ID_4 104 D
## 2 ID_5 105 E
## 3 ID_6 106 F
## 4 ID_7 107 G
## 5 ID_8 108 H
## 6 ID_9 109 I
La siguiente sintaxis explica cómo unir dos tablas de datos utilizando la funcion básica de R.
# Inner join
data_base_inner <- merge(data_A, data_B, by = "ID")
data_base_inner
## ID x1 x2 y1 y2
## 1 ID_4 4 d 104 D
## 2 ID_5 5 e 105 E
## 3 ID_6 6 f 106 F
# Left join
data_base_left <- merge(data_A, data_B, by = "ID", all.x = TRUE)
data_base_left
## ID x1 x2 y1 y2
## 1 ID_1 1 a NA <NA>
## 2 ID_2 2 b NA <NA>
## 3 ID_3 3 c NA <NA>
## 4 ID_4 4 d 104 D
## 5 ID_5 5 e 105 E
## 6 ID_6 6 f 106 F
# Right join
data_base_right <- merge(data_A, data_B, by = "ID", all.y = TRUE)
data_base_right
## ID x1 x2 y1 y2
## 1 ID_4 4 d 104 D
## 2 ID_5 5 e 105 E
## 3 ID_6 6 f 106 F
## 4 ID_7 NA <NA> 107 G
## 5 ID_8 NA <NA> 108 H
## 6 ID_9 NA <NA> 109 I
# Full join
data_base_full <- merge(data_A, data_B, by = "ID", all = TRUE)
data_base_full
## ID x1 x2 y1 y2
## 1 ID_1 1 a NA <NA>
## 2 ID_2 2 b NA <NA>
## 3 ID_3 3 c NA <NA>
## 4 ID_4 4 d 104 D
## 5 ID_5 5 e 105 E
## 6 ID_6 6 f 106 F
## 7 ID_7 NA <NA> 107 G
## 8 ID_8 NA <NA> 108 H
## 9 ID_9 NA <NA> 109 I
# Inner join
data_dplyr_inner <- inner_join(data_A, data_B, by = "ID")
# Left join
data_dplyr_left <- left_join(data_A, data_B, by = "ID")
# Right join
data_dplyr_right <- right_join(data_A, data_B, by = "ID")
# Full join
data_dplyr_full <- full_join(data_A, data_B, by = "ID")