Datos en formato CSV

Lecturas, limpieza y análisis de datos procedente de un dataset

El formato CSV (Comma Separated Values) es uno de los más comunes a la hora de intercambiar datos entre aplicaciones. Un archivo en este formato es un archivo de texto, en el que cada fila es una muestra u ocurrencia y cada columna una variable. Los datos en cada fila se separan entre sí mediante comas, de allí la denominación del formato. Un archivo CSV puede incluir o no un encabezado, una primera línea especificando el nombre de cada una de las columnas de datos. En caso de que el separador para la parte decimal de los números sea la coma, en lugar del punto, los datos de cada fila se separan entre sí mediante puntos y comas. Los datos no numéricos, especialmente cadenas de caracteres, pueden ir delimitados por comillas o no. En suma, existe una cierta variabilidad en el formato CSV si bien su estructura fundamental es siempre la misma. Por ello R cuenta con varias funciones distintas para operar con este tipo de archivos.

Lectura de archivos CSV

Al importar un archivo almacenado en formato CSV, obtenemos como resultado un dataframe R, para realizar esta tarea R cuenta con funciones como read.table(), read.csv() y read.csv2(), siendo estas dos últimas funciones versiones especializadas de la primera, en ella se le asignan valores por defecto a algunos de los parámetros utilizados en la función de lectura. Sintaxis de la función de lectura:

# funciones básicas de resumen, estructura, dimensiones y cabeceras
data_iris<-read.csv("C:/Users/LENOVO/Desktop/Data Science con R Studio/Curso de R Studio/iris/iris.csv")
head(data_iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 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

Veamos cuantos registros tiene el archivo, el númeo de variables y el nombre de ellas de la forma siguiente:

nrow(data_iris)
## [1] 150
ncol(data_iris)
## [1] 5
colnames(data_iris)
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"

Podemos usar la función summary para obtener una vista de los primeros registros, tipo de variable y otros atributos de cada variable. ``

summary(data_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  
##                 
##                 
## 

1.2. Qué hacer cuando faltan valores en un dataset.

Primero carguemos nuestro archivo con el cual trabajaremos los valores N/A, este archivo seá: Llamemos a este missing-data.csv

data_missing<-read.csv("C:/Users/LENOVO/Desktop/Data Science con R Studio/Curso de R Studio/missing-data.csv",na.strings = "")
head(data_missing)
##   Income Phone_type   Car_type
## 1  89800    Android     Luxury
## 2  47500    Android Non-Luxury
## 3  45000     iPhone     Luxury
## 4  44700       <NA>     Luxury
## 5  59500     iPhone     Luxury
## 6     NA    Android Non-Luxury

Tal como podemos observar al dataset le faltan valores, el mismo contiene tres columnas que representan el ingreso, el tipo de teléfono y el vehículo, clasificado en lujo y no lujo, tiene 27 filas y 3 columnas. 1.- Procedimiento: omitir todos los registros que contengan valores NA con la función na.omit()

data_cleaned<-na.omit(data_missing)
data_cleaned
##    Income Phone_type   Car_type
## 1   89800    Android     Luxury
## 2   47500    Android Non-Luxury
## 3   45000     iPhone     Luxury
## 5   59500     iPhone     Luxury
## 7   63300     iPhone Non-Luxury
## 8   52900    Android     Luxury
## 9   78200    Android     Luxury
## 10 145100     iPhone     Luxury
## 11  88600     iPhone Non-Luxury
## 12  65600     iPhone     Luxury
## 14  94600    Android     Luxury
## 15  59400     iPhone     Luxury
## 16  47300     iPhone Non-Luxury
## 18      0     iPhone Non-Luxury
## 19      0    Android     Luxury
## 20  83000     iPhone     Luxury
## 21  64100    Android Non-Luxury
## 22  42100     iPhone Non-Luxury
## 23      0     iPhone     Luxury
## 24  91500     iPhone Non-Luxury
## 25  51200    Android     Luxury
## 26  13800     iPhone Non-Luxury
## 27  47500     iPhone Non-Luxury

observamos que se han eliminado los registros que tenían valores faltantes N/A

nrow(data_cleaned)
## [1] 23
ncol(data_cleaned)
## [1] 3

Uso de la función cmplete.cases() para eliminar todos los valores faltantes. La función complte nos devuelve un vector con valores TRUE cuando existe algun valor en el registro o TRUE en caso contrario, en nuestro caso si aplicamos la función a nuestro dataset data_missing obtenemos

complete.cases(data_missing)
##  [1]  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [13] FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [25]  TRUE  TRUE  TRUE

Se observa que el cuarto valor tiene un valor FALSE, lo que indica que en la cuarta fila encontramos el primer valor NA, y así seguimos y encontramos el resto de los valores ausentes. usemos esta función para eliminar los valores ausente, esto lo realizamos de la manera siguinete:

  data_cleaned2<-data_missing[complete.cases(data_missing),]
  data_cleaned2
##    Income Phone_type   Car_type
## 1   89800    Android     Luxury
## 2   47500    Android Non-Luxury
## 3   45000     iPhone     Luxury
## 5   59500     iPhone     Luxury
## 7   63300     iPhone Non-Luxury
## 8   52900    Android     Luxury
## 9   78200    Android     Luxury
## 10 145100     iPhone     Luxury
## 11  88600     iPhone Non-Luxury
## 12  65600     iPhone     Luxury
## 14  94600    Android     Luxury
## 15  59400     iPhone     Luxury
## 16  47300     iPhone Non-Luxury
## 18      0     iPhone Non-Luxury
## 19      0    Android     Luxury
## 20  83000     iPhone     Luxury
## 21  64100    Android Non-Luxury
## 22  42100     iPhone Non-Luxury
## 23      0     iPhone     Luxury
## 24  91500     iPhone Non-Luxury
## 25  51200    Android     Luxury
## 26  13800     iPhone Non-Luxury
## 27  47500     iPhone Non-Luxury

y como vemos no hay valores nulos. 2.- Eliminar los registros NA de una sola variable, dejando el resto de las variables con sus valores originales, esto lo haciendo uso de la función is.na(), llamemos a este nuevo dataset data_income_cleaned

# 2)ELIMINAR LOS REGISTROS DE UNA SOLA VARIABLE USANDO is.na() con !
data_income_cleaned<-data_missing[!is.na(data_missing$Income),]
data_income_cleaned
##    Income Phone_type   Car_type
## 1   89800    Android     Luxury
## 2   47500    Android Non-Luxury
## 3   45000     iPhone     Luxury
## 4   44700       <NA>     Luxury
## 5   59500     iPhone     Luxury
## 7   63300     iPhone Non-Luxury
## 8   52900    Android     Luxury
## 9   78200    Android     Luxury
## 10 145100     iPhone     Luxury
## 11  88600     iPhone Non-Luxury
## 12  65600     iPhone     Luxury
## 14  94600    Android     Luxury
## 15  59400     iPhone     Luxury
## 16  47300     iPhone Non-Luxury
## 17  72100       <NA>     Luxury
## 18      0     iPhone Non-Luxury
## 19      0    Android     Luxury
## 20  83000     iPhone     Luxury
## 21  64100    Android Non-Luxury
## 22  42100     iPhone Non-Luxury
## 23      0     iPhone     Luxury
## 24  91500     iPhone Non-Luxury
## 25  51200    Android     Luxury
## 26  13800     iPhone Non-Luxury
## 27  47500     iPhone Non-Luxury

En nuestro dataset podemos observar que existen en la columna ingresos valores iguales a cero, en muchos casos tendremos que llevar estos valores como NA u realizar otros cambios a este NA, esto lo´podemos realizar de la forma siguiente:

#CONVERTIR LOS CEROS DEL INGRESO EN na
data_missing$Income[data_missing$Income==0]<-NA
data_missing
##    Income Phone_type   Car_type
## 1   89800    Android     Luxury
## 2   47500    Android Non-Luxury
## 3   45000     iPhone     Luxury
## 4   44700       <NA>     Luxury
## 5   59500     iPhone     Luxury
## 6      NA    Android Non-Luxury
## 7   63300     iPhone Non-Luxury
## 8   52900    Android     Luxury
## 9   78200    Android     Luxury
## 10 145100     iPhone     Luxury
## 11  88600     iPhone Non-Luxury
## 12  65600     iPhone     Luxury
## 13     NA    Android Non-Luxury
## 14  94600    Android     Luxury
## 15  59400     iPhone     Luxury
## 16  47300     iPhone Non-Luxury
## 17  72100       <NA>     Luxury
## 18     NA     iPhone Non-Luxury
## 19     NA    Android     Luxury
## 20  83000     iPhone     Luxury
## 21  64100    Android Non-Luxury
## 22  42100     iPhone Non-Luxury
## 23     NA     iPhone     Luxury
## 24  91500     iPhone Non-Luxury
## 25  51200    Android     Luxury
## 26  13800     iPhone Non-Luxury
## 27  47500     iPhone Non-Luxury

Allí vemos que luego de realizar este cambio tenemos 5 NA en la variable Income, anteriormente teniamos 3.

Medidas de dispersión y centralización con valores faltantes: si queremos calcular la media de una variable numérica que contenga valores faltantes, debemos indicarle a la función mean que el parámetro na.rm = TRUE (rm indica remove (quitar)) para poder realizar el cálculo,

#CALCULO DE LA MEDIA EN UNA COLUMNA CON VALORES FALTANTES
mean(data_missing$Income,na.rm = TRUE)
## [1] 65763.64

Esta forma de calcular la media la podemos usar para calcula la desviación típica u otro valor.

3.- Imputar la media en los valores NA de variable numérica

Carguemos nuevamente el archivo que hemos utilizados (missing_data.csv) y coloquemos NA en los ceros presentes variable Income y llamemos a este dataset data_missing2

data_missing2<-read.csv("C:/Users/LENOVO/Desktop/Data Science con R Studio/Curso de R Studio/missing-data.csv",na.strings = "")
#CONVERTIR LOS CEROS DEL INGRESO EN na
data_missing2$Income[data_missing2$Income==0]<-NA
data_missing2
##    Income Phone_type   Car_type
## 1   89800    Android     Luxury
## 2   47500    Android Non-Luxury
## 3   45000     iPhone     Luxury
## 4   44700       <NA>     Luxury
## 5   59500     iPhone     Luxury
## 6      NA    Android Non-Luxury
## 7   63300     iPhone Non-Luxury
## 8   52900    Android     Luxury
## 9   78200    Android     Luxury
## 10 145100     iPhone     Luxury
## 11  88600     iPhone Non-Luxury
## 12  65600     iPhone     Luxury
## 13     NA    Android Non-Luxury
## 14  94600    Android     Luxury
## 15  59400     iPhone     Luxury
## 16  47300     iPhone Non-Luxury
## 17  72100       <NA>     Luxury
## 18     NA     iPhone Non-Luxury
## 19     NA    Android     Luxury
## 20  83000     iPhone     Luxury
## 21  64100    Android Non-Luxury
## 22  42100     iPhone Non-Luxury
## 23     NA     iPhone     Luxury
## 24  91500     iPhone Non-Luxury
## 25  51200    Android     Luxury
## 26  13800     iPhone Non-Luxury
## 27  47500     iPhone Non-Luxury

Creemos una columna adicional al data_missing2, de tal manera que si en el registro que corresponde al ingreso hay un NA coloque la media de la columna, sin los valores NA, y en caso contrario que coloque el valor del ingreso, eso lo realizamos de la manera siguiente:

data_missing2$MEDIA<-ifelse(is.na(data_missing2$Income),mean(data_missing2$Income,na.rm=TRUE),data_missing2$Income)
data_missing2
##    Income Phone_type   Car_type     MEDIA
## 1   89800    Android     Luxury  89800.00
## 2   47500    Android Non-Luxury  47500.00
## 3   45000     iPhone     Luxury  45000.00
## 4   44700       <NA>     Luxury  44700.00
## 5   59500     iPhone     Luxury  59500.00
## 6      NA    Android Non-Luxury  65763.64
## 7   63300     iPhone Non-Luxury  63300.00
## 8   52900    Android     Luxury  52900.00
## 9   78200    Android     Luxury  78200.00
## 10 145100     iPhone     Luxury 145100.00
## 11  88600     iPhone Non-Luxury  88600.00
## 12  65600     iPhone     Luxury  65600.00
## 13     NA    Android Non-Luxury  65763.64
## 14  94600    Android     Luxury  94600.00
## 15  59400     iPhone     Luxury  59400.00
## 16  47300     iPhone Non-Luxury  47300.00
## 17  72100       <NA>     Luxury  72100.00
## 18     NA     iPhone Non-Luxury  65763.64
## 19     NA    Android     Luxury  65763.64
## 20  83000     iPhone     Luxury  83000.00
## 21  64100    Android Non-Luxury  64100.00
## 22  42100     iPhone Non-Luxury  42100.00
## 23     NA     iPhone     Luxury  65763.64
## 24  91500     iPhone Non-Luxury  91500.00
## 25  51200    Android     Luxury  51200.00
## 26  13800     iPhone Non-Luxury  13800.00
## 27  47500     iPhone Non-Luxury  47500.00

Para las variable cotegóricas debemos imputar valores aleatorios extraidos desde una muestra aleatoria de los datos que no faltan, esto lo haremos creando dos funciones, primera funcion

#x vector de datos que ouede contener NA
rand.impute<- function(x){
# Vector boolenao  dependiendo de los NA
  missing<- is.na(x)
  # cuantos valores hay NA dentro de x
  n.missing<-sum(missing)
  # x.obs son los registros diferente a NA en x
  x.obs<- x[!missing]
  # el valor imputado será por defecto el mismo valor entrado por parámetro
  imputed<-x
  # en los valores que faltaban, se reemplazan por una muestra de los conocidos
  imputed[missing]<-sample(x.obs,n.missing,replace = TRUE)
  return(imputed)
}

# Creamos la segunda funcion que es la encargada de llamar las columnas del dataframe al cual le haremos la imputación
random.impute.data.frame<- function(dataframe,cols){
  names<- names(dataframe)
  for (col in cols) {
    name<-paste(names[col],".imputed", sep = ".")
    dataframe[name]=rand.impute(dataframe[,col])
  }
  dataframe
  
}

Ya hemos cargado las funciones creadas y ahora modifiquemos nuestro dataset original, para ello lo cargamos, nuevamente, y le aplicamos las funciones.

data_missing<-read.csv("C:/Users/LENOVO/Desktop/Data Science con R Studio/Curso de R Studio/missing-data.csv",na.strings = "")
data_missing3<-random.impute.data.frame(data_missing,c(1,2))
data_missing3
##    Income Phone_type   Car_type Income..imputed Phone_type..imputed
## 1   89800    Android     Luxury           89800             Android
## 2   47500    Android Non-Luxury           47500             Android
## 3   45000     iPhone     Luxury           45000              iPhone
## 4   44700       <NA>     Luxury           44700              iPhone
## 5   59500     iPhone     Luxury           59500              iPhone
## 6      NA    Android Non-Luxury               0             Android
## 7   63300     iPhone Non-Luxury           63300              iPhone
## 8   52900    Android     Luxury           52900             Android
## 9   78200    Android     Luxury           78200             Android
## 10 145100     iPhone     Luxury          145100              iPhone
## 11  88600     iPhone Non-Luxury           88600              iPhone
## 12  65600     iPhone     Luxury           65600              iPhone
## 13     NA    Android Non-Luxury               0             Android
## 14  94600    Android     Luxury           94600             Android
## 15  59400     iPhone     Luxury           59400              iPhone
## 16  47300     iPhone Non-Luxury           47300              iPhone
## 17  72100       <NA>     Luxury           72100              iPhone
## 18      0     iPhone Non-Luxury               0              iPhone
## 19      0    Android     Luxury               0             Android
## 20  83000     iPhone     Luxury           83000              iPhone
## 21  64100    Android Non-Luxury           64100             Android
## 22  42100     iPhone Non-Luxury           42100              iPhone
## 23      0     iPhone     Luxury               0              iPhone
## 24  91500     iPhone Non-Luxury           91500              iPhone
## 25  51200    Android     Luxury           51200             Android
## 26  13800     iPhone Non-Luxury           13800              iPhone
## 27  47500     iPhone Non-Luxury           47500              iPhone

1.3.- Variables dummies Muchas veces tendremos variables categóricas, factores, y habrá que usarlas en métodos analíticos que requieren números para poder computar, para ello usemos el dataframe data-conversion.csv y carguemos el paquete dummies e importamos la librería correspondiente

library(dummies)
## dummies-1.5.6 provided by Decision Patterns
students<-read.csv("C:/Users/LENOVO/Desktop/Data Science con R Studio/Curso de R Studio/data-conversion.csv")
students
##    Age State Gender Height Income
## 1   23    NJ      F     61   5000
## 2   13    NY      M     55   1000
## 3   36    NJ      M     66   3000
## 4   31    VA      F     64   4000
## 5   58    NY      F     70  30000
## 6   29    TX      F     63  10000
## 7   39    NJ      M     67  50000
## 8   50    VA      M     70  55000
## 9   23    TX      F     61   2000
## 10  36    VA      M     66  20000
students.new <- dummy.data.frame(students, sep = ".")
## Warning in model.matrix.default(~x - 1, model.frame(~x - 1), contrasts = FALSE):
## non-list contrasts argument ignored

## Warning in model.matrix.default(~x - 1, model.frame(~x - 1), contrasts = FALSE):
## non-list contrasts argument ignored
names(students.new)
## [1] "Age"      "State.NJ" "State.NY" "State.TX" "State.VA" "Gender.F" "Gender.M"
## [8] "Height"   "Income"
students.new1 <- dummy.data.frame(students, names = c("State","Gender") , sep = ".")
## Warning in model.matrix.default(~x - 1, model.frame(~x - 1), contrasts = FALSE):
## non-list contrasts argument ignored

## Warning in model.matrix.default(~x - 1, model.frame(~x - 1), contrasts = FALSE):
## non-list contrasts argument ignored
students.new1
##    Age State.NJ State.NY State.TX State.VA Gender.F Gender.M Height Income
## 1   23        1        0        0        0        1        0     61   5000
## 2   13        0        1        0        0        0        1     55   1000
## 3   36        1        0        0        0        0        1     66   3000
## 4   31        0        0        0        1        1        0     64   4000
## 5   58        0        1        0        0        1        0     70  30000
## 6   29        0        0        1        0        1        0     63  10000
## 7   39        1        0        0        0        0        1     67  50000
## 8   50        0        0        0        1        0        1     70  55000
## 9   23        0        0        1        0        1        0     61   2000
## 10  36        0        0        0        1        0        1     66  20000

GRÁFICOS CON R STUDIO

Uno de los mecanismos de exploracón de datos más usuales y útiles consiste en generar representaciones gráficas de las variables que componen el dataset.

Es frecuente que a partir de la observación de dichas representaciones pueda obtenerse información más fácilmente interpretable que la que nos ofrecen los métodos de exploración descritos en el cap´ıtulo previo.

R cuenta en su paquete base con múltiples funciones para la producción de gráficas, pudiendo generar representaciones en forma de nubes de puntos, líneas,barras, gráficos circulares, etc. Tambi´en tenemos funciones para elaborar histogramas y curvas de densidad. Esos gr´aficos, adem´as de ser útiles como v´ıa de exploración de los datos, pueden ser almacenados para su posterior reutilizaci´on en cualquier tipo de documento.

Ahora conoceremos algunas de las posibilidades gráficas de R Studio, alojadas en su mayor parte en el paquete graphics ( la cual hacer parte de la instalación base de R), aprendiendo a usarlas con casos prácticos en los se utilizarán los datasets que hemos visto hasta ahora.

Gráficos básicos

Muchos de los gráficos básicos que es posible generar con R son resultado de la función plot(). Esta acepta un importante número de parámetros con los que es configurar el gráfico resultante, establecer títulos y otros parámetros gráficos

Sintáxis:

plot(valoresX[, valoresY type = tipoGráfico,

main = t´ıtuloPrincipal, sub = subtítulo,

xlab = t´ıtuloEjeX, ylab = títuloEjeY])

Genera una representación gráfica de los valores facilitados acorde a la configuración especificada por los parámetros adicionales. El parámetro type toma por defecto el valor “p”, dibujando un punto por cada dato. Otros posibles valores son “l”, para dibujar líneas, y “h”, para obtener un histograma.

Para revisar algunas de las diferentes visualizaciones usemos el dataset de auto

auto<-read.csv("C:/Users/LENOVO/Desktop/Data Science con R Studio/Curso de R Studio/auto-mpg.csv")

La variable cilindro esta como variable numérica, sin embargo esta es una categoria, razón por la cual la pasamos a categoría

# Sobreescribimos la variable cylinders
auto$cylinders<-factor(auto$cylinders,
                       levels = c(3,4,5,6,8),
                       labels=c("3cil","4cil","5cil","6cil","8cil"))

Usemos la función attach para que el dataset forme parte de la estructura principal de R

attach(auto)
# Ahora podemos acceder a las variables sin llamar al dataset
head(cylinders)
## [1] 8cil 8cil 8cil 8cil 8cil 8cil
## Levels: 3cil 4cil 5cil 6cil 8cil
# Empecemos con un histograma
hist(acceleration,
     col = "blue",
     xlab = "Aceleración",
     ylab = "Frecuencias",
     main = "Histograma de aceleración")

BOXPLOTS

boxplot(mpg,
        xlab="Millas por galeón")

# Si queremos visualizar boxplots por año 
  boxplot(mpg~model.year,xlab="Años",main = "Millas por Galeón (por año)")

Veamos el consumo de combustible en función al número de cilindros

boxplot(mpg~cylinders , xlab= "Consumo según los cilindros")

SCATTERPLOT

plot(mpg~horsepower)

Veamos lo que se conoce como Matriz de Scatterplots

Por regla general, las nubes de puntos resultan más útiles cuando se representan dos variables, una frente a otra en los ejes X e Y, a fin de determinar si existe o no algún tipo de correlaci´on entre ellas. Lo único que tenemos que hacer es facilitar a plot() dos vectores de valores, uno para el eje X y otro para el eje Y.

pairs(~mpg+displacement+horsepower+weight)

Web Scraping

En ocasiones interesa descargar datos directamente de páginas de internet recorriendo una, varias o, incluso, muchas de ellas. A eso, a falta de un nombre de consenso en español se lo denomina web scraping.

Para descargar datos de páginas web usaremos el paquete rvest.

Para este ejemplo usemos la página: https://dolar.wilkinsonpc.com.co/ donde obtenemos en una tabla la cotización del peso respecto a varias monedas extrajera

library("rvest")
## Warning: package 'rvest' was built under R version 3.6.3
## Loading required package: xml2
## Warning: package 'xml2' was built under R version 3.6.3
url<-"https://dolar.wilkinsonpc.com.co/"
#Obtenemos código html de la página web
pagina_web <- read_html(url)
pagina_web <- html_nodes(pagina_web, "table")

La segunda línea descarga y preprocesa una página descargada de internet. El objeto pagina_web contiene una representación interna de la página. Una página web, en el fondo, no es otra cosa que un árbol del que penden nodos que son párrafos, imágenes, enlaces, tablas, etc. Sobre este árbol se pueden realizar distintos tipos de consultas, i.e., extraer distintos tipos de nodos.

La función html_nodes captura los nodos que tienen determinadas características. En este ejemplo, como ocurre con mucha frecuencia, nos interesan los identificados como tablas (tables). De hecho, las tablas son tan interesantes que el paquete rvest proporciona una función auxiliar para convertir los nodos de tipo table en tablas de R: html_table.

En nuestro ejemplo, la página contiene varias tablas. Como consecuencia, pagina_web es una lista de nodos:

length(pagina_web)
## [1] 35
sapply(pagina_web, class)
##  [1] "xml_node" "xml_node" "xml_node" "xml_node" "xml_node" "xml_node"
##  [7] "xml_node" "xml_node" "xml_node" "xml_node" "xml_node" "xml_node"
## [13] "xml_node" "xml_node" "xml_node" "xml_node" "xml_node" "xml_node"
## [19] "xml_node" "xml_node" "xml_node" "xml_node" "xml_node" "xml_node"
## [25] "xml_node" "xml_node" "xml_node" "xml_node" "xml_node" "xml_node"
## [31] "xml_node" "xml_node" "xml_node" "xml_node" "xml_node"

Para poder ver el número de variables que contiene cada tabla usamos

  sapply(pagina_web, function(x) dim(html_table(x, fill = TRUE)))
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
## [1,]    1    1    1    1    1    1    1    1    1     1     1     1     1     1
## [2,]    2    2    2    2    2    2    2    2    2     2     2     2     2     2
##      [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26]
## [1,]     1     1     1     1     1     1     1     1     1     1   141   140
## [2,]     2     1     1     1     1     1     1     1     1     1   281     2
##      [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35]
## [1,]     1     1    13     2     1     6     7     3     3
## [2,]     2     2     2     2     2     2     2     2     1

que nos indica que la qtabla 29 tiene 13 filas y dos columnas, lo cual es un indicio sólido de que es la que va a contener las cotizaciones de la monedas para los 12 países que etan reflejados en la página web.

Creemos un objeto y llamemoslo cot y carguemos la tabla 29 allí

cot <- html_table(pagina_web[[29]])

Veamos el objeto creado

cot
##                                X1        X2
## 1                       Dólar TRM $3,706.06
## 2  Dolar Compra (Casas de Cambio) $3,300.00
## 3   Dolar Venta (Casas de Cambio) $3,400.00
## 4                            Euro $4,187.68
## 5                 Libra Esterlina $4,631.43
## 6                    Franco Suizo $3,919.72
## 7                Dólar Canadiense $2,731.16
## 8               Dólar Australiano $2,568.86
## 9                            Real   $718.01
## 10                 Peso Argentino    $52.84
## 11                  Peso Mexicano   $165.58
## 12                   Peso Chileno     $4.52
## 13                        Bolivar    $0.018

Cambiemos el nombre de cada variable

names(cot)=c("Moneda","Cotización")
# Hagamos un resumen de las variables en estudio
summary(cot)
##     Moneda           Cotización       
##  Length:13          Length:13         
##  Class :character   Class :character  
##  Mode  :character   Mode  :character

Vemos que la variable Cotización es de tipo charter, para convertirla a numérica debemos eliminar el símbolo $ by de, igual manera, eliminar el punto que de millar que aparece en algunos geristros.

Para eliminar el símbolo $ usaremos la librería tidyverse

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 3.6.3
## -- Attaching packages ------------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.0     v purrr   0.3.4
## v tibble  3.0.1     v dplyr   1.0.0
## v tidyr   1.0.2     v stringr 1.4.0
## v readr   1.3.1     v forcats 0.5.0
## Warning: package 'ggplot2' was built under R version 3.6.3
## Warning: package 'tibble' was built under R version 3.6.3
## Warning: package 'tidyr' was built under R version 3.6.3
## Warning: package 'readr' was built under R version 3.6.3
## Warning: package 'purrr' was built under R version 3.6.3
## Warning: package 'dplyr' was built under R version 3.6.3
## Warning: package 'forcats' was built under R version 3.6.3
## -- Conflicts ---------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter()         masks stats::filter()
## x readr::guess_encoding() masks rvest::guess_encoding()
## x dplyr::lag()            masks stats::lag()
## x purrr::pluck()          masks rvest::pluck()
cot$cotizacion2<-str_sub(cot$Cotización,2,)
cot
##                            Moneda Cotización cotizacion2
## 1                       Dólar TRM  $3,706.06    3,706.06
## 2  Dolar Compra (Casas de Cambio)  $3,300.00    3,300.00
## 3   Dolar Venta (Casas de Cambio)  $3,400.00    3,400.00
## 4                            Euro  $4,187.68    4,187.68
## 5                 Libra Esterlina  $4,631.43    4,631.43
## 6                    Franco Suizo  $3,919.72    3,919.72
## 7                Dólar Canadiense  $2,731.16    2,731.16
## 8               Dólar Australiano  $2,568.86    2,568.86
## 9                            Real    $718.01      718.01
## 10                 Peso Argentino     $52.84       52.84
## 11                  Peso Mexicano    $165.58      165.58
## 12                   Peso Chileno      $4.52        4.52
## 13                        Bolivar     $0.018       0.018

En el paso anterior creamos una nueva variable llamada cotizacion2 donde los registros no contienen el símbolo $, si embargo sigue siendo de tipo char, para llevar la columna a numérica hagamos lo siguiente:

# Pasar a numérico y sustituir (gsub) la coma que está como decimal

cot$cotizacion2<-as.numeric(gsub( ",","",cot$cotizacion2))
summary(cot)
##     Moneda           Cotización         cotizacion2      
##  Length:13          Length:13          Min.   :   0.018  
##  Class :character   Class :character   1st Qu.: 165.580  
##  Mode  :character   Mode  :character   Median :2731.160  
##                                        Mean   :2260.452  
##                                        3rd Qu.:3706.060  
##                                        Max.   :4631.430

Como se observa la variable cotizacion2 es un variable numérica, ya que la función summary nos da los estadísticos que corresponde a esa variable numérica.

Procedamos a realizar la gráfica correspóndiente usando la librería ggplot

library(ggplot2)

# Grafico de Barras
 ggplot(cot, aes(x=Moneda, y=cotizacion2)) + geom_bar(stat="identity")+
    coord_flip()

Capitulo 2

Análisis exploratorio de los datos

Medidas de tendencia central y medidas de dispersión:

Las medidas de tendencia central son medidas estadísticas que pretenden resumir en un solo valor a un conjunto de valores. Representan un centro en torno al cual se encuentra ubicado el conjunto de los datos. Las medidas de tendencia central más utilizadas son: media, mediana y moda.

Media

La media es el valor promedio de un conjunto de datos numéricos, calculada como la suma del conjunto de valores dividida entre el número total de valores. A continuación se muestra la fórmula de la media aritmética:

\[{\displaystyle \bar{x}=\frac{\sum_{i=1}^{n}\left(x_{i}\right)}{n}}\]

donde:

n es el número de datos.

xi es el dato i-ésimo.

En r studio existe

# Para realizar el cálculo de las medidas estadística usaremos el dataset de auto

auto<-read.csv("C:/Users/LENOVO/Desktop/Data Science con R Studio/Curso de R Studio/auto-mpg.csv")

# Cálculo de la media aritmética: creamos una función 
arithmetic.mean <- function(x) {sum(x)/length(x)}
# Calculemos la media de una de las variables
arithmetic.mean(auto$weight)
## [1] 2979.414

s studio trae por defecto esta mediads, para la media existe la función mean, veamos

mean(auto$weight)
## [1] 2979.414

En el ámbito de la estadística, la mediana (del latín mediānus ’del medio’1 ) representa el valor de la variable de posición central en un conjunto de datos ordenados. En r studio existe la función median para este cálculo

median(auto$weight)
## [1] 2822.5

Varianza:

La varianza es una medida de dispersión que representa la variabilidad de una serie de datos respecto a su media. Formalmente se calcula como la suma de los residuos al cuadrado divididos entre el total de observaciones.

# Creamos una función para el cálculo de la varianza
variance <- function (x)   sum((x-mean(x))^2)/(length(x)-1) 
variance(auto$weight)
## [1] 717416.3

Cuartiles, cuartiles, deciles y percentiles

Sabemos que la mediana divide a los datos en dos partes iguales, también tiene interés estudiar otros parámetros , llamados cuantiles, que dividen los datos de la distribución en función de otras cantidades. Los más importantes son los cuartiles, deciles y percentiles.

Cuartiles: son tres valores que divides la serie de datos en cuatro partes iguales. Se representan por Q1(cuartil primero), Q2 (cuartil segundo) y Q3 (cuartil tercero)

Deciles: Son nueve valores que dividen la serie de datos en 10 partes iguales: D1, D2, …, D9.

Percentiles: son 99 valores que dividen la serie de datos en 100 partes iguales: P1, P2, …, P99.

# cuantiles
quantile(auto$weight)
##      0%     25%     50%     75%    100% 
## 1613.00 2226.50 2822.50 3618.25 5140.00
# deciles, Misma función, pero variamos el parámetro prob
quantile(auto$weight, prob=seq(0, 1, length = 11))
##     0%    10%    20%    30%    40%    50%    60%    70%    80%    90%   100% 
## 1613.0 1987.5 2155.0 2315.0 2587.0 2822.5 3102.0 3427.5 3830.0 4265.5 5140.0
# percentiles
quantile(auto$weight, prob=seq(0, 1, length = 101))
##      0%      1%      2%      3%      4%      5%      6%      7%      8%      9% 
## 1613.00 1774.10 1802.50 1835.00 1853.40 1928.00 1946.50 1963.70 1972.00 1982.25 
##     10%     11%     12%     13%     14%     15%     16%     17%     18%     19% 
## 1987.50 2001.65 2031.00 2048.60 2068.50 2096.25 2118.00 2125.00 2130.00 2143.55 
##     20%     21%     22%     23%     24%     25%     26%     27%     28%     29% 
## 2155.00 2164.00 2189.10 2202.45 2219.20 2226.50 2245.30 2264.35 2278.40 2297.25 
##     30%     31%     32%     33%     34%     35%     36%     37%     38%     39% 
## 2315.00 2361.00 2379.60 2395.00 2408.00 2446.75 2489.80 2514.40 2544.70 2571.65 
##     40%     41%     42%     43%     44%     45%     46%     47%     48%     49% 
## 2587.00 2605.50 2634.10 2641.20 2670.00 2682.00 2713.70 2728.50 2762.60 2797.25 
##     50%     51%     52%     53%     54%     55%     56%     57%     58%     59% 
## 2822.50 2860.50 2884.00 2904.65 2930.00 2945.00 2961.00 2989.10 3020.40 3069.50 
##     60%     61%     62%     63%     64%     65%     66%     67%     68%     69% 
## 3102.00 3150.25 3171.10 3210.15 3235.40 3266.25 3292.20 3353.00 3380.40 3412.25 
##     70%     71%     72%     73%     74%     75%     76%     77%     78%     79% 
## 3427.50 3437.65 3462.60 3528.25 3572.80 3618.25 3649.80 3689.85 3734.50 3780.80 
##     80%     81%     82%     83%     84%     85%     86%     87%     88%     89% 
## 3830.00 3870.50 3900.70 3956.05 4044.40 4077.75 4098.60 4140.35 4165.40 4215.00 
##     90%     91%     92%     93%     94%     95%     96%     97%     98%     99% 
## 4265.50 4304.35 4348.80 4378.60 4424.10 4462.25 4501.40 4651.60 4728.70 4948.75 
##    100% 
## 5140.00

Asimetría y Curtosis

Las medidas de distribución nos permiten identificar la forma en que se separan o aglomeran los valores de acuerdo a su representación gráfica.

Asimetría: Esta medida nos permite identificar si los datos se distribuyen de forma uniforme alrededor del punto central (Media aritmética).

Curtosis: esta medida determina el grado de concentración que presentan los valores en la región central de la distribución.

Para realizar obtener estos valores utilizamos el paquete moments

library(moments)
skewness(auto$weight)
## [1] 0.5038141
# Cálculo de la curtosis
kurtosis((auto$weight))
## [1] 2.174459