Proceso del Tidyverse
DATA WRANGLING es el arte de dominar los datos y ponerlos bajo control para el análisis y abarca el importar, ordenar y transformar los datos, los 3 primeros pasos del proceso de Tidyverse.
Proceso del Tidyverse
Para importar ficheros tenemos dos opciones: mediante opción en la barra de herramientas y mediante línea de código.
Mediante la barra de herramientas, en el panel de Environment,
hacemos click en el botón que indica Import Dataset y
elegimos la opción según el tipo de fichero que queremos importar.
El objetivo de readr es proporcionar una forma rápida y
sencilla de leer datos rectangulares de archivos delimitados, como
valores separados por comas (CSV) y valores separados por tabuladores
(TSV).
Puedes encontrar más información del paquete readr en readr.tidyverse.org
Para leer un archivo .csv la función a utilizar es
read_csv() del paquete readr que es parte del
tidyverse. Es suficiente con especificar el nombre del
archivo, pero existen muchos más argumentos que podrías necesitar, como
por ejemplo:
read_csv(file, col_names = TRUE, col_types = ..., col_select = ..., comment = "#", trim_ws = TRUE, n_max = Inf)
Por lo que, si queremos cargar nuestro archivo, indicaremos el siguiente código que por default identificará el número de filas y columnas y el separador, lo indica en el mensaje de advertencia:
library(readr)
players21_1 <- read_csv("Data/players_21.csv")
## Rows: 18944 Columns: 106
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (42): player_url, short_name, long_name, nationality, club_name, league...
## dbl (61): sofifa_id, age, height_cm, weight_kg, league_rank, overall, poten...
## lgl (1): defending_marking
## date (2): dob, joined
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
También lo podemos hacer con el sistema base de , aquí no necesitamos cargar ninguna librería, y la sintaxis será la siguiente:
read.csv(file, sep = "," , dec = ",")
Especificamos ruta de archivo y delimitador de caracteres.
players21_2 <- read.csv("Data/players_21.csv", sep=",")
El paquete readxl facilita la transferencia de datos de
Excel a R y está diseñado para trabajar con datos tabulares.
readxl admite tanto el formato .xls heredado
como el formato .xlsx moderno basado en
xml.
Puedes encontrar más información del paquete readxl en
readxl.tidyverse.org
Para leer un archivo de Excel la función a utilizar es
read_excel() del paquete readxl que es parte
del tidyverse, de acuerdo a la siguiente sintaxis con
algunos argumentos básicos:
read_excel(file, sheet = "nombre", na = "NA", n_max = 5)
Para leer nuestro archivo de excel:
library(readxl)
analisis_com <- read_excel("Data/analisis_comercial.xlsx")
Con más argumentos:
analisis_com <- read_excel("Data/analisis_comercial.xlsx", sheet = "Ventas", na = "NA", n_max = 100)
Hay otras funciones para leer archivos excel como
read.xlsx del paquete openxlsx, que tiene
algunas ventajas como exportar archivos de excel y detectar fechas.
haven permite que R lea y escriba varios formatos de
datos utilizados por otros paquetes estadísticos al envolver la
fantástica biblioteca ReadStat C escrita por Evan Miller. Haven es parte
del tidyverse. Actualmente soporta:
read_sas() y read_xpt()read_sav() y read_por()read_dta()Puedes encontrar más información del paquete haven en haven.tidyverse.org
Otro paquete que puedes utilizar para cargar archivos de SAS, SPSS,
Stata y otros formatos es foreign: SAS
(read.xport()), SPSS (read.spss()), Stata
(read.dta()).
Si se desean manejar grandes volúmenes de datos, pueden aplicar el
paquete data.table. Existe un curso corto gratuito brindado
por la Sociedad Ecuatoriana de Estadística que pueden visitar en el
siguiente link: https://www.youtube.com/Sociedad_Ecuatoriana_Estadistica.
Los más usados son:
El tipo de dato fundamental en R es el vector. Un vector es una secuencia de elementos de datos todos del mismo tipo.
Creamos un vector de dimensión 1:
x <- 4
is.vector(x)
## [1] TRUE
Hay varias formas de crear vectores, pero una de las más comunes es
el operador de concatenación. Esto toma argumentos y los coloca todos en
un vector. A continuación creamos un vector de 4 elementos de tipo
numérico con la función c():
y <- c(11, 13, 15, 20)
y
## [1] 11 13 15 20
is.vector(y)
## [1] TRUE
También podemos crear un vector de tipo caracter:
z <- c("1", "5", "11", "14")
z
## [1] "1" "5" "11" "14"
is.vector(z)
## [1] TRUE
Utilizamos la función rep() para repetir un vector:
rep(y, times=5) # todo el vector 5 veces
## [1] 11 13 15 20 11 13 15 20 11 13 15 20 11 13 15 20 11 13 15 20
rep(y, each=5) # cada elemento se repite 5 veces
## [1] 11 11 11 11 11 13 13 13 13 13 15 15 15 15 15 20 20 20 20 20
También podemos realizar operaciones entre vectores de la misma dimensión:
w <- c(2, 5, 6, 8)
w
## [1] 2 5 6 8
y + 2*w - 3
## [1] 12 20 24 33
Y si los vectores tienen diferente dimensión, esto se conoce como “recycling”. En este caso, R imprime el resultado pero envía un mensaje de advertencia, siempre y cuando las dimensiones de los vectores no sean múltiplos entre sí:
y <- c(11, 13, 15)
y + 2*w - 3
## Warning in y + 2 * w: longitud de objeto mayor no es múltiplo de la longitud de
## uno menor
## [1] 12 20 24 24
Una de las funciones más simples puede ayudarnos a conocer la
información sobre el “recycling” que encontramos antes. Esta es la
función length().
length(x)
## [1] 1
length(y)
## [1] 3
length(z)
## [1] 4
Podemos usar any() y all() para responder
preguntas lógicas sobre elementos:
# ¿existe alguna y mayor a 10?
any(y>10)
## [1] TRUE
# ¿todas las y son menores a 10?
all(y<10)
## [1] FALSE
La función which() nos dirá los elementos que son
mayores a 10.
# ¿cuáles son los elementos mayores a 10?
which(y>10)
## [1] 1 2 3
Podemos llamar elementos específicos de un vector usando la indexación. Por ejemplo:
x[] es una forma de llamar a un elemento específico de
un vector.x[1] es el primer elemento.x[3] es el tercer elemento.x[-3] es un vector con todo menos el tercer
elemento.Vamos a intentar indexar los vectores que tenemos:
w # reviso los elementos que contiene el vector
## [1] 2 5 6 8
w[2] # extraigo el segundo elemento del vector w
## [1] 5
w[-3] # imprimo el vector w, excepto su tercer elemento
## [1] 2 5 8
Hemos visto cómo restar un elemento de un vector, pero podemos usar la misma información para volver a colocarlo.
w <- w[-3] # guardo el vector sin su tercer elemento
w
## [1] 2 5 8
w <- c(w[1:2], 6, w[3])
w
## [1] 2 5 6 8
Los data frames son estructuras de datos de dos dimensiones (rectangulares) que pueden contener datos de diferentes tipos, por lo tanto, son heterogéneas. Esta estructura de datos es la más usada para realizar análisis de datos.
Un data frame es un conjunto de vectores pero deben cumplir algunas propiedades.
Tidy Data
Vamos a crear un data frame con la función data.frame(),
que se conformará de la unión de 3 vectores creados previamente.
nombres <- c("Marcela", "Luis")
edades <- c(24,32)
seguro <- factor(c("IESS", "BMI"))
pacientes <- data.frame(nombres, edades, seguro)
pacientes
## nombres edades seguro
## 1 Marcela 24 IESS
## 2 Luis 32 BMI
Si deseo cambiar el nombre de las columnas del data frame desde la creación:
pacientes2 <- data.frame(N1=nombres, N2=edades, seguro)
pacientes2
## N1 N2 seguro
## 1 Marcela 24 IESS
## 2 Luis 32 BMI
Puedo crear un data frame directamente con sus columnas:
pacientes3 <- data.frame(nombres = c("Marcela", "Luis"),
edades = c(24,32),
seguro = factor(c("IESS", "BMI")))
pacientes3
## nombres edades seguro
## 1 Marcela 24 IESS
## 2 Luis 32 BMI
Cambiar los nombres de las columnas de un data frame:
names(pacientes3) <- c("Name", "Age", "Insurance")
pacientes3
## Name Age Insurance
## 1 Marcela 24 IESS
## 2 Luis 32 BMI
Para estudiar mejor el acceso a los data frames utilizaremos un
dataset de la librería de R llamada datos que traduce
varios conjuntos de datos de práctica.
library(datos)
##
## Attaching package: 'datos'
## The following object is masked _by_ '.GlobalEnv':
##
## nombres
aviones <- data.frame(aviones)
str(aviones) # Datos de aviones
## 'data.frame': 3322 obs. of 9 variables:
## $ codigo_cola: chr "N10156" "N102UW" "N103US" "N104UW" ...
## $ anio : int 2004 1998 1999 1999 2002 1999 1999 1999 1999 1999 ...
## $ tipo : chr "Ala fija multimotor" "Ala fija multimotor" "Ala fija multimotor" "Ala fija multimotor" ...
## $ fabricante : chr "EMBRAER" "AIRBUS INDUSTRIE" "AIRBUS INDUSTRIE" "AIRBUS INDUSTRIE" ...
## $ modelo : chr "EMB-145XR" "A320-214" "A320-214" "A320-214" ...
## $ motores : int 2 2 2 2 2 2 2 2 2 2 ...
## $ asientos : int 55 182 182 182 55 182 182 182 182 182 ...
## $ velocidad : int NA NA NA NA NA NA NA NA NA NA ...
## $ tipo_motor : chr "Turboventilador" "Turboventilador" "Turboventilador" "Turboventilador" ...
colnames(aviones)
## [1] "codigo_cola" "anio" "tipo" "fabricante" "modelo"
## [6] "motores" "asientos" "velocidad" "tipo_motor"
Para visualizar los primeros y últimos datos del dataset,
utilizaremos las funciones head() y
tail().
head(aviones, n = 10)
## codigo_cola anio tipo fabricante modelo motores
## 1 N10156 2004 Ala fija multimotor EMBRAER EMB-145XR 2
## 2 N102UW 1998 Ala fija multimotor AIRBUS INDUSTRIE A320-214 2
## 3 N103US 1999 Ala fija multimotor AIRBUS INDUSTRIE A320-214 2
## 4 N104UW 1999 Ala fija multimotor AIRBUS INDUSTRIE A320-214 2
## 5 N10575 2002 Ala fija multimotor EMBRAER EMB-145LR 2
## 6 N105UW 1999 Ala fija multimotor AIRBUS INDUSTRIE A320-214 2
## 7 N107US 1999 Ala fija multimotor AIRBUS INDUSTRIE A320-214 2
## 8 N108UW 1999 Ala fija multimotor AIRBUS INDUSTRIE A320-214 2
## 9 N109UW 1999 Ala fija multimotor AIRBUS INDUSTRIE A320-214 2
## 10 N110UW 1999 Ala fija multimotor AIRBUS INDUSTRIE A320-214 2
## asientos velocidad tipo_motor
## 1 55 NA Turboventilador
## 2 182 NA Turboventilador
## 3 182 NA Turboventilador
## 4 182 NA Turboventilador
## 5 55 NA Turboventilador
## 6 182 NA Turboventilador
## 7 182 NA Turboventilador
## 8 182 NA Turboventilador
## 9 182 NA Turboventilador
## 10 182 NA Turboventilador
tail(aviones, n=4)
## codigo_cola anio tipo fabricante modelo
## 3319 N997DL 1992 Ala fija multimotor MCDONNELL DOUGLAS AIRCRAFT CO MD-88
## 3320 N998AT 2002 Ala fija multimotor BOEING 717-200
## 3321 N998DL 1992 Ala fija multimotor MCDONNELL DOUGLAS CORPORATION MD-88
## 3322 N999DN 1992 Ala fija multimotor MCDONNELL DOUGLAS CORPORATION MD-88
## motores asientos velocidad tipo_motor
## 3319 2 142 NA Turboventilador
## 3320 2 100 NA Turboventilador
## 3321 2 142 NA Turboreactor
## 3322 2 142 NA Turboreactor
## mes temperatura humedad precipitaciones
## 1 enero 20.37 88 72.0
## 2 febrero 18.56 86 33.9
## 3 marzo 18.40 81 37.5
## 4 abril 21.96 79 36.6
## 5 mayo 29.53 80 31.0
## 6 junio 28.16 78 16.6
## 7 julio 36.38 71 1.2
## 8 agosto 36.62 69 6.8
## 9 septiembre 40.03 78 36.8
## 10 octubre 27.59 82 30.8
## 11 noviembre 22.15 85 38.5
## 12 diciembre 19.85 83 22.7
Los tibbles son data frames, pero modifican algunas características antiguas para hacernos la vida más fácil.
La mayoría de las veces usaremos el término tibble y data frame de manera indistinta.
Los Tibbles son marcos de datos que son perezosos y hoscos: hacen menos (es decir, no cambian los nombres o tipos de variables, y no hacen coincidencias parciales) y se quejan más (por ejemplo, cuando una variable no existe). Esto lo obliga a enfrentar los problemas antes, lo que generalmente conduce a un código más limpio y expresivo.
Tibbles también tiene un método print() mejorado que los hace más
fáciles de usar con grandes conjuntos de datos que contienen objetos
complejos. Puedes revisar vignette("tibble")si quieres
conocer más acerca de los tibbles.
Puedes encontrar más información del paquete tibble en
tibble.tidyverse.org.
La mayoría de los paquetes de R suelen usar data frames clásicos, así
que si deseas trabajar con tibbles (que es más recomendable) puedes
convertir un data frame en un tibble, con la función
as_tibble().
Existen dos diferencias principales entre el uso de un tibble y un data frame clásico: la impresión en la consola y la selección de los subconjuntos.
Vamos a visualizar un dataframe:
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✔ ggplot2 3.3.6 ✔ dplyr 1.0.9
## ✔ tibble 3.1.7 ✔ stringr 1.4.0
## ✔ tidyr 1.2.0 ✔ forcats 0.5.1
## ✔ purrr 0.3.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(datos)
str(flores) # estructura dataframe
## 'data.frame': 150 obs. of 5 variables:
## $ Largo.Sepalo: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Ancho.Sepalo: num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Largo.Petalo: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Ancho.Petalo: num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Especie : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
head(flores) # imprimo el dataframe
## Largo.Sepalo Ancho.Sepalo Largo.Petalo Ancho.Petalo Especie
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
Ahora mira las diferencias al imprimir un tibble:
flores <- as_tibble(flores) # convierto data frame en tibble
str(flores) # estructura tibble
## tibble [150 × 5] (S3: tbl_df/tbl/data.frame)
## $ Largo.Sepalo: num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Ancho.Sepalo: num [1:150] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Largo.Petalo: num [1:150] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Ancho.Petalo: num [1:150] 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Especie : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
flores # imprimo tibble
## # A tibble: 150 × 5
## Largo.Sepalo Ancho.Sepalo Largo.Petalo Ancho.Petalo Especie
## <dbl> <dbl> <dbl> <dbl> <fct>
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
## 7 4.6 3.4 1.4 0.3 setosa
## 8 5 3.4 1.5 0.2 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 10 4.9 3.1 1.5 0.1 setosa
## # … with 140 more rows
Dentro de R una lista es una estructura que puede combinar objetos de
diferentes tipos y se crean con la función list().
list(1, c(4,7), pacientes)
## [[1]]
## [1] 1
##
## [[2]]
## [1] 4 7
##
## [[3]]
## nombres edades seguro
## 1 Marcela 24 IESS
## 2 Luis 32 BMI
Podemos cambiar los nombres de los elementos de la lista:
lista1 <- list(A=1, B=c(4,7), C=pacientes)
lista1
## $A
## [1] 1
##
## $B
## [1] 4 7
##
## $C
## nombres edades seguro
## 1 Marcela 24 IESS
## 2 Luis 32 BMI
Podemos acceder a los elementos de la lista con
lista$posicion
lista1$B
## [1] 4 7
lista1$C
## nombres edades seguro
## 1 Marcela 24 IESS
## 2 Luis 32 BMI
Podemos acceder a los elementos de la lista con [] o al
contenido de las estructuras que contiene la listas con
[[]].
lista1[2]
## $B
## [1] 4 7
lista1[[2]]
## [1] 4 7
Diferencias entre estructuras de datos
Tipos de datos en R
Para determinar el tipo de dato de un dataset aplicamos la función
class()
Numéricos:
class(5)
## [1] "numeric"
class(analisis_com$Cantidad)
## [1] "numeric"
Factores:
Util para tipos de datos ordinales x: es el vector de información levels: los niveles del factor labels: nombre de los niveles El factor puede tener un orden específico
data_factor <- factor(x= c('alto', 'bajo', 'alto', 'alto'), levels = c('bajo', 'mediano', 'alto'))
data_factor # Mostrar el factor
## [1] alto bajo alto alto
## Levels: bajo mediano alto
Datos lógicos y valores perdidos:
Al importar los datos es posible que no estén en el formato correcto, podemos pasar de un tipo de dato a otro (siempre que sea posible), usando R-base:
data_factor <- factor(x= c('alto', 'bajo', 'alto', 'alto'), levels = c('bajo', 'mediano', 'alto'))
data_factor # Mostrar el factor
## [1] alto bajo alto alto
## Levels: bajo mediano alto
Fechas:
Paquetes Date, POSIXt y
lubridate que veremos más adelante.