Objetivo

En esta pequeña entrega la idea es presentar ejemplos simples de como manipular un dataset. Se utilizarán muchas funciones de múltiples paquetes (En cada caso se aclarara cuando será necesario utilizar cada uno).

Dataset

Para todo el ejemplo vamos a utilizar el dataset iris

Visualizar

Ver las primeras 7 observaciones:

head(iris,7)

Ver las últimas 5 observaciones:

tail(iris,5)

Descripción

Ver la estructura general de la tabla:

str(iris)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

Ver un resumen de las variables:

summary(iris)
##   Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
##  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
##  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
##  Median :5.800   Median :3.000   Median :4.350   Median :1.300  
##  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
##  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
##  Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
##        Species  
##  setosa    :50  
##  versicolor:50  
##  virginica :50  
##                 
##                 
## 

Ver una descripción más detallada de la tabla:

library(StatMeasures)
contents(iris)

Manipular Dataset

Para esta sección se utilizaran varias funciones del paquete dplyr:

library(dplyr)

Seleccionar Variables

Seleccionar solo algunas variables del dataset:

iris %>% select(Species,Sepal.Length)

Agregar Nueva Variable

Agregar una nueva variable al dataset:

iris %>% mutate(NuevaVariable=5)

Agregar varias:

iris %>% mutate(NuevaVariable=5,
                NuevaVariable2="Hola")

Cambiar Tipo de Dato

Inicialmente el tipo de dato de la variable Species es factor:

class(iris$Species)
## [1] "factor"

Para cambiarlo a character:

iris %>% mutate(Species=as.character(Species))->iris2

Lo chequeamos luego con:

class(iris2$Species)
## [1] "character"

Filtrar

Filtrar el dataset por una condición:

iris %>% filter(Sepal.Length<5)->iris2

Para verificar el cambio podemos chequear la cantidad de registros (Recordemos que el dataset original contenía 150 observaciones)

nrow(iris2)
## [1] 22

También puede filtrarse por varias condiciones a la vez:

iris %>% filter(Sepal.Length<5,Species=="virginica")

Quitar Observaciones duplicadas

Quitar duplicados es un caso particular de filtrar:

iris %>% filter(!duplicated(iris))->iris2
nrow(iris2)
## [1] 149

Ordenar

Ordenar por una variable:

iris %>% arrange(Sepal.Length)

Ordenar por varias:

iris %>% arrange(desc(Sepal.Length),Sepal.Width)

Reestructurar

Agrupar

Agrupar por una variable y contar observaciones:

iris %>% group_by(Species) %>% count()

Agrupar por una variable y calcular agregaciones:

iris %>% group_by(Species) %>% 
  summarise(Promedio_SL=mean(Sepal.Length),
            Mediana_SW=median(Sepal.Width))

Agrupar por varias variables:

iris %>% mutate(Sepal.Length.Grande=ifelse(Sepal.Length>6,"Si","No"))->iris2
iris2 %>% group_by(Species,Sepal.Length.Grande) %>% count()

Filas a Columnas

Para este caso vamos a generar un data.frame de ejemplo:

ejemplo<-data.frame(Categoria=c("A","B","A","B","A","B"),
                    Periodo=c(201802,201802,
                              201803,201803,
                              201804,201804),
                    Resultado=c("Bien","Mal","Regular",
                                "Excelente","Mal","Regular"))

Queremos que los valores de la variable Categoria pasen a ser columnas, y la variable Resultado se exponga de acuerdo a la combinación formada entre Categoria y Periodo:

ejemplo %>% reshape(timevar = "Categoria",idvar="Periodo",direction = "wide")

Columnas a Filas

Para este caso vamos a generar una variable que enumere cada observación de iris:

ejemplo2<-iris %>% mutate(ID_observacion=1:150)

Queremos que para cada observación se generen tantos registros como variables originales, con su respectivo valor. Es decir, para la primera observación deberían aparecer 5 registros (uno por cada columna de iris). Lo hacemos de la siguiente forma:

library(tidyr)
ejemplo2 %>% gather(key=Caracteristica,
                    value=Valor,
                    -ID_observacion)

Tabla Cruzada

Para este caso vamos a generar una variable nueva en iris:

ejemplo3<-iris %>% mutate(NuevaVariable=ifelse(runif(150,0,1)<0.4,"Si","No"))

Queremos saber cual es el valor promedio de la variable Sepal.Width por cada cruce de las variables Species y NuevaVariable:

library(data.table)
ejemplo3 %>% dcast(Species~NuevaVariable,
                   fun.aggregate=mean,
                   value.var="Sepal.Width")

Unir Tablas

Para poder unir dos tablas es necesario que las mismas compartan la misma dimensión por la cual se quiere unificar (Filas o Columnas). Vale resaltar que esta es una práctica poco sugerida debido a que abre la posibilidad a cometer errores de integridad y coherencia en la información.

Unir Columnas

Creamos dos data.frames diferentes a partir de iris:

df1<-iris %>% select(Species)
df2<-iris %>% select(Sepal.Length,Sepal.Width)

Ambos tienen la misma cantidad de filas:

nrow(df1)
## [1] 150
nrow(df2)
## [1] 150

Puedo unir las columnas de ambos data.frames:

cbind(df1,df2)

Unir por Filas

Creamos dos data.frames diferentes a partir de iris:

df1<-iris %>% filter(Sepal.Length==6)
df2<-iris %>% filter(Sepal.Length==4.4)

Ambos tienen la misma cantidad de columnas:

ncol(df1)
## [1] 5
ncol(df2)
## [1] 5

Puedo unir las filas de ambos data.frames:

rbind(df1,df2)

Cruzar Tablas

Para esta sección donde vamos a cruzar dos tablas diferentes, vamos a utilizar el dataset iris pero también vamos a crear otro con el cual hacer el cruce: (Notar que falta la especie versicolor y se incluye una nueva margarita)

Tabla_Aromas<-data.frame(
  Species=c("setosa","virginica","margarita"),
  Puntaje_Aroma=c(10,6,9)
) 

Solo coincidencias (Inner)

Buscamos las observaciones donde la variable elegida en el “by” tenga correspondencia en ambas tablas:

iris %>% inner_join(Tabla_Aromas,by="Species")->rdos_inner

Si verificamos la cantidad de observaciones obtenidas veremos que solo obtendremos 100 casos (Las 100 observaciones de iris que tienen a su especie en Tabla_Aromas)

nrow(rdos_inner)
## [1] 100

Cruzar desde la Izquierda (Left)

Buscamos las observaciones donde la variable elegida en el “by” tenga correspondencia en la tabla iris, independientemente si aparece en Tabla_Aromas:

iris %>% left_join(Tabla_Aromas,by="Species")->rdos_left

Si verificamos la cantidad de observaciones obtenidas veremos que hay 150 casos (Las 100 observaciones de iris que tienen a su especie en Tabla_Aromas y las 50 otras que no se encuentran)

nrow(rdos_left)
## [1] 150

Cruzar desde la Derecha (Right)

Buscamos las observaciones donde la variable elegida en el “by” tenga correspondencia en la Tabla_Aromas, independientemente si aparece en iris:

iris %>% right_join(Tabla_Aromas,by="Species")->rdos_right

Si verificamos la cantidad de observaciones obtenidas veremos que hay 101 casos (Las 100 observaciones de iris que tienen a su especie en Tabla_Aromas y la observaciones restante de Tabla_Aromas)

nrow(rdos_right)
## [1] 101

Todos los Cruces (Full)

Buscamos las observaciones donde la variable elegida en el “by” tenga correspondencia en alguna de las dos tablas:

iris %>% full_join(Tabla_Aromas,by="Species")->rdos_full

Si verificamos la cantidad de observaciones obtenidas veremos que hay 151 casos (Las 100 observaciones de iris que tienen a su especie en Tabla_Aromas y la observaciones restante de iris y Tabla_Aromas que no encontraron coincidencia)

nrow(rdos_full)
## [1] 151

Publicaciones Recomendadas

Para sumar a este trabajo considero que son útiles las hojas de ayuda que propone el equipo de R Studio:

Data Wrangling with dplyr and tidyr