Creamos, con código, una carpeta llamada pruebas donde guardaremos los datos
3
Usamos la función download.file() para descargar los datos que hay en my_url. Los guardamos en la carpeta pruebas de nuestro proyecto. Concretamente en el fichero plazas_turisticas.csv
4
Hace exactamente lo mismo que 3, pero esta vez, hemos especificado el nombre de los dos argumentos de la función
Es bueno hacer el código modular (por si queremos cambiar las rutas en el futuro). Por eso, especificamos en my_ruta el sitio donde guardaremos los datos
2
Usamos curl::curl_download() para descargar el fichero. Es una función más moderna que download.file()
Importación de datos
La primera etapa de un análisis de datos consiste en cargar los datos en R (en la memoria de R, en el Global)
podemos usar/cargar datos de los paquetes
Muchos paquetes de R contienen datos que podemos usar
… intenta entender el siguiente chunk de código
#- cuando iniciamos R se cargan automáticamente un grupo de paquetes (R-base)print(.packages()) #- [🌶]imprimimos los nombres de los "currently attached packages"#- en uno de esos paquetes hay un conjunto de datos llamado "iris"iris #- llamamos a "iris"find("iris") #- [🌶] ¿donde está iris?str(iris) #- qué es iris?my_iris <- iris #- "hacemos una copia" de iris en el Globalfind("my_iris") #- ¿donde está my_iris?iris <-c(2, 4) #- creamos un vector llamado irisfind("iris") #- ¿donde está ahora iris?
Cuando carguemos/importemos esos datos tabulares en R …
Se almacenarán internamente en R como data.frames
RStudio permite cargar datos usando menús.
Usando menús (File > Import Dataset) se pueden cargar datos CSV, EXCEL, SPSS, SAS y STATA.
Se puede hacer con menús, pero nosotros usaremos código
(La razón es que queremos que nuestros análisis sean reproducibles)
Para importar (y exportar) datos utilizaremos código
Usaremos funciones, concretamente funciones del paquete rio que permite importar y exportar ficheros en casi cualquier formato.
Para importar datos en R usaremos la función rio::import()
Para exportar datos en R usaremos la función rio::export()
importando datos con rio::import()
La función rio::import()tiene varios argumentos, pero solo usaremos el primero.
Su primer argumento se llama file y su descripción dice que … el valor de file ha de ser: “A character string naming a file, URL, or single-file .zip or .tar archive”. WTF!!
Es decir, el valor de file ha de ser la ruta (de nuestro ordenador) donde están los datos que queremos importar
Bueno, … en realidad también podemos importar directamente desde un “url”
Tarea: importar a R datos que tenemos guardados en nuestro ordenador
#- en esta url hay un fichero de datos en formato .csvmy_url <-"https://raw.githubusercontent.com/perezp44/iris_data/master/data/iris.csv"curl::curl_download(url = my_url, destfile ="./pruebas/iris.csv")
here::here()devuelve la ruta al directorio de trabajo Como trabajamos con Rproject’s, entonces devuelve la ruta a la carpeta del Rproject en tú ordenador. Esto nos será útil cuando trabajemos con ficheros .qmd
Lo veremos más adelante en una extensión
Formatos de datos propios de R
R tiene 2 formatos de datos propios: .rda y .rds
Formatos de datos propios de R
Guardar datos en formatos como .csv o .xlsx es lo más habitual si quieres abrir estos datos en otros programas, pero …
… pero al grabar en estos formatos guardas los datos, PERO no guardas los metadatos!!!
R tiene 2 formatos de datos propios: .rda y .rds
Estos formatos sí guardan los metadatos
Formato .rds
Exportar datos a formato .rds
rio::export(x = iris, file ="./pruebas/iris.rds")
Extensión: dos formas alternativas de exportar a .rds (😱😱)
(Sí, en R se pueden hacer las cosas de muchas maneras!!! 🚨🚨)
saveRDS(iris, file ="./pruebas/iris.rds") #- con base-Rreadr::write_rds(iris, "./pruebas/iris.rds") #- con pkg "readr"
Importar datos en formato .rds
df <- rio::import(file ="./pruebas/iris.rds")
Extensión: dos formas alternativas de importar .rds
(Sí, en R se pueden hacer las cosas de muchas maneras!!! 🚨🚨)
my_iris_1 <-readRDS("./pruebas/iris.rds") #- con R-basemy_iris_2 <- readr::read_rds("./pruebas/iris.rds") #- tidyverse
Formato .RData (o .rda)
El formato .RData tiene la ventaja de que puedes guardar varios objetos a la vez
Para exportar datos a formato .rda
#- guardamos los objetos mtcars e iris en un fichero llamado "mtcars_and_iris.RData"save(mtcars, iris, file ="./pruebas/mtcars_and_iris.RData")
Para importar datos en formato .rda, tenemos que usar la función load()
load(file ="./pruebas/mtcars_and_iris.RData")
Extensión: Para importar .rdadesde la web hay que usar load(url())
#- hay que usar load(url())#- no funciona xq han borrado el archivodf <-load(url("http://gedemced.uab.cat/images/POP_ENC_AMB_2014.Rdata"))#- pero si aún así no funcionase, usa repmis::source_data()my_url <-"https://github.com/perezp44/LAU2boundaries4spain/blob/master/data/Provincias.rda?raw=true"df <-load(url(my_url)) #- no funcionadf <- repmis::source_data(my_url)
Acceder a datos a través de API’s
Hay muuuuuchas organizaciones que ofrecen datos a través de API’s y …
… en muchas ocasiones, hay un paquete de R para acceder fácilmente a ellos!!!
Eurostat
Eurostat es la oficina de estadística de la Unión Europea
El paquete eurostat permite acceder a las API’s de Eurostat para obtener datos
Por ejemplo aquí puedes ver una de las múltiples tablas de datos que ofrece Eurostat; concretamente la tabla Cultural employment by sex o con siglas “cult_emp_sex”
¿Importamos esa tabla a R con el paquete eurostat?
# install.packages("eurostat")library(eurostat)#- importamos los datos de la tabla "cult_emp_sex": "Cultural employment by sex"df <- eurostat::get_eurostat("cult_emp_sex")
Practica: importar datos de Eurostat
Podemos buscar un tema en Eurostat; por ejemplo aquí hay datos de “Employment and unemployment (LFS)”, aquí datos sobre “Population and social conditions” y aquí sobre “Crime and criminal justice”
Para mi es más cómodo buscar datos con el paquete eurostat. ¿Probamos?
library(eurostat)#- podemos buscar un "tema" con la f. search_eurostat()my_tema <-"employment"aa <- eurostat::search_eurostat(pattern = my_tema, type ="all") #- elegimos un dataset; por ejemplo "hlth_silc_17"my_table <-"hlth_silc_17"#- da información sobre la Base de datos que estas buscandoeurostat::label_eurostat_tables(my_table) #- importamos los datos de "my_table" con get_eurostat()df <- eurostat::get_eurostat(my_table, time_format ="raw", keepFlags =TRUE ) #- pedimos los descriptores/labels de las seriesdf_l <- eurostat::label_eurostat(df)
Permite acceder a una gran variedad de datos económicos. Aquí tienes información
library(quantmod) #- install.packages("quantmod")#- For stocks and shares, the yahoo source is used. facebook <-getSymbols(Symbols ='F', src ='yahoo', auto.assign =FALSE) barChart(facebook) #- For currencies and metals, the oanda source is used.tc_euro_dolar <-getSymbols(Symbols ='EUR/USD', src ='oanda', auto.assign =FALSE)#- For economics series, the FRED source is used. Japan_GDP <-getSymbols(Symbols ='JPNNGDP', src ='FRED', auto.assign =FALSE)
Algunos BONUS de I/O
Con lo que hemos visto hasta ahora nos apañamos, pero conviene ver alguna cosa más …
Bonus 1 (🌶🌶 … 🌶): exportar los datos de un df a un archivo .xlsxya existente
#- bonus: le añadimos un libro mas al archivo "./pruebas/iris.xlsx"rio::export(iris, "./pruebas/iris.xlsx") #- por si acaso lo hubiésemos borradorio::export(iris, "./pruebas/iris.xlsx", which ="iris_2")#- lo mismo pero poniendo los nombres de los argumentosrio::export(x = iris, file ="./pruebas/iris.xlsx", which ="iris_3")
Esta solución ya no funciona 😱 !!
Tendremos que usar nuevo paquete: openxlsx
#- tenemos que usar el pkg openxlsxlibrary(openxlsx) #- pak::pak("openxlsx")#- tenemos que crear un "Woorkbook" con la f. loadWorkbook()my_workbook <- openxlsx::loadWorkbook("./pruebas/iris.xlsx")#- ahora añadimos hojas/sheets al Woorkbookopenxlsx::addWorksheet(my_workbook, "iris_2")openxlsx::addWorksheet(my_workbook, "my_mtcars")#- ahora escribimos datos en las nuevas hojas/sheets q hemos creadoopenxlsx::writeData(my_workbook, sheet ="iris_2", x = iris)openxlsx::writeData(my_workbook, sheet ="my_mtcars", x = mtcars)#- exportamos/guardamos el archivo (con las nuevas sheets)openxlsx::saveWorkbook(my_workbook, "./pruebas/iris.xlsx", overwrite =TRUE)
Bonus 2 (🌶🌶🌶): exportar 2 df’s en un único archivo .xlsx
Seguimos usando el paquete rio, pero …
… los objetos que queremos exportar se incluyen dentro de la función list()
Bonus 3 (🌶🌶): importar una hoja/libro especifica de un archivo .xlsx
Seguimos usando el paquete rio, pero …
… tenemos que usar un nuevo argumento: sheet
iris_1 <- rio::import("./pruebas/my_iris_pinguinos.xlsx") #- solo importa el primer libropinguinos_1 <- rio::import("./pruebas/my_iris_pinguinos.xlsx", sheet =2)pinguinos_2 <- rio::import(file ="./pruebas/my_iris_pinguinos.xlsx", sheet ="my_pinguinos")
Bonus 4: (!!!! 😱 😱) importamos todos los libros de un archivo .xlsx
library(readxl) #- necesitamos la función readxl::excel_sheet()mys_sheets <- readxl::excel_sheets(here::here("pruebas", "my_iris_pinguinos.xlsx"))#- con base::lapply()my_dfs_list <-lapply(mys_sheets, readxl::read_excel,path = here::here("pruebas", "my_iris_pinguinos.xlsx"))#- con purrr::map()my_dfs_list <- purrr::map(mys_sheets, readxl::read_excel,path = here::here("pruebas", "my_iris_pinguinos.xlsx"))
Ok, pero ahora tenemos los 2 data.frames dentro de una lista ¿qué hacemos?
#- Extrayendo un data.frame de una lista: con [[]]my_iris <- my_dfs_list2[[1]]
Bonus 5: (!!!!!!) importamos todos archivos de datos de una carpeta concreta
#- importamos todos los archivos que hemos creado en "./pruebas/"library(purrr)my_carpeta <- here::here("pruebas")lista_de_archivos <- fs::dir_ls(my_carpeta) my_dfs_list_2 <-map(lista_de_archivos, rio::import)
Ya veremos, con un ejemplo, cómo podemos juntar todos los df’s en un único data.frame
Extensiones
Webscrapping [🌶🌶🌶 🌶🌶]
Webscrapping consiste en obtener datos directamente de páginas web, de su código html.
Webscrapping (ejemplo 1)
En esta página web hay una tabla con los pueblos más “altos” de Teruel
Para obtener esos datos en R, podemos usar el paquete rvest
library(rvest)library(tidyverse)my_url <-"https://es.wikipedia.org/wiki/Anexo:Municipios_de_la_provincia_de_Teruel"content <-read_html(my_url)body_table <- content %>%html_nodes('body') %>%html_nodes('table') %>%html_table(dec =",")#- solo hay una tablaTeruel <- body_table[[1]] #- estoy haciendo subsetting de una lista
digresión: es lo mismo un data.frame que una tibble [🌶🌶🌶]
Sí y no (!!!)
No son exactamente lo mismo, pero para nosotros son totalmente equivalentes. Podemos pensar que las tibbles son data.frame’s modernizados o tuneados
Las dos son estructuras de R para almacenar datos tabulares. Si quieres ver en qué se diferencian lee esto.
Veámoslo un poco:
typeof(iris)
[1] "list"
class(iris)
[1] "data.frame"
names(attributes(iris))
[1] "names" "class" "row.names"
Convertimos iris en tibble:
iris_2 <- tibble::as_tibble(iris)
typeof(iris_2)
[1] "list"
class(iris_2)
[1] "tbl_df" "tbl" "data.frame"
names(attributes(iris_2))
[1] "class" "row.names" "names"
Alguna funciones antiguas puede que no funcionen con tibbles. Si te pasa esto, tienes que usar as.data.frame(). Puedes leerlo aquí
seleccionando “manualmente” un archivo de datos
Este truco es chulo … pero no hay que hacerlo
my_data <- rio::import(file.choose())
No hay que hacerlo si queremos que nuestros análisis sean reproducibles
gestionando las rutas con here::here()
Problemas con las rutas “tradicionales”
Rutas absolutas son “frágiles”
C:\tu-usuario\tu-proyecto\datos\archivo.csv
No funcionarán en otras máquinas
Rutas relativas pueden ser ambiguas:
"./datos/archivo.csv" o "../scripts/codigo.R"
¿Relativas a qué? Depende de dónde ejecutes!!
Consecuencias:
Scripts no reproducibles.
“Error: No se puede encontrar el archivo”
En realidad, como nosotros trabajamos con Rstudio y con Rproject’s, de momento nos basta con utilizar rutas relativas, PERO, esto cambiará cuando trabajemos con archivos .qmd
Rutas con here::here()
Construye rutas absolutas, PERO estas rutas absolutas no se construyen a mano, sino cuando se ejecuta el código; por lo tanto, como trabajamos con Rproject’s, esas rutas absolutas funcionarán tanto si trabajamos con ficheros .R como con ficheros .qmd
Como nosotros trabajamos con Rproject’s, las rutas relativas que vayamos construyendo serán rutas relativas a la carpeta raíz de tu Rproject, y here::he() las convertirá en rutas absolutas. Por ejemplo:
Resulta que quiero saber que provincia tiene más municipios, así que vamos a ir al INE, concrétamente aquí. En esa página hay un fichero que nos permitirá contar el nº de municipios
rm(list =ls()) #- antes vamos a limpiar el Global env.my_url <-"https://www.ine.es/daco/daco42/codmun/codmun20/20codmun.xlsx"my_ruta_guardar <- here::here("pruebas", "20codmun.xlsx")curl::curl_download(my_url, my_ruta_guardar) #- lo guardo en discodf_1 <- rio::import(my_ruta_guardar) #- q pb tenemos?
Vamos a usar menús, pero que no nos vea Hadley!!!
Seguid la siguiente ruta de menús: File > Import Dataset > From Excel ...
Pegáis en la caja de texto el url y pincháis el botón update
df_2 <- readxl::read_xlsx(my_url, skip =1) #- no funciona. readxl solo lee del PCmy_ruta_guardar <- here::here("pruebas", "20codmun.xlsx")df_2 <- readxl::read_xlsx(my_ruta_guardar, skip =1)
#- script para bajar la relación de municipios INE a 1 de enero de 2021 url_descarga <-"https://www.ine.es/daco/daco42/codmun/diccionario21.xlsx"nombre_fichero <-"diccionario21.xlsx"#- obtengo el nombre del archivonombre_fichero <- stringr::str_extract(url_descarga, "([^\\/]+$)")#- añado la fecha de descarga al nombre de archivoextension <- stringr::str_extract(url_descarga, "([^\\.]+$)")nombre <- stringr::str_remove(nombre_fichero, paste0(".",extension))nombre_fichero <-paste0(nombre , "_", Sys.Date(), ".", extension)#- lo guardomy_ruta <- here::here("pruebas", nombre_fichero) #- ruta para guardar el ficherocurl::curl_download(url = url_descarga, destfile = my_ruta)
Importo el fichero a la memoria de R
df <- readxl::read_xlsx(path = my_ruta, skip =1)#- la verdad es que skip = 1 también hubiese funcionado con el paquete `rio` #- ya que `rio` llama a `readxl`
seguimos con el ejemplo
aparecen muchas cosas/funciones que veremos más adelante [🌶🌶🌶🌶]
#- fusiono los 2 ficheros (lo veremos!!)df_ok <-left_join(df_muni, codigos_prov)
Borro la carpeta (para dejar el Rproject limpio)
fs::dir_delete("pruebas") #- [🌶] borro la carpeta pruebas
Más extensiones
funciones, paquetes, etc …
quizás 🤔 … lo más importante del curso sea entender bien cómo “funciona” una función
Sí, es muy importante entender qué es y cómo usar una función
De hecho, todo lo que ocurre, todo lo que pasa en R es porque has llamado a una función
Again: si algo ocurre en R es porque has hecho una llamada a una función, una “function call”
To understand computations in R, two slogans are helpful:
- Everything that exists is an object.
- Everything that happens is a function call.
— John Chambers (creador de S)
Usar funciones permite:
reutilizar código y organizar los programas de manera más eficiente
facilita la depuración de errores y el mantenimiento
mejora la legibilidad del código
¿qué es una función?
Una función no es más un trozo de código R, unas instrucciones de R, a las que les hemos puesto/asignado un nombre; entonces, cuando invoquemos ese nombre, esa función, se ejecutarán esas lineas de código y nos devolverá un resultado
(Como no creo que lo anterior os diga mucho, vamos a usar 5 minutos para crear nuestra primera función)
supongo que ahora se entiende mejor qué es una función?
Recuerda, no es más que un trozo de instrucciones/código en R que alguien ha creado para ser usada
Para usarlas, solo tenemos que invocar su nombre y dar valores a sus argumentos
seguimos con las funciones
Vamos a profundizar en nuestro conocimiento de las funciones usando una: usando la función sqrt()
Resulta que alguien se ha preocupado de construir una función llamada sqrt() que sirve para calcular raíces cuadradas. Vamos a usarla!! Cómo??
ejemplo: cómo aprender a usar sqrt()
Para usar una función puedes buscar en internete, pedir ayuda a una IA, etc … pero creo que mejor si usas la ayuda oficial de la función
Sí cada función de R tiene una página de ayuda interna.
Para abrir la ayuda oficial hay que situar el cursor en el nombre de la función y pinchar en F1F1
También puedes hacer: help(sqrt)
ayuda oficial de sqrt()
La ayuda oficial parece muy complicada, pero hay que aprender a leer las ayudas de las funciones. Es es MUY IMPORTANTE!!!! si quieres aprender a manejarte con R.
vamos a usar sqrt()para aprender cómo usar funciones
Tarea: ejecuta estas instrucciones e intenta entender que ocurre
sqrt(9)sqrt(9, 4) #- no funciona ¿por qué? ¿cuantos argumentos tiene la f. sqrt()?sqrt("9") #- no funciona, ¿por qué? ¿Cómo, de que tipo, ha de ser el argumento?
… más detalles
En realidad, cuando vamos a usar una función, cada argumento de la función tiene 2 elementos: el nombre del argumento y un valor para el argumento
El nombre de la función sqrt() es sqrt, ok, pero ¿cuales son sus argumentos? La ayuda nos dice que sólo tiene un argumento, cuyo nombre es x ; además, el valor del argumento debe ser numérico
sqrt(9) #- en realidad "no hace falta" poner el nombre del argumentosqrt(x =9) #- sqrt(x =4)
hay que diferenciar el nombre y el valor del argumento de una función
Calcula el logaritmo de 1000 en base 10. Para ello tenéis que usar la función log()
Cómo no sabemos cómo se usa, no sabemos cómo es su sintaxis, no sabemos cuales son sus argumentos, nos va a tocar mirar la ayuda de la función
log(1000) no va a funcionar. ¿Por qué? para saberlo tendrás que mirar la ayuda de la función log()
Esto no funciona:
log(1000) #- como no especificamos el valor del argumento "base",#- R lo fija a su valor x defecto; es decir, base = exp(1) #- así que estamos tomando logaritmos naturales
Varias soluciones:
log(x =1000, base =10) #- GOODlog(1000, base =10) #- es equivalentelog(x =1000, 10) #- es equivalentelog(1000, 10) #- es equivalentelog(1000, bas =10) #- funciona, pero ... mejor no hacerlo
¿Por qué no podemos usar la expresión de abajo?
log(10, 1000)
¿Funcionará?
log(base =10, 1000)
… lo ultimísimo sobre funciones
¿Qué hacen los siguientes chunks?
add1 <-function(my_number) { my_number +1}
my_suma_3a <-function(n1 , n2, n3){ n1 + n2 + n3}#- vamos a usar nuestra funciónmy_suma_3a(2) #- xq no funciona?