install.packages("dplyr")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
install.packages("readxl")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
library(readxl)
install.packages("tidyverse")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
library(tidyverse)
## ── Attaching packages ─────────────────────────── tidyverse 1.2.1 ──
## ✔ ggplot2 3.1.1          ✔ readr   1.3.1     
## ✔ tibble  2.1.1          ✔ purrr   0.3.2.9000
## ✔ tidyr   0.8.3          ✔ stringr 1.4.0     
## ✔ ggplot2 3.1.1          ✔ forcats 0.4.0
## ── Conflicts ────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
install.packages("hrbrthemes")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
library(hrbrthemes)
## NOTE: Either Arial Narrow or Roboto Condensed fonts are required to use these themes.
##       Please use hrbrthemes::import_roboto_condensed() to install Roboto Condensed and
##       if Arial Narrow is not on your system, please see http://bit.ly/arialnarrow
library(scales)
## 
## Attaching package: 'scales'
## The following object is masked from 'package:purrr':
## 
##     discard
## The following object is masked from 'package:readr':
## 
##     col_factor
library(countrycode)
library(glue)
## 
## Attaching package: 'glue'
## The following object is masked from 'package:dplyr':
## 
##     collapse
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(crosstalk)
library(DT)
library(gganimate)
install.packages("htmlwidgets")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
library(widgetframe)
## Loading required package: htmlwidgets
install.packages("magrittr")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
library(magrittr)
## 
## Attaching package: 'magrittr'
## The following object is masked from 'package:purrr':
## 
##     set_names
## The following object is masked from 'package:tidyr':
## 
##     extract
install.packages("ggplot2")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
library(ggplot2)
install.packages("purr")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
## Warning: package 'purr' is not available (for R version 3.5.3)
install.packages("devtools")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
devtools::install_github("tidyverse/purrr")
## Skipping install of 'purrr' from a github remote, the SHA1 (25d84f7d) has not changed since last install.
##   Use `force = TRUE` to force installation
library(purrr)
install.packages("countrycode")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
library(countrycode)
install.packages("ggrepel")
## Installing package into '/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.5'
## (as 'lib' is unspecified)
library(ggrepel)

Por que automatizar en R?

1-Porque ayuda a simplificar el tiempo de trabajo en el analisis de datos y reportes. Si puede reducir el tiempo empleado en el procesamiento manual de datos y enfocar más el análisis y la información, eso solo puede ser algo bueno.

2-Permite a la persona o al equipo enfocarse en los problemas dificiles. Expande tus opciones de visualización de datos. El uso de un software de código abierto como R permitirá dibujar en una amplia gama de herramientas y bibliotecas de gráficos que no están disponibles en el software propietario. Por ejemplo, los informes HTML con el paquete rmarkdown pueden incluir gráficos interactivos, mapas y tablas que utilizan las últimas tecnologías web, más sobre esto más adelante.

3-Provee un analisis continuo y reproducible tambien un analisis repitivo.

4-Reduce errores; cuando su informe se basa en la entrada de datos manual y en una fórmula con referencias de celda codificadas de forma rígida, un número tipográfico o fuera de lugar puede llevar a resultados que están fuera de lugar. Automatizar el proceso con un script eliminará completamente la posibilidad de error humano.

Ahora bien es importante automatizar procesos en R pero antes debemos empezar por responder estas preguntas:

1-Cuando es posible automatizar?

Casi siempre es posible automatizar. El cuando lo establece la automatizacion de pruebas como una inversion.

2-Por donde empiezo a automatizar?

Para orientarse en este universo se recomienda empezar identificando tareas de prueba que sean aburridas, repetitivas y sin mucho valor aparente, pero que podrían ser determinantes en momentos muy puntuales o que siempre generan condiciones de fallo en sus sistemas actuales. Es solo un pequeño primer paso pero alivia el escozor.

Luego toca entrar en matices más elaborados, como frecuencia de cambio o criticidades desde negocio. Nuestro foco suele ser asegurar que no se retrocede en el producto, es decir, automatizar las pruebas de regresión funcional.

path <- "../../data/blog_data/gapminder_messy.xlsx"
messy <- file.path(wd,"gapminder_messy.xlsx")

Vamos a programar un proceso que: iterar sobre cada hoja en el archivo excel saque solo la sección de la tabla de datos (comenzando en la fila 5) Añadir una columna de año rellenada por el nombre de la hoja. Combine todas las tablas separadas en un solo marco de datos reordenar las columnas a nuestras especificaciones deseadas La reproducibilidad de este código proviene del hecho de que es independiente del número de hojas en nuestro archivo de Excel. Eso significa que cada vez que obtengamos un archivo actualizado con una nueva pestaña de datos, solo apuntamos el mismo código a este archivo y obtendremos un nuevo conjunto de datos que incluye estos nuevos datos. Cualquier cálculo futuro que obtengamos de los datos, como los últimos cambios de período a período, se derivará automáticamente de los últimos datos disponibles que acabamos de recibir.

combined_data <- 
  excel_sheets(messy) %>% 
  map_df(~ {
    read_excel(messy, sheet = .x, skip = 4, trim_ws = TRUE) %>% 
      mutate(year = as.integer(.x))
  }) %>% 
  select(country, year, everything())


head(combined_data)
## # A tibble: 6 x 5
##   country      year gdpPercap lifeExp      pop
##   <chr>       <int>     <dbl>   <dbl>    <dbl>
## 1 Afghanistan  2007      975.    43.8 31889923
## 2 Albania      2007     5937.    76.4  3600523
## 3 Algeria      2007     6223.    72.3 33333216
## 4 Angola       2007     4797.    42.7 12420476
## 5 Argentina    2007    12779.    75.3 40301927
## 6 Australia    2007    34435.    81.2 20434176
tail(combined_data)
## # A tibble: 6 x 5
##   country             year gdpPercap lifeExp      pop
##   <chr>              <int>     <dbl>   <dbl>    <dbl>
## 1 Venezuela           1952     7690.    55.1  5439568
## 2 Vietnam             1952      605.    40.4 26246839
## 3 West Bank and Gaza  1952     1516.    43.2  1030585
## 4 Yemen, Rep.         1952      782.    32.5  4963829
## 5 Zambia              1952     1147.    42.0  2672000
## 6 Zimbabwe            1952      407.    48.5  3080907

Parte de nuestro análisis incluirá el cálculo de estadísticas de resumen continentales, pero actualmente no tenemos una columna de continente en nuestro conjunto de datos. Agregar uno en Excel nos requeriría hacer nuestra propia tabla de búsqueda con un continente correspondiente para cada país único en el conjunto de datos y luego usar una función VLOOKUP. En R podemos hacer fácilmente esta parte del flujo de trabajo automatizado utilizando el paquete countrycode para traducir de un esquema de codificación geográfica a otro; en nuestro caso, obtener un nombre de continente basado en un nombre de país, así:

combined_data <- combined_data %>% 
  mutate(continent = countrycode(sourcevar = country, origin = "country.name", destination = "continent")) %>% 
  select(continent, everything())

head(combined_data)
## # A tibble: 6 x 6
##   continent country      year gdpPercap lifeExp      pop
##   <chr>     <chr>       <int>     <dbl>   <dbl>    <dbl>
## 1 Asia      Afghanistan  2007      975.    43.8 31889923
## 2 Europe    Albania      2007     5937.    76.4  3600523
## 3 Africa    Algeria      2007     6223.    72.3 33333216
## 4 Africa    Angola       2007     4797.    42.7 12420476
## 5 Americas  Argentina    2007    12779.    75.3 40301927
## 6 Oceania   Australia    2007    34435.    81.2 20434176
continent_summary <- 
  combined_data %>% 
  group_by(continent, year) %>% 
  summarise(gdpPercap = weighted.mean(gdpPercap, pop),
            lifeExp = weighted.mean(lifeExp, pop),
            pop = sum(pop)) %>% 
  ungroup() %>% 
  gather(metric, value, 3:5)

continent_summary
## # A tibble: 180 x 4
##    continent  year metric    value
##    <chr>     <int> <chr>     <dbl>
##  1 Africa     1952 gdpPercap 1311.
##  2 Africa     1957 gdpPercap 1445.
##  3 Africa     1962 gdpPercap 1541.
##  4 Africa     1967 gdpPercap 1775.
##  5 Africa     1972 gdpPercap 2063.
##  6 Africa     1977 gdpPercap 2245.
##  7 Africa     1982 gdpPercap 2295.
##  8 Africa     1987 gdpPercap 2181.
##  9 Africa     1992 gdpPercap 2072.
## 10 Africa     1997 gdpPercap 2099.
## # … with 170 more rows

Ahora tenemos un conjunto de datos consolidado con una variable de continente adicional codificada para cada país. Un caso común con el informe de datos sería producir informes distintos de múltiples subconjuntos de un solo conjunto de datos. Esto se hace fácil usando rmarkdown con la capacidad de suministrar un parámetro en la parte superior de la secuencia de comandos de su informe, que luego se puede usar como una variable en el código dentro del informe para alterar los resultados. Digamos en nuestro ejemplo que queremos producir por lotes un informe para cada continente. Si suministramos el nombre del continente para el que queremos construir el informe en la sección de parámetros de lo que se conoce como YAML en la parte superior del script del informe, así:

title: My Report output: html_document params: continent: Europe

Luego podemos usar ese parámetro para filtrar nuestro conjunto de datos consolidados a solo países que coincidan con el parámetro de continente y luego usar esos datos para todos los análisis posteriores.

filtered_data <- combined_data %>% 
  filter(continent == params$continent)

En un informe HTML, podemos usar gráficos interactivos vinculados para alentar a los usuarios a interactuar con los datos y explorar las ideas. Construyamos algunos gráficos para mostrar los últimos cambios porcentuales del período de las 3 métricas en el conjunto de datos. Primero hacemos los datos para calcular los cambios …

p_change <- filtered_data %>% 
  group_by(continent, country) %>% 
  arrange(year) %>% 
  mutate(gdpPercap_change = (gdpPercap - lag(gdpPercap)) / lag(gdpPercap),
         lifeExp_change = (lifeExp - lag(lifeExp)) / lag(lifeExp),
         pop_change = (pop - lag(pop)) / lag(pop))
         
latest_figs <- p_change %>% 
  filter(year == max(year)) %>%
  select(-year) %>% 
  arrange(country) %>% 
  ungroup()

La triste verdad es que la mayoría de los gerentes realmente aman los informes de Microsoft Office o PDF. Sin embargo, no se preocupe, porque con ggplot2 tenemos la mejor biblioteca de gráficos estáticos del mundo a nuestra disposición y obtener estos gráficos en un informe automatizado de Word, PowerPoint o PDF con rmarkdown es un paseo por el parque. La tabla a continuación combina las tres métricas de nuestros datos en una tabla, a la Hans Rosling (RIP), para nuestra última ola de datos. La posición de las anotaciones de país se automatizan con el paquete ggrepel y se calculan para repeler las etiquetas de texto superpuestas entre sí.

continent_summary <- 
  combined_data %>% 
  group_by(continent, year) %>% 
  summarise(gdpPercap = weighted.mean(gdpPercap, pop),
            lifeExp = weighted.mean(lifeExp, pop),
            pop = sum(pop)) %>% 
  ungroup() %>% 
  gather(metric, value, 3:5)