diff --git a/01-rstudio-intro.md b/01-rstudio-intro.md new file mode 100644 index 00000000..c97b30bf --- /dev/null +++ b/01-rstudio-intro.md @@ -0,0 +1,779 @@ +--- +title: Introducción a R y RStudio +teaching: 45 +exercises: 10 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Describir el propósito y el uso de cada panel del RStudio IDE +- Ubicar botones y opciones en RStudio IDE +- Definir una variable +- Asignar un dato a una variable +- Administrar un espacio de trabajo en una sesión R interactiva +- Usar operadores matemáticos y de comparación +- Llamar funciones +- Gestionar paquetes + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo orientarse en RStudio? +- ¿Cómo interactuar con R? +- ¿Cómo administrar tu entorno? +- ¿Cómo instalar paquetes? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +## Motivación + +La ciencia es un proceso de varios pasos: una vez que hayas diseñado un experimento y recopilado datos, ¡comienza la verdadera diversión! +Esta lección te enseñará cómo comenzar este proceso usando R y RStudio. Comenzaremos con datos brutos, realizaremos análisis exploratorios +y aprenderemos a trazar gráficamente los resultados. Este ejemplo comienza con un conjunto de datos de [gapminder.org](https://www.gapminder.org) +que contiene información sobre la población de muchos países a lo largo del tiempo. ¿Puedes leer estos datos en R? ¿Puedes hacer un gráfico de +la población de Senegal? ¿Puedes calcular el ingreso promedio de los países del continente asiático? Al final de estas lecciones, +¡podrás hacer cosas como graficar datos de poblaciones de estos países en menos de un minuto! + +## Antes de empezar el taller + +Asegúrate de tener instalada la última versión de R y RStudio en tu máquina. Esto es importante, ya que algunos paquetes utilizados en el +taller pueden no instalarse correctamente (o no funcionar) si R no está actualizado. + +[Descarga e instala la última versión de R aquí](https://www.r-project.org/), +[descarga e instala RStudio aquí](https://www.rstudio.com/) + +## Introducción a RStudio + +Bienvenido a la parte R del taller de Software Carpentry. + +A lo largo de esta lección, vamos a enseñarte algunos de los fundamentos del lenguaje R, así como algunas buenas prácticas para organizar el +código de proyectos científicos que harán tu vida más fácil. + +Usaremos RStudio: un entorno de desarrollo integrado y gratuito de código abierto. RStudio proporciona un editor incorporado, funciona en todas +las plataformas (incluso en servidores) y ofrece muchas ventajas, como la integración de control de versiones y gestión de proyectos. + +**Diseño básico** + +Cuando abres por primera vez el RStudio, serás recibido por tres paneles: + +- La consola interactiva de R (a la izquierda) +- Ambiente/Historial (en la esquina superior derecha) +- Archivos/Gráficos/Paquetes/Ayuda/Visor (abajo a la derecha) + +![](fig/01-rstudio.png){alt='RStudio layout'} + +Si abres archivos, como los scripts R, también se abrirá un panel de editor en la esquina superior izquierda. + +![](fig/01-rstudio-script.png){alt='RStudio layout with .R file open'} + +## Flujo de trabajo dentro de RStudio + +Hay dos formas principales en que uno puede trabajar dentro de RStudio. + +1. Probar y jugar dentro de la consola interactiva de R y luego copiar el código en un archivo .R para ejecutarlo más tarde. + - Esto funciona bien cuando se hacen pequeñas pruebas y/o se está comenzando. + - Rápidamente se vuelve laborioso. +2. Comienza a escribir un archivo en .R y usa las teclas de acceso directo de RStudio para ejecutar la línea actual, las líneas seleccionadas o modificadas en la consola interactiva. + - Esta es una buena forma de comenzar; todo tu código estará guardado para después. + - Podrás ejecutar el archivo que quieres desde RStudio o mediante la función `source ()` de R. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Ejecutando segmentos/secciones de tu código + +RStudio ofrece gran flexibilidad para ejecutar código desde dentro de la ventana del editor +Hay botones, opciones de menú y atajos de teclado. Para ejecutar la línea actual, puedes + +1. hacer clic en el botón `Run` arriba en el panel del Editor, o 2. Seleccionar "Run Lines" desde el menú + "Code", o 3. Presionar Ctrl-Enter en Windows o Linux o Command-Enter en OS X. (Este atajo también se + puede hacer colocando el mouse sobre el botón). Para ejecutar un bloque de código, selecciónalo y luego + pulsa `Run`. Si has modificado una línea de código dentro de un bloque que acabas de ejecutar, + no es necesario re-seleccionar el bloque y `Run`, puedes usar el botón + `Re-run the previous region`. Esto ejecutará el bloque de código anterior, incluidas las modificaciones que + hayas realizado. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Introducción a R + +Gran parte de tu tiempo en R lo gastarás en la consola interactiva de R. Aquí es donde ejecutarás todo tu código, +y puede ser un entorno útil para probar ideas antes de guardarlas en un script R. La consola en RStudio es la misma que +obtendrías si escribieras `R` en la terminal de shell/linea de comandos. + +Lo primero que verás en la sesión interactiva de R es un montón de información, seguido por un ">" y un cursor parpadeante. +Esto es similar al entorno de la terminal de shell que aprendiste durante las lecciones de shell: R opera con la misma idea +de "leer, evaluar, mostrar" (tú escribes comandos, R intenta ejecutarlos y luego devuelve un resultado). + +## Usando R como una calculadora + +Lo más simple que podrías hacer con R es aritmética: + + +```r +1 + 100 +``` + +```{.output} +[1] 101 +``` + +R te mostrará la respuesta, precedido de un "[1]". No te preocupes por esto por ahora, lo explicaremos más adelante. Por ahora piensa en eso como parte de la salida. + +Al igual que bash, si escribes un comando incompleto R esperará a que lo completes: + +```r +> 1 + +``` + +```output ++ +``` + +Cada vez que presionas Enter y R te muestra un "+" en lugar de ">", significa que está esperando que completes el comando. Si deseas cancelar un comando, simplemente presiona "Esc" y RStudio te devolverá el ">" **prompt**. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Cancelando comandos + +Si usas R desde la línea de comandos en lugar de estar dentro de RStudio, +debes usar `Ctrl + C` en lugar de` Esc` para cancelar el comando. +¡Esto se aplica también a los usuarios de Mac! + +La cancelación de un comando no sólo es útil para matar comandos incompletos: +también puedes usarlo para decirle a R que deje de ejecutar el código (por ejemplo, si tarda +mucho más de lo que esperabas), o para deshacerte del código que estás escribiendo actualmente. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Cuando usas R como calculadora, el orden de las operaciones es el mismo que has aprendido en la escuela. + +De mayor a menor precedencia: + +- Paréntesis: `(`, `)` +- Exponente: `^` o `**` +- División: `/` +- Multiplicación: `*` +- Suma: `+` +- Resta: `-` + + +```r +3 + 5 * 2 +``` + +```{.output} +[1] 13 +``` + +Usa paréntesis para agrupar las operaciones a fin de forzar el orden de la evaluación o para aclarar lo que deseas hacer. + + +```r +(3 + 5) * 2 +``` + +```{.output} +[1] 16 +``` + +Esto puede ser difícil de manejar cuando no es necesario, pero aclara tus intenciones. +Recuerda que otros pueden leer tu código. + + +```r +(3 + (5 * (2 ^ 2))) # difícil de leer +3 + 5 * 2 ^ 2 # claro, si recuerdas las reglas +3 + 5 * (2 ^ 2) # si olvidas algunas reglas, esto podría ayudar +``` + +El texto después de cada línea de código se llama "comentario". Todo lo que sigue después del símbolo hash (o numeral) `#` es ignorado por R cuando se ejecuta el código. + +Los números pequeños o grandes tienen una notación científica: + + +```r +2/10000 +``` + +```{.output} +[1] 2e-04 +``` + +Es la abreviatura de "multiplicado por `10 ^ XX` ". Entonces `2e-4` es la abreviatura de `2 * 10^(-4)`. + +Tú también puedes escribir números en notación científica: + + +```r +5e3 # nota la falta del signo menos aquí +``` + +```{.output} +[1] 5000 +``` + +## Funciones matemáticas + +R tiene muchas funciones matemáticas integradas. Para llamar a una función, simplemente escribimos su nombre seguido de paréntesis ( ). +Todo lo que escribas dentro de los paréntesis se llaman argumentos de la función: + + +```r +sin(1) # función trigonométrica +``` + +```{.output} +[1] 0.841471 +``` + + +```r +log(1) # logaritmo natural +``` + +```{.output} +[1] 0 +``` + + +```r +log10(10) # logaritmo en base-10 +``` + +```{.output} +[1] 1 +``` + + +```r +exp(0.5) # e^(1/2) +``` + +```{.output} +[1] 1.648721 +``` + +No te preocupes si no recuerdas todas las funciones en R. Simplemente puedes buscarlas en Google, +o si puedes recordar el comienzo del nombre de la función, puedes usar el tabulador para completar su nombre en RStudio. + +Esta es una de las ventajas que RStudio tiene sobre R, tiene capacidades de autocompletado que te permiten buscar funciones, sus argumentos y los valores que toman más fácilmente. + +Escribir un `?` antes del nombre de un comando abrirá la página de ayuda para ese comando. Además de proporcionar una +descripción detallada del comando y cómo funciona, al desplazarse hacia la parte inferior de la página de ayuda generalmente +se mostrarán ejemplos que ilustran el uso del comando. Veremos un ejemplo más adelante. +Puedes consultar también [las guías rápidas](https://raw.githubusercontent.com/rstudio/cheatsheets/master/translations/spanish/introduccion-a-r.pdf) +disponibles en el sitio de RStudio. + +## Comparando + +Podemos realizar comparaciones en R: + + +```r +1 == 1 # igualdad (observa dos signos iguales, se lee como "es igual a") +``` + +```{.output} +[1] TRUE +``` + + +```r +1 != 2 # desigualdad (leída como "no es igual a") +``` + +```{.output} +[1] TRUE +``` + + +```r +1 < 2 # menor que +``` + +```{.output} +[1] TRUE +``` + + +```r +1 <= 1 # menor o igual que +``` + +```{.output} +[1] TRUE +``` + + +```r +1 > 0 # mayor que +``` + +```{.output} +[1] TRUE +``` + + +```r +1 >= -9 # mayor o igual que +``` + +```{.output} +[1] TRUE +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Comparando números + +Una advertencia sobre la comparación de números: +nunca debes usar `==` para comparar dos números a menos que +sean enteros (**integer** es un tipo de datos que +específica números enteros). + +Las computadoras sólo pueden representar números decimales con +un cierto grado de precisión, así que dos números que parecen iguales +cuando se muestran por R, pueden tener diferentes representaciones +subyacentes y por lo tanto ser diferentes por un pequeño margen de error +(llamado tolerancia numérica de la máquina). + +En su lugar, debes usar la función `all.equal`. + +Lectura adicional: [http://floating-point-gui.de/](https://floating-point-gui.de/) + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Variables y asignaciones + +Podemos almacenar valores en variables usando el operador de asignación `<-`. Veamos un ejemplo: + + +```r +x <- 1/40 +``` + +Observa que la asignación no muestra el valor. En cambio, lo almacena para más adelante en algo llamado **variable**. `x` ahora contiene el **valor** `0.025`: + + +```r +x +``` + +```{.output} +[1] 0.025 +``` + +Más precisamente, el valor almacenado es una *aproximación decimal* de esta fracción, llamado [número de coma flotante o **floating point**](https://en.wikipedia.org/wiki/Floating_point). + +Busca la pestaña `Environment` en uno de los paneles de RStudio, y verás que `x` y su valor han aparecido. Nuestra variable `x` se puede usar en lugar de un número en cualquier cálculo que espere un número: + + +```r +log(x) +``` + +```{.output} +[1] -3.688879 +``` + +Ten en cuenta que las variables pueden reasignarse, es decir, puedes cambiar el valor almacenado en la variable: + + +```r +x <- 100 +``` + +`x` tenía el valor `0.025` y ahora tiene el valor `100`. + +También, los valores de asignación pueden contener la variable asignada: + + +```r +x <- x + 1 # observa cómo RStudio actualiza la descripción de x en la pestaña superior derecha +y <- x * 2 +``` + +El lado derecho de la asignación puede ser cualquier expresión de R válida. +La expresión del lado derecho *se evalúa por completo* antes de que se realice la asignación. + +Los nombres de las variables pueden contener letras, números, guiones bajos y puntos. No pueden comenzar con un número ni contener espacios en absoluto. Diferentes personas usan diferentes convenciones para nombres largos de variables, estos incluyen + +- puntos.entre.palabras +- guiones\_bajos\_entre\_palabras +- MayúsculasMinúsculasParaSepararPalabras + +Lo que uses depende de ti, pero **sé consistente**. + +También es posible utilizar el operador `=` para la asignación: + + +```r +x = 1/40 +``` + +Esta forma es menos común entre los usuarios R. Lo más importante es +**ser consistente** con el operador que usas. Ocasionalmente hay lugares +donde es menos confuso usar `<-` que `=`, y es el símbolo más común usado en la comunidad. +Entonces la recomendación es usar `<-`. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +De los siguientes ejemplos, ¿Cuáles son nombres de variables válidas en R? + + +```r +min_height +max.height +_age +.mass +MaxLength +min-length +2widths +celsius2kelvin +``` + +::::::::::::::: solution + +## Solución al desafío 1 + +Los siguientes nombres de variables son válidos en R: + + +```r +min_height +max.height +MaxLength +celsius2kelvin +``` + +El punto al inicio crea una variable oculta: + + +```r +.mass +``` + +Los siguientes no son nombres de variables válidos en R: + + +```r +_age +min-length +2widths +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Vectorización + +Es muy importante tener en cuenta que R es *vectorizado*, lo que significa que las variables y funciones pueden tener vectores como valores y R puede operar en vectores completos a la vez. +En contraste con los conceptos de vectores de física y matemáticas, un vector en R describe un conjunto de valores del +mismo tipo de datos en un cierto orden. Por ejemplo: + + +```r +1:5 +``` + +```{.output} +[1] 1 2 3 4 5 +``` + +```r +2^(1:5) +``` + +```{.output} +[1] 2 4 8 16 32 +``` + +```r +x <- 1:5 +2^x +``` + +```{.output} +[1] 2 4 8 16 32 +``` + +Esto es increíblemente poderoso; discutiremos esto en una próxima lección. + +## Administrando tu entorno + +Hay algunos comandos útiles que puedes usar para interactuar con la sesión de R. + +`ls` listará todas las variables y funciones almacenadas en el entorno global +(tu sesión de trabajo en R): + + +```r +ls() +``` + +```{.output} +[1] "x" "y" +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: ocultando objetos + +Al igual que en el shell, `ls` oculta por defecto cualquier variable o función que comience +con un ".". Para listar todos los objetos, escribe `ls(all.names = TRUE)` + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Ten en cuenta que no se dió ningún argumento a `ls`, pero sí se necesita poner los paréntesis +para decirle a R que llame a la función. + +Si escribimos `ls` nada más, ¡R mostrará el código fuente de esa función! + + +```r +ls +``` + +```{.output} +function (name, pos = -1L, envir = as.environment(pos), all.names = FALSE, + pattern, sorted = TRUE) +{ + if (!missing(name)) { + pos <- tryCatch(name, error = function(e) e) + if (inherits(pos, "error")) { + name <- substitute(name) + if (!is.character(name)) + name <- deparse(name) + warning(gettextf("%s converted to character string", + sQuote(name)), domain = NA) + pos <- name + } + } + all.names <- .Internal(ls(envir, all.names, sorted)) + if (!missing(pattern)) { + if ((ll <- length(grep("[", pattern, fixed = TRUE))) && + ll != length(grep("]", pattern, fixed = TRUE))) { + if (pattern == "[") { + pattern <- "\\[" + warning("replaced regular expression pattern '[' by '\\\\['") + } + else if (length(grep("[^\\\\]\\[<-", pattern))) { + pattern <- sub("\\[<-", "\\\\\\[<-", pattern) + warning("replaced '[<-' by '\\\\[<-' in regular expression pattern") + } + } + grep(pattern, all.names, value = TRUE) + } + else all.names +} + + +``` + +Puedes usar `rm` para eliminar objetos que ya no necesitas: + + +```r +rm(x) +``` + +Si tienes muchas cosas en tu entorno y deseas borrarlas todas, +puedes pasar los resultados de `ls` y mandarlos a la función `rm`: + + +```r +rm(list = ls()) +``` + +En este caso, hemos combinado los dos. Al igual que el orden de las operaciones, todo lo que se encuentre dentro de los paréntesis más internos se evalúa primero, y así sucesivamente. + +En este caso, hemos especificado que los resultados de `ls` se deben usar para el argumento `list` y luego remover la lista con `rm`. Cuando asignes valores a argumentos por su nombre, *debes* usar el operador `=`. + +Si, en cambio, usamos `<-`, habrá efectos secundarios no deseados, o puedes recibir un mensaje de error: + + +```r +rm(list <- ls()) +``` + +```{.error} +Error in rm(list <- ls()): ... must contain names or character strings +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Advertencias vs. Errores + +¡Presta atención cuando R hace algo inesperado! Los errores, como el anterior, +se lanzan cuando R no puede proceder a un cálculo. Por otro lado, las advertencias +generalmente significan que la función se ha ejecutado, pero probablemente +no funcionó como se esperaba. + +En ambos casos, el mensaje que muestra R usualmente te da pistas sobre cómo +solucionar el problema. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Paquetes en R + +Es posible agregar funciones a R escribiendo un paquete u obteniendo un paquete escrito +por otra persona. Hay más de 10.000 paquetes disponibles en CRAN (la red completa de archivos R). +R y RStudio tienen funcionalidad para administrar paquetes: + +- Puedes ver qué paquetes están instalados escribiendo `installed.packages()` +- Puedes instalar paquetes escribiendo `install.packages("nombre_de_paquete")` +- Puedes actualizar los paquetes instalados escribiendo `update.packages()` +- Puedes eliminar un paquete con `remove.packages("nombre_de_paquete")` +- Puedes hacer que un paquete esté disponible para su uso con `library(nombre_de_paquete)` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +¿Cuál será el valor de cada variable después de cada comando en el siguiente programa? + + +```r +mass <- 47.5 +age <- 122 +mass <- mass * 2.3 +age <- age - 20 +``` + +::::::::::::::: solution + +## Solución al desafío 2 + + +```r +mass <- 47.5 +``` + +Esto dará un valor de 47.5 para la variable mass + + +```r +age <- 122 +``` + +Esto dará un valor de 122 para la variable age + + +```r +mass <- mass * 2.3 +``` + +Multiplica el valor existente en mass 47.5 por 2.3 para dar un nuevo valor +109\.25 a la variable mass. + + +```r +age <- age - 20 +``` + +Resta 20 del valor existente de 122 para obtener un nuevo valor +de 102 para la variable age. + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +Ejecuta el código del desafío anterior y escribe un comando para comparar la variable `mass` con `age`. +¿Es la variable `mass` más grande que `age`? + +::::::::::::::: solution + +## Solución del desafío 3 + +Una forma de responder esta pregunta en R es usar `>` para hacer lo siguiente: + + +```r +mass > age +``` + +```{.output} +[1] TRUE +``` + +Esto debería dar un valor booleano `TRUE` ya que 109.25 es mayor que 102. + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 4 + +Limpia tu entorno de trabajo borrando las variables de `mass` y `age`. + +::::::::::::::: solution + +## Solución al desafío 4 + +Podemos usar el comando `rm` para realizar esta tarea: + + +```r +rm(age, mass) +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 5 + +Instala los siguientes paquetes: `ggplot2`, `plyr`, `gapminder`. + +::::::::::::::: solution + +## Solución al desafío 5 + +Puedes utilizar el comando `install.packages()` para instalar los paquetes requeridos. + + +```r +install.packages("ggplot2") +install.packages("plyr") +install.packages("gapminder") +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Usa RStudio para escribir y correr programas en R. +- R tiene operadores aritméticos y funciones matemáticas usuales. +- Utilizar `<-` para asignar valores a variables. +- Utilizar `ls()` para listar las variables en el programa. +- Utilizar `rm()` para eliminar objetos en el programa. +- Utilizar `install.packages()` para instalar paquetes (libraries). + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/02-project-intro.md b/02-project-intro.md new file mode 100644 index 00000000..f62a74c3 --- /dev/null +++ b/02-project-intro.md @@ -0,0 +1,275 @@ +--- +title: Gestión de proyectos con RStudio +teaching: 20 +exercises: 10 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Crear proyectos independientes en RStudio + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo gestionar mis proyectos en R? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +## Introducción + +El proceso científico es naturalmente incremental, y la vida de muchos proyectos comienza como notas aleatorias, algún código, luego un manuscrito, y +eventualmente todo está mezclado. + + + + +La mayoría de la gente tiende a organizar sus proyectos de esta manera: + +![](fig/bad_layout.png) + +Hay muchas razones de por qué debemos **siempre** evitar esto: + +1. Es realmente difícil saber cuál versión de tus datos es + la original y cuál es la modificada. +2. Es muy complicado porque se mezclan archivos con varias + extensiones juntas. +3. Probablemente te lleve mucho tiempo encontrar realmente + cosas, y relacionar las figuras correctas con el código exacto + que ha sido utilizado para generarlas. + +Un buen diseño del proyecto finalmente hará tu vida más fácil: + +- Ayudará a garantizar la integridad de tus datos. +- Hace que sea más simple compartir tu código con alguien más + (un compañero de laboratorio, colaborador o supervisor). +- Permite cargar fácilmente tu código junto con el envío de tu manuscrito. +- Hace que sea más fácil retomar un proyecto después de un descanso. + +## Una posible solución + +Afortunadamente hay herramientas y paquetes que pueden ayudarte a gestionar tu trabajo con efectividad. + +Uno de los aspectos más poderosos y útiles de RStudio es su funcionalidad de gestión de proyectos. Lo utilizaremos hoy para crear un proyecto autocontenido y reproducible. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío: Creando un proyecto autocontenido + +Vamos a crear un proyecto en RStudio: + +1. Hacer clic en el menú "File", luego en "New Project". +2. Hacer clic en "New Directory". +3. Hacer clic en "Empty Project". +4. Introducir el nombre del directorio para guardar tu proyecto, por ejemplo: "my\_project". +5. Si está disponible, seleccionar la casilla de verificación "Create a git repository." +6. Hacer clic en el botón "Create Project". + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Ahora cuando inicies R en este directorio de proyectos, o abras este proyecto con RStudio, todo nuestro trabajo estará completamente autocontenido en este directorio. + +## Buenas prácticas para la organización del proyecto + +Aunque no existe una "mejor" forma de diseñar un proyecto, existen algunos principios +generales que deben cumplirse para facilitar su gestión: + +### Tratar los datos como de sólo lectura + +Este es probablemente el objetivo más importante al configurar un proyecto. Los datos +suelen consumir mucho tiempo y/o ser costosos de recolectar. Trabajar con ellos en un formato en el que pueden ser modificados (por ejemplo, en Excel) significa que nunca estás seguro de donde provienen, o cómo han sido modificados desde su recolección. +Por lo tanto, es una buena idea manejar tus datos como de "sólo lectura". + +### Limpieza de datos + +En muchos casos tus datos estarán "sucios" y necesitarán un preprocesamiento significativo +para obtener un formato R (o cualquier otro lenguaje de programación) que te resulte útil. Esta +tarea es algunas veces llamada **"data munging"**. Es útil almacenar estos **scripts** en una carpeta separada y crear una segunda carpeta de datos de "sólo lectura" para contener los **datasets** "limpios". + +### Tratar la salida generada como disponible + +Todo lo generado por tus **scripts** debe tratarse como descartable: todo debería +poder regenerarse a partir de tus **scripts**. + +Hay muchas diferentes maneras de gestionar esta salida. Es útil +tener una carpeta de salida con diferentes subdirectorios para cada análisis +por separado. Esto hace que sea más fácil después, ya que muchos de nuestros análisis son exploratorios +y no terminan siendo utilizados en el proyecto final, y algunos de los análisis se comparten entre proyectos. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Tip: Good Enough Practices for Scientific Computing + +[Good Enough Practices for Scientific Computing](https://github.com/swcarpentry/good-enough-practices-in-scientific-computing/blob/gh-pages/good-enough-practices-for-scientific-computing.pdf) brinda las siguientes recomendaciones para la organización de proyectos: + +1. Coloque cada proyecto en su propio directorio, el cual lleva el nombre del proyecto. +2. Coloque documentos de texto asociados con proyecto en el directorio `doc`. +3. Coloque los datos sin procesar y los metadatos en el directorio `data`, y archivos generados durante la limpieza y análisis en el directorio `results` . +4. Coloque los **scripts** fuente del proyecto y los programas en el directorio `src`, y programas traídos de otra parte o compilados localmente en el directorio `bin`. +5. Nombre todos archivos de tal manera que reflejen su contenido o función. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::::: callout + +## Tip: ProjectTemplate - una posible solución + +Una manera de automatizar la gestión de un proyecto es instalar el paquete `ProjectTemplate`. +Este paquete configurará una estructura de directorios ideal para la gestión de proyectos. +Esto es muy útil ya que te permite tener tu **pipeline/workflow** de análisis organizado y estructurado. +Junto con la funcionalidad predeterminada del proyecto RStudio y Git, podrás realizar el seguimiento de tu +trabajo y compartirlo con colaboradores. + +1. Instala `ProjectTemplate`. +2. Carga la librería. +3. Inicializa el proyecto: + + +```r +install.packages("ProjectTemplate") +library("ProjectTemplate") +create.project("../my_project", merge.strategy = "allow.non.conflict") +``` + +Para más información de ProjectTemplate y su functionalidad visita la +página [ProjectTemplate](https://projecttemplate.net/index.html). + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +### Separar la definición de funciones y la aplicación + +Una de las maneras más efectivas de trabajar con R es comenzar escribiendo el código que deseas que se ejecute directamente en un **script** .R, y enseguida ejecutar las líneas seleccionadas (ya sea utilizando los atajos del teclado en RStudio o haciendo clic en el botón "Run") en la consola interactiva de R. + +Cuando tu proyecto se encuentra en sus primeras etapas, el archivo **script** inicial .R generalmente contendrá muchas líneas de código ejecutadas directamente. Conforme vaya madurando, fragmentos reutilizables podrán ser llevados a sus +propias funciones. Es buena idea separar estas funciones en dos carpetas separadas; una +para guardar funciones útiles que reutilizarás a través del análisis y proyectos, y +una para guardar los **scripts** de análisis. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Tip: Evitando la duplicación + +Puedes encontrarte utilizando datos o **scripts** de análisis a través de varios proyectos. +Normalmente, deseas evitar la duplicación para ahorrar espacio y evitar +actualizar el código en múltiples lugares. + +En este caso, es útil hacer "links simbólicos", los cuales son esencialmente +accesos directos a archivos en otro lugar en un sistema de archivos. En Linux y OS X puedes +utilizar el comando `ln -s`, y en Windows crear un acceso directo o +utilizar el comando `mklink` desde la terminal de Windows. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +### Guardar los datos en el directorio de datos + +Ahora que tenemos una buena estructura de directorios colocaremos/guardaremos los archivos de datos en el directorio `data/`. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Descargar los datos gapminder de [aquí](https://raw.githubusercontent.com/resbaz/r-novice-gapminder-files/master/data/gapminder-FiveYearData.csv). + +1. Descargar el archivo (CTRL + S, clic botón derecho del ratón -> "Guardar como...", o Archivo -> "Guardar página como...") +2. Asegúrate de que esté guardado con el nombre `gapminder-FiveYearData.csv` +3. Guardar el archivo en la carpeta `data/` dentro de tu proyecto. + +Más delante cargaremos e inspeccionaremos estos datos. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +Es útil tener una idea general sobre el **dataset**, directamente desde la +línea de comandos, antes de cargarlo en R. Comprender mejor el **dataset** +será útil al tomar decisiones sobre cómo cargarlo en R. Utiliza la terminal de +línea de comandos para contestar las siguientes preguntas: + +1. ¿Cuál es el tamaño del archivo? +2. ¿Cuántas líneas de datos contiene? +3. ¿Cuáles tipos de valores están almacenados en este archivo? + +::::::::::::::: solution + +## Solución al desafío 2 + +Al ejecutar estos comandos en la terminal: + + +```sh +ls -lh data/gapminder-FiveYearData.csv +``` + +```{.output} +-rw-r--r-- 1 runner docker 80K Nov 10 17:55 data/gapminder-FiveYearData.csv +``` + +El tamaño del archivo es 80K. + + +```sh +wc -l data/gapminder-FiveYearData.csv +``` + +```{.output} +1705 data/gapminder-FiveYearData.csv +``` + +Hay 1705 líneas. Los datos se ven así: + + +```sh +head data/gapminder-FiveYearData.csv +``` + +```{.output} +country,year,pop,continent,lifeExp,gdpPercap +Afghanistan,1952,8425333,Asia,28.801,779.4453145 +Afghanistan,1957,9240934,Asia,30.332,820.8530296 +Afghanistan,1962,10267083,Asia,31.997,853.10071 +Afghanistan,1967,11537966,Asia,34.02,836.1971382 +Afghanistan,1972,13079460,Asia,36.088,739.9811058 +Afghanistan,1977,14880372,Asia,38.438,786.11336 +Afghanistan,1982,12881816,Asia,39.854,978.0114388 +Afghanistan,1987,13867957,Asia,40.822,852.3959448 +Afghanistan,1992,16317921,Asia,41.674,649.3413952 +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::::: callout + +## Tip: Línea de comandos en R Studio + +Puedes abrir rápidamente una terminal en RStudio usando la opción del menú **Tools -> Shell...**. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +### Control de versiones + +Es importante llevar a cabo el control de versiones en un proyecto. Ve [aquí](https://swcarpentry.github.io/git-novice-es/14-supplemental-rstudio/) para una buena lección donde se describe el uso de Git con R Studio. + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Usar RStudio para crear y gestionar proyectos con un diseño consistente. +- Tratar los datos brutos como de sólo lectura. +- Tratar la salida generada como disponible. +- Definición y aplicación de funciones separadas. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/03-seeking-help.md b/03-seeking-help.md new file mode 100644 index 00000000..eac7b887 --- /dev/null +++ b/03-seeking-help.md @@ -0,0 +1,305 @@ +--- +title: Buscando ayuda +teaching: 10 +exercises: 10 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Poder leer archivos de ayuda de R, para funciones y operadores especiales +- Poder usar vistas de tareas CRAN para identificar paquetes para resolver un problema +- Para poder buscar ayuda de tus compañeros + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo obtener ayuda en R? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +::::::::::::::::::::::::::::::::::::::: checklist + +## Palabras clave + +Comando : Traducción + +`help` : ayuda + +`vignette` : viñeta + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Lectura de archivos de ayuda + +R, y cada paquete, proporciona archivos de ayuda para las funciones. La sintaxis general +para buscar ayuda en cualquier función, "function\_name", de una función específica que esté en un paquete +cargado dentro de tu **namespace** (tu sesión interactiva en R): + + +```r +?function_name +help(function_name) +``` + +Esto cargará una página de ayuda en RStudio (o como texto sin formato en R por sí mismo). + +Cada página de ayuda se divide en secciones: + +- Descripción: una descripción extendida de lo que hace la función. +- Uso: los argumentos de la función y sus valores predeterminados. +- Argumentos: una explicación de los datos que espera cada argumento. +- Detalles: cualquier detalle importante a tener en cuenta. +- Valor: los datos que regresa la función. +- Ver también: cualquier función relacionada que pueda serte útil. +- Ejemplos: algunos ejemplos de cómo usar la función. + +Las diferentes funciones pueden tener diferentes secciones, pero estas son las principales que debes tener en cuenta. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Lectura de archivos de ayuda + +Uno de los aspectos más desalentadores de R es la gran cantidad de funciones +disponibles. Es muy difícil, si no imposible, recordar el +uso correcto para cada función que usas. Afortunadamente, están los archivos de ayuda +¡lo que significa, que no tienes que hacerlo! + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Operadores especiales + +Para buscar ayuda en operadores especiales, usa comillas: + + +```r +?"<-" +``` + +## Obteniendo ayuda en los paquetes + +Muchos paquetes vienen con "viñetas": tutoriales y documentación de ejemplo extendida. +Sin ningún argumento, `vignette()` listará todas las viñetas disponibles para todos los paquetes instalados; +`vignette(package="package-name")` listará todas las viñetas disponibles para +`package-name`, y `vignette("vignette-name")` abrirá la viñeta especificada. + +Si un paquete no tiene viñetas, generalmente puedes encontrar ayuda escribiendo +`help("package-name")`. + +## Cuando recuerdas un poco sobre la función + +Si no estás seguro de en qué paquete está una función, o cómo se escribe específicamente, puedes hacer una búsqueda difusa: + + +```r +??function_name +``` + +## Cuando no tienes idea de dónde comenzar + +Si no sabes qué función o paquete necesitas usar, utiliza +[CRAN Task Views](https://cran.at.r-project.org/web/views) +es una lista especialmente mantenida de paquetes agrupados en +campos. Este puede ser un buen punto de partida. + +## Cuando tu código no funciona: busca ayuda de tus compañeros + +Si tienes problemas para usar una función, 9 de cada 10 veces, +las respuestas que estas buscando ya han sido respondidas en +[Stack Overflow](https://stackoverflow.com/). Puedes buscar usando +la etiqueta `[r]`. + +Si no puedes encontrar la respuesta, hay algunas funciones útiles para +ayudarte a hacer una pregunta a tus compañeros: + + +```r +?dput +``` + +Descargará los datos con los que estás trabajando en un formato para que puedan +ser copiados y pegados por cualquier otra persona en su sesión de R. + + +```r +sessionInfo() +``` + +```{.output} +R version 4.3.1 (2023-06-16) +Platform: x86_64-pc-linux-gnu (64-bit) +Running under: Ubuntu 22.04.3 LTS + +Matrix products: default +BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0 +LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0 + +locale: + [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8 + [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8 + [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C +[10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C + +time zone: UTC +tzcode source: system (glibc) + +attached base packages: +[1] stats graphics grDevices utils datasets methods base + +loaded via a namespace (and not attached): +[1] compiler_4.3.1 tools_4.3.1 yaml_2.3.7 knitr_1.45 xfun_0.41 +[6] renv_1.0.3 evaluate_0.23 +``` + +Imprimirá tu versión actual de R, así como cualquier paquete que hayas +cargado. Esto puede ser útil para otros para ayudar a reproducir y depurar +tu problema. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Buscar la ayuda para la función `c`. ¿Qué tipo de vector +crees que crearás si evalúas lo siguiente?: + + +```r +c(1, 2, 3) +c('d', 'e', 'f') +c(1, 2, 'f') +``` + +::::::::::::::: solution + +## Solución al desafío 1 + +La función `c()` crea un vector, en el cual todos los elementos son +del mismo tipo. En el primer caso, los elementos son numéricos, en el +segundo, son **character**, y en el tercero son **character**: +los valores numéricos son "forzados" para ser **characters**. + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +Buscar la ayuda para la función `paste`. Tendrás que usar esto más tarde. +¿Cuál es la diferencia entre los argumentos `sep` y `collapse`? + +::::::::::::::: solution + +## Solución para el desafío 2 + +Busca la ayuda de la función `paste()`, usa: + + +```r +help("paste") +?paste +``` + +La diferencia entre `sep` y `collapse` es un poco +complicada. La función `paste` acepta cualquier número de argumentos, cada uno +de los cuales puede ser un vector de cualquier longitud. El argumento `sep` especifica la cadena +usada entre términos concatenados — por defecto, un espacio. El resultado es un +vector tan largo como el argumento más largo proporcionado a `paste`. En cambio, +`collapse` especifica que después de la concatenación los elementos son *colapsados* +juntos utilizando el separador dado, y el resultado es una sola cadena. +e.g. + + +```r +paste(c("a","b"), "c") +``` + +```{.output} +[1] "a c" "b c" +``` + +```r +paste(c("a","b"), "c", sep = ",") +``` + +```{.output} +[1] "a,c" "b,c" +``` + +```r +paste(c("a","b"), "c", collapse = "|") +``` + +```{.output} +[1] "a c|b c" +``` + +```r +paste(c("a","b"), "c", sep = ",", collapse = "|") +``` + +```{.output} +[1] "a,c|b,c" +``` + +(Para más información, +ve a la parte inferior de la página de ayuda `?paste` y busca los +ejemplos, o prueba `example('paste')`.) + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +Usa la ayuda para encontrar una función (y sus parámetros asociados) que tu puedas +usar para cargar datos de un archivo csv en los cuales las columnas están delimitadas con "\\ t" +(tab) y el punto decimal es un "." (punto). Esta comprobación para el separador decimal +es importante, especialmente si estás trabajando con colegas internacionales +ya que diferentes países tienen diferentes convenciones para el +punto decimal (i.e. coma vs. punto). +sugerencia: usa `??csv` para buscar funciones relacionadas con csv. + +::::::::::::::: solution + +## Solución para el desafío 3 + +La función R estándar para leer archivos delimitados por tabuladores con un separador +de punto decimal es `read.delim()`. Tu puedes hacer esto también con +`read.table(file, sep="\t")` (el punto es el separador +decimal por defecto para `read.table()`, aunque es posible que tengas que cambiar también el argumento +`comment.char` si tu archivo de datos contiene caracteres +numeral (#) + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Otros recursos útiles + +- [Quick R](https://www.statmethods.net/) +- [RStudio cheat sheets](https://www.rstudio.com/resources/cheatsheets/) +- [Cookbook for R](https://www.cookbook-r.com/) + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Usar `help()` para obtener ayuda online de R. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/04-data-structures-part1.md b/04-data-structures-part1.md new file mode 100644 index 00000000..2ca4c743 --- /dev/null +++ b/04-data-structures-part1.md @@ -0,0 +1,1115 @@ +--- +title: Estructuras de datos +teaching: 40 +exercises: 15 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Conocer los distintos tipos de datos. +- Comenzar a explorar los *data frames* y entender cómo se relacionan con **vectors**, **factors** y **lists**. +- Ser capaz de preguntar sobre el tipo, clase y estructura de un objeto en R. +- Conocer y entender qué es coerción y cuáles son los distintos tipos de coerciones. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo leer datos en R? +- ¿Cuáles son los tipos de datos básicos en R? +- ¿Cómo represento la información categórica en R? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +::::::::::::::::::::::::::::::::::::::: checklist + +## Palabras clave + +Comando : Significado + +*data set* : conjunto de datos + +`c` : combinar + +`dim` : dimensión + +`nrow` : número de filas + +`ncol`: número de columnas + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Una de las características más poderosas de R es su habilidad para manejar datos tabulares - +como los que puedes tener en una planilla de cálculo o un archivo CSV. +Comencemos creando un **dataset** llamado `gatos` que se vea de la siguiente forma: + + +```r +color,peso,le_gusta_cuerda +mixto,2.1,1 +negro,5.0,0 +atigrado,3.2,1 +``` + +Podemos usar la función `data.frame` para crearlo. + + +```r +gatos <- data.frame(color = c("mixto", "negro", "atigrado"), + peso = c(2.1, 5.0, 3.2), + le_gusta_cuerda = c(1, 0, 1)) +gatos +``` + +```{.output} + color peso le_gusta_cuerda +1 mixto 2.1 1 +2 negro 5.0 0 +3 atigrado 3.2 1 +``` + + + +::::::::::::::::::::::::::::::::::::::::: callout + +## Consejo: Edición de archivos de texto en R + +Crea el archivo `data/gatos-data.csv` en RStudio usando el ítem del Menú **Files -> New folder**. +Ahid debes crear el directorio data para poder guardar dentro el archivo gatos-data.csv. +Ahora sí usa `write.csv(gatos, "data/gatos-data.csv", row.names=FALSE)` para crear el archivo + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Podemos leer el archivo en R con el siguiente comando: + + +```r +gatos <- read.csv(file = "data/gatos-data.csv", stringsAsFactors = TRUE) +gatos +``` + +```{.output} + color peso le_gusta_cuerda +1 mixto 2.1 1 +2 negro 5.0 0 +3 atigrado 3.2 1 +``` + +La función `read.table` se usa para leer datos tabulares almacenados en un archivo de +texto donde las columnas de datos están separadas por caracteres de puntuación, por ejemplo +archivos CSV (csv = valores separados por comas). Las tabulaciones y las comas son los +caracteres de puntuación más utilizados para separar o delimitar datos en archivos csv. +Para mayor comodidad, R proporciona otras 2 versiones de "read.table". Estos son: `read.csv` +para archivos donde los datos están separados por comas y `read.delim` para archivos +donde los datos están separados por tabulaciones. De estas tres funciones, `read.csv` es +el más utilizado. Si fuera necesario, es posible anular o modificar el delimitador predeterminado +para `read.csv` y ` read.delim`. + +Podemos empezar a explorar el **dataset** inmediatamente proyectando las columnas usando el operador `$`: + + +```r +gatos$peso +``` + +```{.output} +[1] 2.1 5.0 3.2 +``` + +```r +gatos$color +``` + +```{.output} +[1] mixto negro atigrado +Levels: atigrado mixto negro +``` + +Podemos hacer otras operaciones sobre las columnas. Por ejemplo, podemos aumentar el peso de todos los gatos con: + + +```r +gatos$peso + 2 +``` + +```{.output} +[1] 4.1 7.0 5.2 +``` + +Podemos imprimir los resultados en una oración + + +```r +paste("El color del gato es", gatos$color) +``` + +```{.output} +[1] "El color del gato es mixto" "El color del gato es negro" +[3] "El color del gato es atigrado" +``` + +Pero qué pasa con: + + +```r +gatos$peso + gatos$color +``` + +```{.warning} +Warning in Ops.factor(gatos$peso, gatos$color): '+' not meaningful for factors +``` + +```{.output} +[1] NA NA NA +``` + +Si adivinaste que el último comando iba a resultar en un error porque `2.1` más +`"negro"` no tiene sentido, estás en lo cierto - y ya tienes alguna intuición sobre un concepto +importante en programación que se llama *tipos de datos*. + +No importa cuán complicado sea nuestro análisis, todos los datos en R se interpretan con uno de estos +tipos de datos básicos. Este rigor tiene algunas consecuencias importantes. + +Hay 5 tipos de datos principales: `double`, `integer`, `complex`, `logical` and `character`. + +Podemos preguntar cuál es la estructura de datos si usamos la función `class`: + + +```r +class(gatos$color) +``` + +```{.output} +[1] "factor" +``` + +```r +class(gatos$peso) +``` + +```{.output} +[1] "numeric" +``` + +También podemos ver que `gatos` es un **data.frame** si usamos la función `class`: + + +```r +class(gatos) +``` + +```{.output} +[1] "data.frame" +``` + +## Vectores y Coerción de Tipos + +Para entender mejor este comportamiento, veamos otra de las estructuras de datos en R: el **vector**. + +Un vector en R es esencialmente una lista ordenada de cosas, con la condición especial +de que *todos los elementos en un vector tienen que ser del mismo tipo de datos básico*. +Si no eliges un tipo de datos, por defecto R elige el tipo de datos **logical**. +También puedes declarar un vector vacío de cualquier tipo que quieras. + +Una indicación del número de elementos en el vector - específicamente los índices +del vector, en este caso `[1:3]` y unos pocos ejemplos +de los elementos del vector - en este caso **strings** vacíos. + +Podemos ver que `gatos$peso` es un vector usando la funcion `str`. + + +```r +str(gatos$peso) +``` + +```{.output} + num [1:3] 2.1 5 3.2 +``` + +Las columnas de datos que cargamos en **data.frames** de R son todas vectores +y este es el motivo por el cual R requiere +que todas las columnas sean del mismo tipo de datos básico. + +:::::::::::::::::::::::::::::::::::::: discussion + +## Discusión 1 + +¿Por qué R es tan obstinado acerca de lo que ponemos en nuestras columnas de datos? +¿Cómo nos ayuda esto? + +::::::::::::::: solution + +## Discusión 1 + +Al mantener todos los elementos de una columna del mismo tipo, podemos hacer +suposiciones simples sobre nuestros datos; si puedes interpretar un elemento +en una columna como un número, entonces puedes interpretar *todos* los elementos como números, +y por tanto no hace falta comprobarlo cada vez. +Esta consistencia es lo que se suele mencionar como *datos limpios*; +a la larga, la consistencia estricta hace nuestras vidas más fáciles cuando usamos R. + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +También puedes crear vectores con contenido explícito con la función **combine** o `c()`: + + +```r +mi_vector <- c(2,6,3) +mi_vector +``` + +```{.output} +[1] 2 6 3 +``` + +```r +str(mi_vector) +``` + +```{.output} + num [1:3] 2 6 3 +``` + +Dado lo que aprendimos hasta ahora, ¿qué crees que hace el siguiente código? + + +```r +otro_vector <- c(2,6,'3') +``` + +Esto se denomina *coerción de tipos de datos* y es motivo de muchas sorpresas y la razón por la cual es necesario conocer +los tipos de datos básicos y cómo R los interpreta. Cuando R encuentra una mezcla de tipos de datos (en este caso **numeric** y **character**) para combinarlos en un vector, va a forzarlos a ser del mismo tipo. + +Considera: + + +```r +vector_coercion <- c('a', TRUE) +str(vector_coercion) +``` + +```{.output} + chr [1:2] "a" "TRUE" +``` + +```r +otro_vector_coercion <- c(0, TRUE) +str(otro_vector_coercion) +``` + +```{.output} + num [1:2] 0 1 +``` + +Las reglas de coerción son: `logical` -> `integer` -> `numeric` -> `complex` -> +`character`, donde -> se puede leer como *se transforma en*. +Puedes intentar forzar la coerción de acuerdo a esta cadena usando las funciones `as.`: + + +```r +vector_caracteres <- c('0','2','4') +vector_caracteres +``` + +```{.output} +[1] "0" "2" "4" +``` + +```r +str(vector_caracteres) +``` + +```{.output} + chr [1:3] "0" "2" "4" +``` + +```r +caracteres_coercionados_numerico <- as.numeric(vector_caracteres) +caracteres_coercionados_numerico +``` + +```{.output} +[1] 0 2 4 +``` + +```r +numerico_coercionado_logico <- as.logical(caracteres_coercionados_numerico) +numerico_coercionado_logico +``` + +```{.output} +[1] FALSE TRUE TRUE +``` + +Como puedes notar, es sorprendete ver qué pasa cuando R forza la conversión de un tipo de datos a otro. Es decir, si tus datos no lucen como pensabas que deberían lucir, puede ser culpa de la coerción de tipos. Por lo tanto, asegúrate que todos los elementos de tus vectores y las columnas de tus **data.frames** sean del mismo tipo o te encontrarás con sorpresas desagradables. + +Pero la coerción de tipos también puede ser muy útil. Por ejemplo, en los datos de `gatos`, +`le_gusta_cuerda` es numérica, pero sabemos que los 1s y 0s en realidad representan **`TRUE`** y **`FALSE`** +(una forma habitual de representarlos). Deberíamos usar el tipo de datos +**`logical`** en este caso, que tiene dos estados: **`TRUE`** o **`FALSE`**, que es exactamente +lo que nuestros datos representan. Podemos convertir esta columna al tipo de datos **`logical`** +usando la función `as.logical`: + + +```r +gatos$le_gusta_cuerda +``` + +```{.output} +[1] 1 0 1 +``` + +```r +class(gatos$le_gusta_cuerda) +``` + +```{.output} +[1] "integer" +``` + +```r +gatos$le_gusta_cuerda <- as.logical(gatos$le_gusta_cuerda) +gatos$le_gusta_cuerda +``` + +```{.output} +[1] TRUE FALSE TRUE +``` + +```r +class(gatos$le_gusta_cuerda) +``` + +```{.output} +[1] "logical" +``` + +La función **combine**, `c()`, también agregará elementos al final de un vector existente: + + +```r +ab <- c('a', 'b') +ab +``` + +```{.output} +[1] "a" "b" +``` + +```r +abc <- c(ab, 'c') +abc +``` + +```{.output} +[1] "a" "b" "c" +``` + +También puedes hacer una serie de números así: + + +```r +mySerie <- 1:5 +mySerie +``` + +```{.output} +[1] 1 2 3 4 5 +``` + +```r +str(mySerie) +``` + +```{.output} + int [1:5] 1 2 3 4 5 +``` + +```r +class(mySerie) +``` + +```{.output} +[1] "integer" +``` + +Finalmente, puedes darle nombres a los elementos de tu vector: + + +```r +names(mySerie) <- c("a", "b", "c", "d", "e") +mySerie +``` + +```{.output} +a b c d e +1 2 3 4 5 +``` + +```r +str(mySerie) +``` + +```{.output} + Named int [1:5] 1 2 3 4 5 + - attr(*, "names")= chr [1:5] "a" "b" "c" "d" ... +``` + +```r +class(mySerie) +``` + +```{.output} +[1] "integer" +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Comienza construyendo un vector con los números del 1 al 26. +Multiplica el vector por 2 y asigna al vector resultante, los nombres de A hasta Z +(Pista: hay un vector pre-definido llamado **`LETTERS`**) + +::::::::::::::: solution + +## Solución del desafío 1 + + +```r +x <- 1:26 +x <- x * 2 +names(x) <- LETTERS +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Factores + +Otra estructura de datos importante se llama **factor**. + + +```r +str(gatos$color) +``` + +```{.output} + Factor w/ 3 levels "atigrado","mixto",..: 2 3 1 +``` + +Los factores usualmente parecen caracteres, pero se usan para representar información categórica. +Por ejemplo, construyamos un vector de **strings** con etiquetas para las coloraciones para todos los +gatos en nuestro estudio: + + +```r +capas <- c('atigrado', 'carey', 'carey', 'negro', 'atigrado') +capas +``` + +```{.output} +[1] "atigrado" "carey" "carey" "negro" "atigrado" +``` + +```r +str(capas) +``` + +```{.output} + chr [1:5] "atigrado" "carey" "carey" "negro" "atigrado" +``` + +Podemos convertir un vector en un **factor** de la siguiente manera: + + +```r +categorias <- factor(capas) +class(categorias) +``` + +```{.output} +[1] "factor" +``` + +```r +str(categorias) +``` + +```{.output} + Factor w/ 3 levels "atigrado","carey",..: 1 2 2 3 1 +``` + +Ahora R puede interpretar que hay tres posibles categorías en nuestros datos - pero también +hizo algo sorprendente: en lugar de imprimir los **strings** como se las dimos, imprimió una +serie de números. R ha reemplazado las categorías con índices numéricos, lo cual es necesario porque +muchos cálculos estadísticos usan esa representación para datos categóricos: + + +```r +class(capas) +``` + +```{.output} +[1] "character" +``` + +```r +class(categorias) +``` + +```{.output} +[1] "factor" +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +¿Hay algún **factor** en nuestro **data.frame** `gatos`? ¿Cuál es el nombre? +Intenta usar `?read.csv` para darte cuenta cómo mantener las columnas de texto como vectores de caracteres +en lugar de factores; luego escribe uno o más comandos para mostrar que el **factor** en +`gatos` es en realidad un vector de caracteres cuando se carga de esta manera. + +::::::::::::::: solution + +## Solución al desafío 2 + +Una solución es usar el argumento `stringAsFactors`: + + +```r +gatos <- read.csv(file="data/gatos-data.csv", stringsAsFactors=FALSE) +str(gatos$color) +``` + +Otra solución es usar el argumento `colClasses` +que permiten un control más fino. + + +```r +gatos <- read.csv(file="data/gatos-data.csv", colClasses=c(NA, NA, "character")) +str(gatos$color) +``` + +Nota: Los nuevos estudiantes encuentran los archivos de ayuda difíciles de entender; asegúrese de hacerles saber +que esto es normal, y anímelos a que tomen su mejor opción en función del significado semántico, +incluso si no están seguros. + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +En las funciones de modelado, es importante saber cuáles son los niveles de referencia. Se asume +que es el primer factor, pero por defecto los factores están etiquetados en +orden alfabetico. Puedes cambiar esto especificando los niveles: + + +```r +misdatos <- c("caso", "control", "control", "caso") +factor_orden <- factor(misdatos, levels = c("control", "caso")) +str(factor_orden) +``` + +```{.output} + Factor w/ 2 levels "control","caso": 2 1 1 2 +``` + +En este caso, le hemos dicho explícitamente a R que "control" debería estar representado por 1, y +"caso" por 2. Esta designación puede ser muy importante para interpretar los +resultados de modelos estadísticos! + +## Listas + +Otra estructura de datos que querrás en tu bolsa de trucos es `list`. Una lista +es más simple en algunos aspectos que los otros tipos, porque puedes poner cualquier cosa +que tú quieras en ella: + + +```r +lista <- list(1, "a", TRUE, 1+4i) +lista +``` + +```{.output} +[[1]] +[1] 1 + +[[2]] +[1] "a" + +[[3]] +[1] TRUE + +[[4]] +[1] 1+4i +``` + +```r +otra_lista <- list(title = "Numbers", numbers = 1:10, data = TRUE ) +otra_lista +``` + +```{.output} +$title +[1] "Numbers" + +$numbers + [1] 1 2 3 4 5 6 7 8 9 10 + +$data +[1] TRUE +``` + +Ahora veamos algo interesante acerca de nuestro **data.frame**; ¿Qué pasa si corremos la siguiente línea? + + +```r +typeof(gatos) +``` + +```{.output} +[1] "list" +``` + +Vemos que los **data.frames** parecen listas 'en su cara oculta' - esto es porque un +**data.frame** es realmente una lista de vectores y factores, como debe ser - +para mantener esas columnas que son una combinación de vectores y factores, +el **data.frame** necesita algo más flexible que un vector para poner todas las +columnas juntas en una tabla. En otras palabras, un `data.frame` es una +lista especial en la que todos los vectores deben tener la misma longitud. + +En nuestro ejemplo de `gatos`, tenemos una variable **integer**, una **double** y una **logical**. Como +ya hemos visto, cada columna del **data.frame** es un vector. + + +```r +gatos$color +``` + +```{.output} +[1] mixto negro atigrado +Levels: atigrado mixto negro +``` + +```r +gatos[,1] +``` + +```{.output} +[1] mixto negro atigrado +Levels: atigrado mixto negro +``` + +```r +typeof(gatos[,1]) +``` + +```{.output} +[1] "integer" +``` + +```r +str(gatos[,1]) +``` + +```{.output} + Factor w/ 3 levels "atigrado","mixto",..: 2 3 1 +``` + +Cada fila es una *observación* de diferentes variables del mismo **data.frame**, y +por lo tanto puede estar compuesto de elementos de diferentes tipos. + + +```r +gatos[1,] +``` + +```{.output} + color peso le_gusta_cuerda +1 mixto 2.1 TRUE +``` + +```r +typeof(gatos[1,]) +``` + +```{.output} +[1] "list" +``` + +```r +str(gatos[1,]) +``` + +```{.output} +'data.frame': 1 obs. of 3 variables: + $ color : Factor w/ 3 levels "atigrado","mixto",..: 2 + $ peso : num 2.1 + $ le_gusta_cuerda: logi TRUE +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +Hay varias maneras sutilmente diferentes de indicar variables, observaciones y elementos de **data.frames**: + +- `gatos[1]` +- `gatos[[1]]` +- `gatos$color` +- `gatos["color"]` +- `gatos[1, 1]` +- `gatos[, 1]` +- `gatos[1, ]` + +Investiga cada uno de los ejemplos anteriores y explica el resultado de cada uno. + +*Sugerencia:* Usa la función **`typeof()`** para examinar el resultado en cada caso. + +::::::::::::::: solution + +## Solución al desafío 3 + + +```r +gatos[1] +``` + +```{.output} + color +1 mixto +2 negro +3 atigrado +``` + +Podemos interpretar un **data frame** como una lista de vectores. Un único par de corchetes `[1]` +resulta en la primera proyección de la lista, como otra lista. En este caso es la primera columna del +**data frame**. + + +```r +gatos[[1]] +``` + +```{.output} +[1] mixto negro atigrado +Levels: atigrado mixto negro +``` + +El doble corchete `[[1]]` devuelve el contenido del elemento de la lista. En este caso, +es el contenido de la primera columna, un *vector* de tipo *factor*. + + +```r +gatos$color +``` + +```{.output} +[1] mixto negro atigrado +Levels: atigrado mixto negro +``` + +Este ejemplo usa el caracter `$` para direccionar elementos por nombre. *color* es la +primera columna del *data frame*, de nuevo un *vector* de tipo *factor*. + + +```r +gatos["color"] +``` + +```{.output} + color +1 mixto +2 negro +3 atigrado +``` + +Aquí estamos usando un solo corchete `["color"]` reemplazando el número del índice con +el nombre de la columna. Como el ejemplo 1, el objeto devuelto es un *list*. + + +```r +gatos[1, 1] +``` + +```{.output} +[1] mixto +Levels: atigrado mixto negro +``` + +Este ejemplo usa un solo corchete, pero esta vez proporcionamos coordenadas de fila y columna. +El objeto devuelto es el valor en la fila 1, columna 1. El objeto es un *integer* pero como +es parte de un *vector* de tipo *factor*, R muestra la etiqueta "mixto" asociada con el valor entero. + + +```r +gatos[, 1] +``` + +```{.output} +[1] mixto negro atigrado +Levels: atigrado mixto negro +``` + +Al igual que en el ejemplo anterior, utilizamos corchetes simples y proporcionamos +las coordenadas de fila y columna. La coordenada de la fila no se especifica, +R interpreta este valor faltante como todos los elementos en este *column* *vector*. + + +```r +gatos[1, ] +``` + +```{.output} + color peso le_gusta_cuerda +1 mixto 2.1 TRUE +``` + +De nuevo, utilizamos el corchete simple con las coordenadas de fila y columna. +La coordenada de la columna no está especificada. El valor de retorno es una *list* +que contiene todos los valores en la primera fila. + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Matrices + +Por último, pero no menos importante, están las matrices. Podemos declarar una matriz llena de ceros de +la siguiente forma: + + +```r +matrix_example <- matrix(0, ncol=6, nrow=3) +matrix_example +``` + +```{.output} + [,1] [,2] [,3] [,4] [,5] [,6] +[1,] 0 0 0 0 0 0 +[2,] 0 0 0 0 0 0 +[3,] 0 0 0 0 0 0 +``` + +Y de manera similar a otras estructuras de datos, podemos preguntar cosas sobre la matriz: + + +```r +class(matrix_example) +``` + +```{.output} +[1] "matrix" "array" +``` + +```r +typeof(matrix_example) +``` + +```{.output} +[1] "double" +``` + +```r +str(matrix_example) +``` + +```{.output} + num [1:3, 1:6] 0 0 0 0 0 0 0 0 0 0 ... +``` + +```r +dim(matrix_example) +``` + +```{.output} +[1] 3 6 +``` + +```r +nrow(matrix_example) +``` + +```{.output} +[1] 3 +``` + +```r +ncol(matrix_example) +``` + +```{.output} +[1] 6 +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 4 + +¿Cuál crees que es el resultado del comando +`length(matrix_example)`? +Inténtalo. +¿Estabas en lo correcto? ¿Por qué / por qué no? + +::::::::::::::: solution + +## Solución al desafío 4 + +¿Cuál crees que es el resultado del comando +`length(matrix_example)`? + + +```r +matrix_example <- matrix(0, ncol=6, nrow=3) +length(matrix_example) +``` + +```{.output} +[1] 18 +``` + +Debido a que una matriz es un vector con atributos de dimensión añadidos, `length` +proporciona la cantidad total de elementos en la matriz. + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 5 + +Construye otra matriz, esta vez conteniendo los números 1:50, +con 5 columnas y 10 renglones. +¿Cómo llenó la función **`matrix`** de manera predeterminada la matriz, por columna o por renglón? +Investiga como cambiar este comportamento. +(Sugerencia: lee la documentación de la función **`matrix`**.) + +::::::::::::::: solution + +## Solución al desafío 5 + +Construye otra matriz, esta vez conteniendo los números 1:50, +con 5 columnas y 10 renglones. +¿Cómo llenó la función **`matrix`** de manera predeterminada la matriz, por columna o por renglón? +Investiga como cambiar este comportamento. +(Sugerencia: lee la documentación de la función **`matrix`**.) + + +```r +x <- matrix(1:50, ncol=5, nrow=10) +x <- matrix(1:50, ncol=5, nrow=10, byrow = TRUE) # to fill by row +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 6 + +Crea una lista de longitud dos que contenga un vector de caracteres para cada una de las secciones en esta parte del curso: + +- tipos de datos +- estructura de datos + +Inicializa cada vector de caracteres con los nombres de los tipos de datos y estructuras de datos +que hemos visto hasta ahora. + +::::::::::::::: solution + +## Solución al desafío 6 + + +```r +dataTypes <- c('double', 'complex', 'integer', 'character', 'logical') +dataStructures <- c('data.frame', 'vector', 'factor', 'list', 'matrix') +answer <- list(dataTypes, dataStructures) +``` + +Nota: es útil hacer una lista en el pizarrón o en papel colgado en la pared listando +todos los tipos y estructuras de datos y mantener la lista durante el resto del curso +para recordar la importancia de estos elementos básicos. + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 7 + +Considera la salida de R para la siguiente matriz: + + +```{.output} + [,1] [,2] +[1,] 4 1 +[2,] 9 5 +[3,] 10 7 +``` + +¿Cuál fué el comando correcto para escribir esta matriz? Examina +cada comando e intenta determinar el correcto antes de escribirlos. +Piensa en qué matrices producirán los otros comandos. + +1. `matrix(c(4, 1, 9, 5, 10, 7), nrow = 3)` +2. `matrix(c(4, 9, 10, 1, 5, 7), ncol = 2, byrow = TRUE)` +3. `matrix(c(4, 9, 10, 1, 5, 7), nrow = 2)` +4. `matrix(c(4, 1, 9, 5, 10, 7), ncol = 2, byrow = TRUE)` + +::::::::::::::: solution + +## Solución al desafío 7 + +Considera la salida de R para la siguiente matriz: + + +```{.output} + [,1] [,2] +[1,] 4 1 +[2,] 9 5 +[3,] 10 7 +``` + +¿Cuál era el comando correcto para escribir esta matriz? Examina +cada comando e intenta determinar el correcto antes de escribirlos. +Piensa en qué matrices producirán los otros comandos. + + +```r +matrix(c(4, 1, 9, 5, 10, 7), ncol = 2, byrow = TRUE) +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Usar `read.csv` para leer los datos tabulares en R. +- Los vectores, factores, listas y dataframes son estructuras de datos en R +- Los tipos de datos básicos en R son **double**, **integer**, **complex**, **logical**, y **character**. +- Los **factors** representan variables categóricas en R. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/05-data-structures-part2.md b/05-data-structures-part2.md new file mode 100644 index 00000000..7e4b958e --- /dev/null +++ b/05-data-structures-part2.md @@ -0,0 +1,749 @@ +--- +title: Explorando data frames +teaching: 20 +exercises: 10 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Poder agregar y quitar filas y columnas. +- Poder quitar filas con valores `NA`. +- Poder anexar dos *data frames*. +- Poder articular qué es un `factor` y cómo convertir entre `factor` y `character`. +- Poder entender las propiedades básicas de un *data frame*, incluyendo tamaño, clase o tipo de columnas, nombres y primeras filas. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo manipular un *data frame*? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +A esta altura, ya viste los tipos y estructuras de datos básicos de R y todo lo que hagas va a ser una manipulación de esas herramientas. Ahora pasaremos a aprender un par de cosas sobre cómo trabajar con la clase *data frame* (la estructura de datos que usarás la mayoría del tiempo y que será la estrella del show). Un *data frame* es la tabla que creamos al cargar información de un archivo csv. + +::::::::::::::::::::::::::::::::::::::: checklist + +## Palabras clave + +Comando : Traducción + +`nrow`: número de filas + +`ncol`: número de columnas + +`rbind`: combinar filas + +`cbind`: combinar columnas + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Agregando columnas y filas a un data frame + +Aprendimos que las columnas en un *data frame* son vectores. Por lo tanto, sabemos que nuestros datos son consistentes con el tipo de dato dentro de esa columna. Si queremos agregar una nueva columna, podemos empezar por crear un nuevo vector: + + +```r +gatos +``` + +```{.output} + color peso legusta_la_cuerda +1 mixto 2.1 1 +2 negro 5.0 0 +3 atigrado 3.2 1 +``` + +```r +edad <- c(2,3,5) +``` + +Podemos entonces agregarlo como una columna via: + + +```r +cbind(gatos, edad) +``` + +```{.output} + color peso legusta_la_cuerda edad +1 mixto 2.1 1 2 +2 negro 5.0 0 3 +3 atigrado 3.2 1 5 +``` + +Tenga en cuenta que fallará si tratamos de agregar un vector con un número diferente de entradas que el número de filas en el marco de datos. + + +```r +edad <- c(2, 3, 5, 12) +cbind(gatos, edad) +``` + +```{.error} +Error in data.frame(..., check.names = FALSE): arguments imply differing number of rows: 3, 4 +``` + +```r +edad <- c(2, 3) +cbind(gatos, edad) +``` + +```{.error} +Error in data.frame(..., check.names = FALSE): arguments imply differing number of rows: 3, 2 +``` + +¿Por qué no funcionó? Claro, R quiere ver un elemento en nuestra nueva columna para cada fila de la tabla: + +Para que funcione, debemos tener `nrow(gatos)` = `length(edad)`. Vamos a sobrescribir el contenido de los gatos con nuestro nuevo marco de datos. + + +```r +edad <- c(2, 3, 5) +gatos <- cbind(gatos, edad) +gatos +``` + +```{.output} + color peso legusta_la_cuerda edad +1 mixto 2.1 1 2 +2 negro 5.0 0 3 +3 atigrado 3.2 1 5 +``` + +Ahora, qué tal si agregamos filas, en este caso, la última vez vimos que las filas de un *data frame* están compuestas por listas: + + +```r +nueva_fila <- list("carey", 3.3, TRUE, 9) +gatos <- rbind(gatos, nueva_fila) +``` + +```{.warning} +Warning in `[<-.factor`(`*tmp*`, ri, value = "carey"): invalid factor level, NA +generated +``` + +Qué significa el error que nos da R? 'invalid factor level' nos dice algo acerca de factores (factors)... pero qué es un factor? Un factor es un tipo de datos en R. Un factor es una categoría (por ejemplo, color) con la que R puede hacer ciertas operaciones. Por ejemplo: + + +```r +colores <- factor(c("negro","canela","canela","negro")) +levels(colores) +``` + +```{.output} +[1] "canela" "negro" +``` + +```r +nlevels(colores) +``` + +```{.output} +[1] 2 +``` + +Se puede reorganizar el orden de los factores para que en lugar de que aparezcan por orden alfabético sigan el orden elegido por el usuario. + + +```r +colores ## el orden actual +``` + +```{.output} +[1] negro canela canela negro +Levels: canela negro +``` + +```r +colores <- factor(colores, levels = c("negro", "canela")) +colores # despues de re-organizar +``` + +```{.output} +[1] negro canela canela negro +Levels: negro canela +``` + +## Factores + +Los objetos de la clase *factor* son otro tipo de datos que debemos usar con cuidado. Cuando R crea un *factor*, únicamente permite los valores que originalmente +estaban allí cuando cargamos los datos. Por ejemplo, en nuestro caso +'negro', 'canela' y 'atigrado'. Cualquier categoría nueva que no entre en esas categorías será rechazada (y se conviertirá en NA). + +La advertencia (*Warning*) nos está diciendo que agregamos 'carey' a nuestro factor +*color*. Pero los otros valores, 3.3 (de tipo *numeric*), TRUE (de tipo *logical*), y 9 (de tipo *numeric*) se añadieron exitosamente a *peso*, *le\_gusta\_cuerda*, y *edad*, respectivamente, dado que esos valores no son de tipo *factor*. Para añadir una nueva categoría 'carey' al *data frame* gatos en la columna *color*, debemos agregar explícitamente a 'carey' como un nuevo nivel (*level*) en el factor: + + +```r +levels(gatos$color) +``` + +```{.output} +[1] "atigrado" "mixto" "negro" +``` + +```r +levels(gatos$color) <- c(levels(gatos$color), 'carey') +gatos <- rbind(gatos, list("carey", 3.3, TRUE, 9)) +``` + +De manera alternativa, podemos cambiar la columna a tipo *character*. En este caso, perdemos las categorías, pero a partir de ahora podemos incorporar cualquier palabra a la columna, sin problemas con los niveles del factor. + + +```r +str(gatos) +``` + +```{.output} +'data.frame': 5 obs. of 4 variables: + $ color : Factor w/ 4 levels "atigrado","mixto",..: 2 3 1 NA 4 + $ peso : num 2.1 5 3.2 3.3 3.3 + $ legusta_la_cuerda: num 1 0 1 1 1 + $ edad : num 2 3 5 9 9 +``` + +```r +gatos$color <- as.character(gatos$color) +str(gatos) +``` + +```{.output} +'data.frame': 5 obs. of 4 variables: + $ color : chr "mixto" "negro" "atigrado" NA ... + $ peso : num 2.1 5 3.2 3.3 3.3 + $ legusta_la_cuerda: num 1 0 1 1 1 + $ edad : num 2 3 5 9 9 +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Imaginemos que, como los perros, 1 año humano es equivalente a 7 años en los gatos (La compañía Purina usa [un algoritmo más sofisticado](https://www.proplan.com/gatos/cat-edad-calculator)). + +1. Crea un vector llamado `human.edad` multiplicando `gatos$edad` por 7. +2. Convierte `human.edad` a *factor*. +3. Convierte `human.edad` de nuevo a un vector numérico usando la función `as.numeric()`. Ahora, divide por 7 para regresar a las edades originales. Explica lo sucedido. + +::::::::::::::: solution + +## Solución al Desafío 1 + +1. `human.edad <- gatos$edad * 7` +2. `human.edad <- factor(human.edad)` o `as.factor(human.edad)` las dos opciones funcionan igual de bien. +3. `as.numeric(human.edad)` produce `1 2 3 4 4` porque los factores se guardan como objetos de tipo entero *integer* (1:4), cada uno de los cuales tiene asociado una etiqueta *label* (28, 35, 56, y 63). Convertir un objeto de un tipo de datos a otro, por ejemplo de *factor* a *numeric* nos dá los enteros, no las etiquetas *labels*. Si queremos los números originales, necesitamos un paso intermedio, debemos convertir `human.edad` al tipo *character* y luego a *numeric* (¿cómo funciona esto?). Esto aparece en la vida real cuando accidentalmente incluimos un *character* en alguna columna de nuestro archivo .csv, que se suponía que únicamente contendría números. Tendremos este problema, si al leer el archivo olvidamos incluir `stringsAsFactors=FALSE`. + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Quitando filas + +Ahora sabemos cómo agregar filas y columnas a nuestro *data frame* en R, pero en nuestro primer intento para agregar un gato llamado 'carey' agregamos una fila que no sirve. + + +```r +gatos +``` + +```{.output} + color peso legusta_la_cuerda edad +1 mixto 2.1 1 2 +2 negro 5.0 0 3 +3 atigrado 3.2 1 5 +4 3.3 1 9 +5 carey 3.3 1 9 +``` + +Podemos pedir el *data frame* sin la fila errónea: + + +```r +gatos[-4,] +``` + +```{.output} + color peso legusta_la_cuerda edad +1 mixto 2.1 1 2 +2 negro 5.0 0 3 +3 atigrado 3.2 1 5 +5 carey 3.3 1 9 +``` + +Notar que -4 significa que queremos remover la cuarta fila, la coma sin nada detrás indica que se aplica a todas las columnas. Podríamos remover ambas filas en un llamado usando ambos números dentro de un vector: `gatos[c(-4,-5),]` + +Alternativamente, podemos eliminar filas que contengan valores `NA`: + + +```r +na.omit(gatos) +``` + +```{.output} + color peso legusta_la_cuerda edad +1 mixto 2.1 1 2 +2 negro 5.0 0 3 +3 atigrado 3.2 1 5 +5 carey 3.3 1 9 +``` + +Volvamos a asignar el nuevo resultado *output* al *data frame* `gatos`, así nuestros cambios son permanentes: + + +```r +gatos <- na.omit(gatos) +``` + +## Eliminando columnas + +También podemos eliminar columnas en un *data frame*. Hay dos formas de eliminar una columna: por número o nombre de índice. + + +```r +gatos[,-4] +``` + +```{.output} + color peso legusta_la_cuerda +1 mixto 2.1 1 +2 negro 5.0 0 +3 atigrado 3.2 1 +5 carey 3.3 1 +``` + +Observa la coma sin nada antes, lo que indica que queremos mantener todas las filas. + +Alternativamente, podemos quitar la columna usando el nombre del índice. + + +```r +drop <- names(gatos) %in% c("edad") +gatos[,!drop] +``` + +```{.output} + color peso legusta_la_cuerda +1 mixto 2.1 1 +2 negro 5.0 0 +3 atigrado 3.2 1 +5 carey 3.3 1 +``` + +## Añadiendo filas o columnas a un data frame + +La clave que hay que recordar al añadir datos a un *data frame* es que *las columnas son vectores o factores, mientras que las filas son listas*. Podemos pegar dos *data frames* usando `rbind` que significa unir las filas (verticalmente): + + +```r +gatos <- rbind(gatos, gatos) +gatos +``` + +```{.output} + color peso legusta_la_cuerda edad +1 mixto 2.1 1 2 +2 negro 5.0 0 3 +3 atigrado 3.2 1 5 +5 carey 3.3 1 9 +11 mixto 2.1 1 2 +21 negro 5.0 0 3 +31 atigrado 3.2 1 5 +51 carey 3.3 1 9 +``` + +Pero ahora los nombres de las filas *rownames* son complicados. Podemos removerlos y R los nombrará nuevamente, de manera secuencial: + + +```r +rownames(gatos) <- NULL +gatos +``` + +```{.output} + color peso legusta_la_cuerda edad +1 mixto 2.1 1 2 +2 negro 5.0 0 3 +3 atigrado 3.2 1 5 +4 carey 3.3 1 9 +5 mixto 2.1 1 2 +6 negro 5.0 0 3 +7 atigrado 3.2 1 5 +8 carey 3.3 1 9 +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +Puedes crear un nuevo *data frame* desde R con la siguiente sintaxis: + + +```r +df <- data.frame(id = c('a', 'b', 'c'), + x = 1:3, + y = c(TRUE, TRUE, FALSE), + stringsAsFactors = FALSE) +``` + +Crear un data frame que contenga la siguiente información personal: + +- nombre +- apellido +- número favorito + +Luego usa `rbind` para agregar una entrada para la gente sentada alrededor tuyo. +Finalmente, usa `cbind` para agregar una columna con espacio para que cada persona conteste a la siguiente pregunta: "¿Es hora de una pausa?" + +::::::::::::::: solution + +## Solución al Desafío 2 + + +```r +df <- data.frame(first = c('Grace'), + apellido = c('Hopper'), + numero_favorito = c(0), + stringsAsFactors = FALSE) +df <- rbind(df, list('Marie', 'Curie', 238) ) +df <- cbind(df, cafe = c(TRUE,TRUE)) +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Ejemplo realista + +Hasta ahora, hemos visto las manipulaciones básicas que pueden hacerse en un *data frame*. Ahora, vamos a extender esas habilidades con un ejemplo más real. Vamos a importar el **gapminder dataset** que descargamos previamente: + +La función `read.table` se usa para leer datos tabulares que están guardados en un archivo de texto, +donde las columnas de datos están separadas por un signo de puntuación como en los archivos +CSV (donde **csv** es **comma-separated values** en inglés, es decir, valores separados por comas). + +Los signos de puntuación más comunmente usados para separar o delimitar datos en archivos de texto son tabuladores y comas. +Por conveniencia, R provee dos versiones de la función `read.table`. Estas versiones son: `read.csv` +para archivos donde los datos están separados por comas y `read.delim` para archivos donde los datos están separados +por tabuladores. De las tres variantes, `read.csv` es la más comúnmente usada. De ser necesario, es posible sobrescribir +el signo de puntuación usado por defecto para ambas funciones: `read.csv` y `read.delim`. + + +```r +gapminder <- read.csv("data/gapminder-FiveYearData.csv") +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Tips misceláneos + +- Otro tipo de archivo que puedes encontrar es el separado por tabuladores (.tsv). Para especificar este separador, usa `"\t"` o `read.delim()`. + +- Los archivos pueden descargarse de Internet a una carpeta local usando `download.file`. + La función `read.csv` puede ser ejecutada para leer el archivo descargado, por ejemplo: + + +```r +download.file("https://raw.githubusercontent.com/swcarpentry/r-novice-gapminder/gh-pages/_episodes_rmd/data/gapminder-FiveYearData.csv", destfile = "data/gapminder-FiveYearData.csv") +gapminder <- read.csv("data/gapminder-FiveYearData.csv") +``` + +- De manera alternativa, puedes leer los archivos directamente en R, usando una dirección web y `read.csv`. Es importante notar que, si se hace esto último, no habrá una copia local del archivo csv en tu computadora. Por ejemplo, + + +```r +gapminder <- read.csv("https://raw.githubusercontent.com/swcarpentry/r-novice-gapminder/gh-pages/_episodes_rmd/data/gapminder-FiveYearData.csv") +``` + +- Puedes leer directamente planillas de Excel sin necesidad de convertirlas a texto plano usando el paquete [readxl](https://cran.r-project.org/package=readxl). + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Vamos a investigar gapminder un poco; lo primero que hay que hacer siempre es ver cómo se ve el dataset usando `str`: + + +```r +str(gapminder) +``` + +```{.output} +'data.frame': 1704 obs. of 6 variables: + $ country : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... + $ year : int 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ... + $ pop : num 8425333 9240934 10267083 11537966 13079460 ... + $ continent: chr "Asia" "Asia" "Asia" "Asia" ... + $ lifeExp : num 28.8 30.3 32 34 36.1 ... + $ gdpPercap: num 779 821 853 836 740 ... +``` + +También podemos examinar columnas individuales del *data frame* con la función `typeof`: + + +```r +typeof(gapminder$year) +``` + +```{.output} +[1] "integer" +``` + +```r +typeof(gapminder$country) +``` + +```{.output} +[1] "character" +``` + +```r +str(gapminder$country) +``` + +```{.output} + chr [1:1704] "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... +``` + +También podemos interrogar al *data frame* por la información sobre sus dimensiones; +recordando que `str(gapminder)` dijo que había 1704 observaciones de 6 variables en gapminder, ¿qué piensas que el siguiente código producirá y por qué? + + +```r +length(gapminder) +``` + +```{.output} +[1] 6 +``` + +Un intento certero hubiera sido decir que el largo (`length`) de un *data frame* es el número de filas (1704), pero no es el caso; recuerda, un *data frame es una lista de vectores y factors*. + + +```r +typeof(gapminder) +``` + +```{.output} +[1] "list" +``` + +Cuando `length` devuelve 6, es porque gapminder está construida por una lista de 6 columnas. Para conseguir el número de filas, intenta: + + +```r +nrow(gapminder) +``` + +```{.output} +[1] 1704 +``` + +```r +ncol(gapminder) +``` + +```{.output} +[1] 6 +``` + +O, para obtener ambos de una vez: + + +```r +dim(gapminder) +``` + +```{.output} +[1] 1704 6 +``` + +Probablemente queremos saber los nombres de las columnas. Para hacerlo, podemos pedir: + + +```r +colnames(gapminder) +``` + +```{.output} +[1] "country" "year" "pop" "continent" "lifeExp" "gdpPercap" +``` + +A esta altura, es importante preguntarnos si la estructura de R está en sintonía con nuestra intuición y nuestras expectativas, ¿tienen sentido los tipos de datos reportados para cada columna? Si no lo tienen, necesitamos resolver cualquier problema antes de que se conviertan en sorpresas ingratas luego. Podemos hacerlo usando lo que aprendimos sobre cómo R interpreta los datos y la importancia de la estricta consistencia con la que registramos los datos. + +Una vez que estamos contentos con el tipo de datos y que la estructura parece razonable, es tiempo de empezar a investigar nuestros datos. Mira las siguientes líneas: + + +```r +head(gapminder) +``` + +```{.output} + country year pop continent lifeExp gdpPercap +1 Afghanistan 1952 8425333 Asia 28.801 779.4453 +2 Afghanistan 1957 9240934 Asia 30.332 820.8530 +3 Afghanistan 1962 10267083 Asia 31.997 853.1007 +4 Afghanistan 1967 11537966 Asia 34.020 836.1971 +5 Afghanistan 1972 13079460 Asia 36.088 739.9811 +6 Afghanistan 1977 14880372 Asia 38.438 786.1134 +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +También es útil revisar algunas líneas en el medio y el final del **data frame** ¿Cómo harías eso? + +Buscar líneas exactamente en el medio no es tan difícil, pero simplemente revisar algunas lineas al azar es suficiente. ¿cómo harías eso? + +::::::::::::::: solution + +## Solución al desafío 3 + +Para revisar las últimas líneas del *data frame* R tiene una función para esto: + + +```r +tail(gapminder) +``` + +```{.output} + country year pop continent lifeExp gdpPercap +1699 Zimbabwe 1982 7636524 Africa 60.363 788.8550 +1700 Zimbabwe 1987 9216418 Africa 62.351 706.1573 +1701 Zimbabwe 1992 10704340 Africa 60.377 693.4208 +1702 Zimbabwe 1997 11404948 Africa 46.809 792.4500 +1703 Zimbabwe 2002 11926563 Africa 39.989 672.0386 +1704 Zimbabwe 2007 12311143 Africa 43.487 469.7093 +``` + +```r +tail(gapminder, n = 15) +``` + +```{.output} + country year pop continent lifeExp gdpPercap +1690 Zambia 1997 9417789 Africa 40.238 1071.3538 +1691 Zambia 2002 10595811 Africa 39.193 1071.6139 +1692 Zambia 2007 11746035 Africa 42.384 1271.2116 +1693 Zimbabwe 1952 3080907 Africa 48.451 406.8841 +1694 Zimbabwe 1957 3646340 Africa 50.469 518.7643 +1695 Zimbabwe 1962 4277736 Africa 52.358 527.2722 +1696 Zimbabwe 1967 4995432 Africa 53.995 569.7951 +1697 Zimbabwe 1972 5861135 Africa 55.635 799.3622 +1698 Zimbabwe 1977 6642107 Africa 57.674 685.5877 +1699 Zimbabwe 1982 7636524 Africa 60.363 788.8550 +1700 Zimbabwe 1987 9216418 Africa 62.351 706.1573 +1701 Zimbabwe 1992 10704340 Africa 60.377 693.4208 +1702 Zimbabwe 1997 11404948 Africa 46.809 792.4500 +1703 Zimbabwe 2002 11926563 Africa 39.989 672.0386 +1704 Zimbabwe 2007 12311143 Africa 43.487 469.7093 +``` + +Para revisar algunas lineas al azar? + +## sugerencia: Hay muchas maneras de hacer esto + +La solución que presentamos aquí utiliza funciones anidadas, por ejemplo una función es el argumento de otra función. Esto te puede parecer nuevo, pero ya lo haz usado. +Recuerda *my\_dataframe[rows, cols]* imprime el *data frame* con la sección de filas y columnas definidas (incluso puedes seleccionar un rando de filas y columnas usando **:** por ejemplo). Para obtener un número al azar o varios números al azar R tiene una función llamada *sample*. + + +```r +gapminder[sample(nrow(gapminder), 5), ] +``` + +```{.output} + country year pop continent lifeExp gdpPercap +751 Ireland 1982 3480000 Europe 73.100 12618.321 +714 Indonesia 1977 136725000 Asia 52.702 1382.702 +798 Japan 1977 113872473 Asia 75.380 16610.377 +939 Malaysia 1962 8906385 Asia 55.737 2036.885 +318 Comoros 1977 304739 Africa 50.939 1172.603 +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Para que nuestro análisis sea reproducible debemos poner el código en un *script* +al que podremos volver y editar en el futuro. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 4 + +Ve a Archivo -> nuevo -> R script, y crea un script de R llamado load-gapminder.R +para cargar el dataset gapminder. Ponlo en el directorio `scripts/` +y agrégalo al control de versiones. + +Ejecuta el script usando la función `source`, usando el path como su argumento +o apretando el botón de "source" en RStudio. + +::::::::::::::: solution + +## Solución al desafío 4 + +Los contenidos de `scripts/load-gapminder.R`: + + +```r +download.file("https://raw.githubusercontent.com/swcarpentry/r-novice-gapminder/gh-pages/_episodes_rmd/data/gapminder-FiveYearData.csv", destfile = "data/gapminder-FiveYearData.csv") +gapminder <- read.csv(file = "data/gapminder-FiveYearData.csv") +``` + +Para ejecutar el script y cargar los archivos en la variable `gapminder`: + +Para ejecutar el script y cargar los archivos en la variable `gapminder`: + + +```r +source(file = "scripts/load-gapminder.R") +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 5 + +Leer el output de `str(gapminder)` de nuevo; +esta vez, usar lo que has aprendido de factores, listas y vectores, las funciones como `colnames` y `dim` +para explicar qué significa el output de `str`. +Si hay partes que no puedes entender, discútelo con tus compañeros. + +::::::::::::::: solution + +## Solución desafío 5 + +El objeto `gapminder` es un data frame con columnas + +- `country` y `continent` como *factors*. +- `year` como *integer vector*. +- `pop`, `lifeExp`, and `gdpPercap` como *numeric vectors*. + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Usar `cbind()` para agregar una nueva columna a un *data frame* +- Usar `rbind()` para agregar una nueva fila a un *data frame* +- Quitar filas de un *data frame* +- Usar `na.omit()` para remover filas de un *data frame* con valores `NA` +- Usar `levels()` y `as.character()` para explorar y manipular columnas de clase *factor* +- Usar `str()`, `nrow()`, `ncol()`, `dim()`, `colnames()`, `rownames()`, `head()` y `typeof()` para entender la estructura de un *data frame* +- Leer un archivo csv usando `read.csv()` +- Entender el uso de `length()` en un *data frame* + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/06-data-subsetting.md b/06-data-subsetting.md new file mode 100644 index 00000000..53c304d3 --- /dev/null +++ b/06-data-subsetting.md @@ -0,0 +1,1323 @@ +--- +title: Haciendo subconjuntos de datos +teaching: 35 +exercises: 15 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Ser capaz de hacer subconjuntos de vectores, factores, matrices, listas y *data frames*. +- Ser capaz de extraer uno o multiples elementos: por posición, por nombre, o usando operaciones de comparación. +- Ser capaz de saltar y quitar elementos de diferentes estructuras de datos. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo trabajar con subconjuntos de datos en R? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +R dispone de muchas operaciones para generar subconjuntos. Dominarlas +te permitirá hacer fácilmente operaciones muy complejas en cualquier **dataset**. + +Existen seis maneras distintas por las cuales se puede hacer un subconjunto +de datos de cualquier objeto, y existen tres operadores distintos para hacer subconjuntos +para las diferentes estructuras de datos. + +Empecemos con el caballito de batalla de R: un vector numérico. + + +```r +x <- c(5.4, 6.2, 7.1, 4.8, 7.5) +names(x) <- c('a', 'b', 'c', 'd', 'e') +x +``` + +```{.output} + a b c d e +5.4 6.2 7.1 4.8 7.5 +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Vectores atómicos + +En R, un vector puede contener palabras, números o valores lógicos. Estos son +llamados vectores *atómicos* ya que no se pueden simplificar más. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Ya que creamos un vector ejemplo juguemos con él, ¿cómo podemos acceder a su contenido? + +## Accediendo a los elementos del vector usando sus índices + +Para extraer elementos o datos de un vector podemos usar su índice correspondiente, empezando +por uno: + + +```r +x[1] +``` + +```{.output} + a +5.4 +``` + + +```r +x[4] +``` + +```{.output} + d +4.8 +``` + +No lo parece, pero el operador corchetes es una función. Para los vectores +(y las matrices), esto significa "dame el n-ésimo elemento". + +También podemos pedir varios elementos al mismo tiempo: + + +```r +x[c(1, 3)] +``` + +```{.output} + a c +5.4 7.1 +``` + +O podemos tomar un rango del vector: + + +```r +x[1:4] +``` + +```{.output} + a b c d +5.4 6.2 7.1 4.8 +``` + +el operador `:` crea una sucesión de números del valor a la izquierda hasta el de +la derecha. + + +```r +1:4 +``` + +```{.output} +[1] 1 2 3 4 +``` + +```r +c(1, 2, 3, 4) +``` + +```{.output} +[1] 1 2 3 4 +``` + +También podemos pedir el mismo elemento varias veces: + + +```r +x[c(1,1,3)] +``` + +```{.output} + a a c +5.4 5.4 7.1 +``` + +Si pedimos por índices mayores a la longitud del vector, R regresará +un valor faltante. + + +```r +x[6] +``` + +```{.output} + + NA +``` + +Este es un vector de longitud uno que contiene un `NA`, cuyo nombre también es +`NA`. + +Si pedimos el elemento en el índice 0, obtendremos un vector vacío. + + +```r +x[0] +``` + +```{.output} +named numeric(0) +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## La numeración de R comienza en 1 + +En varios lenguajes de programación (C y Python por ejemplo), el primer +elemento de un vector tiene índice 0. En R, el primer elemento tiene el índice 1. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Saltando y quitando elementos + +Si usamos un valor negativo como índice para un vector, R regresará cada elemento *excepto* lo que se ha especificado: + + +```r +x[-2] +``` + +```{.output} + a c d e +5.4 7.1 4.8 7.5 +``` + +También podemos saltar o no mostrar varios elementos: + + +```r +x[c(-1, -5)] # o bien x[-c(1,5)] +``` + +```{.output} + b c d +6.2 7.1 4.8 +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Orden de las operaciones + +Un pequeño obstáculo para los novatos ocurre cuando tratan de saltar rangos +de elementos de un vector. Es natural tratar de filtrar una sucesión de la +siguiente manera: + + +```r +x[-1:3] +``` + +Esto nos devuelve un error algo críptico: + + +```{.error} +Error in x[-1:3]: only 0's may be mixed with negative subscripts +``` + +Pero recuerda el orden de las operaciones. `:` es en realidad una función. Toma +como primer elemento -1 y como segundo 3, por lo que se genera la sucesión +de números: `c(-1, 0, 1, 2, 3)`. + +La solución correcta sería empaquetar la llamada de la función dentro de +paréntesis, de está manera el operador `-` se aplica al resultado: + + +```r +x[-(1:3)] +``` + +```{.output} + d e +4.8 7.5 +``` + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Para quitar los elementos de un vector, será necesario que asignes el resultado +de vuelta a la variable: + + +```r +x <- x[-4] +x +``` + +```{.output} + a b c e +5.4 6.2 7.1 7.5 +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Dado el siguiente código: + + +```r +x <- c(5.4, 6.2, 7.1, 4.8, 7.5) +names(x) <- c('a', 'b', 'c', 'd', 'e') +print(x) +``` + +```{.output} + a b c d e +5.4 6.2 7.1 4.8 7.5 +``` + +Encuentra al menos 3 comandos distintos que produzcan la siguiente salida: + + +```{.output} + b c d +6.2 7.1 4.8 +``` + +Después de encontrar los tres comandos distintos, compáralos con los de tu vecino. ¿Tuvieron distintas estrategias? + +::::::::::::::: solution + +## Solución al desafío 1 + + +```r +x[2:4] +``` + +```{.output} + b c d +6.2 7.1 4.8 +``` + + +```r +x[-c(1,5)] +``` + +```{.output} + b c d +6.2 7.1 4.8 +``` + + +```r +x[c("b", "c", "d")] +``` + +```{.output} + b c d +6.2 7.1 4.8 +``` + + +```r +x[c(2,3,4)] +``` + +```{.output} + b c d +6.2 7.1 4.8 +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Haciendo subconjuntos por nombre + +Podemos extraer elementos usando sus nombres, en lugar de extraerlos por índice: + + +```r +x <- c(a=5.4, b=6.2, c=7.1, d=4.8, e=7.5) # podemos nombrar un vector en la misma línea +x[c("a", "c")] +``` + +```{.output} + a c +5.4 7.1 +``` + +Esta forma es mucho más segura para hacer subconjuntos: las posiciones +de muchos elementos pueden cambiar a menudo cuando estamos creando una cadena +de subconjuntos, ¡pero los nombres siempre permanecen iguales! + +## Creando subconjuntos usando operaciones lógicas + +También podemos usar un vector con elementos lógicos para hacer subconjuntos: + + +```r +x[c(FALSE, FALSE, TRUE, FALSE, TRUE)] +``` + +```{.output} + c e +7.1 7.5 +``` + +Dado que los operadores de comparación (e.g. `>`, `<`, `==`) dan como resultado valores lógicos, +podemos usarlos para crear subconjuntos de manera mas sintética: la siguiente instrucción +tiene el mismo resultado que el anterior. + + +```r +x[x > 7] +``` + +```{.output} + c e +7.1 7.5 +``` + +Explicando un poco lo que sucedió, la instrucción `x>7`, genera un vector +lógico `c(FALSE, FALSE, TRUE, FALSE, TRUE)` y después éste selecciona +los elementos de `x` correspondientes a los valores `TRUE`. + +Podemos usar `==` para imitar el método anterior de indexar con nombre +(recordemos que se usa `==` en vez de `=` para comparar): + + +```r +x[names(x) == "a"] +``` + +```{.output} + a +5.4 +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Combinando condiciones lógicas + +Muchas veces queremos combinar varios criterios lógicos. Por ejemplo, tal vez +queramos encontrar todos los países en Asia *o* (en inglés **or**) Europe *y* (en +inglés **and**) con esperanza de vida en cierto rango. Existen muchas operaciones +para combinar vectores con elementos lógicos en R: + +- `&`, el operador "lógico AND": regresa `TRUE` si tanto la derecha y la izquierda + son `TRUE`. +- `|`, el operador "lógico OR": regresa `TRUE`, si la derecha o la izquierda + (o ambos) son `TRUE`. + +A veces encontrarás `&&` y `̣||` en vez de `&` y `|`. Los operadores de dos caracteres +solo comparan los primeros elementos de cada vector e ignoran las demás elementos. En +general no debes usar los operadores de dos caracteres en el análisis de datos; déjalos +para la programación, i.e. para decir cuando se ejecutara una instrucción. + +- `!`, el operador "lógico NOT": convierte `TRUE` a `FALSE` y `FALSE` a + `TRUE`. Puede negar una sola condición lógica (e.g. `!TRUE` se vuelve + `FALSE`), o un vector **logical** (e.g. `!c(TRUE, FALSE)` se vuelve + `c(FALSE, TRUE)`). + +Más aún, puedes comparar todos los elementos de un vector entre ellos usando +la función `all` (que regresa `TRUE` si todos los elementos del vector son +`TRUE`) y la función `any` (que regresa `TRUE` si uno o más elementos del vector +son `TRUE`). + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +Dado el siguiente código: + + +```r +x <- c(5.4, 6.2, 7.1, 4.8, 7.5) +names(x) <- c('a', 'b', 'c', 'd', 'e') +print(x) +``` + +```{.output} + a b c d e +5.4 6.2 7.1 4.8 7.5 +``` + +Escribe un comando para crear el subconjunto de valores de `x` que sean mayores +a 4 pero menores que 7. + +::::::::::::::: solution + +## Solución al desafío 3 + + +```r +x_subset <- x[x<7 & x>4] +print(x_subset) +``` + +```{.output} + a b d +5.4 6.2 4.8 +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Nombres no únicos + +Debes tener en cuenta que es posible que múltiples elementos en un vector tengan el mismo nombre. (Para un +**data frame**, las columnas pueden tener el mismo nombre ---aunque R intenta evitarlo--- pero los nombres +de las filas deben ser únicos). +Considera estos ejemplos: + + +```r +x <- 1:3 +x +``` + +```{.output} +[1] 1 2 3 +``` + +```r +names(x) <- c('a', 'a', 'a') +x +``` + +```{.output} +a a a +1 2 3 +``` + +```r +x['a'] # solo devuelve el primer valor +``` + +```{.output} +a +1 +``` + +```r +x[names(x) == 'a'] # devuelve todos los tres valores +``` + +```{.output} +a a a +1 2 3 +``` + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Obteniendo ayuda para los operadores + +Recuerda que puedes obtener ayuda para los operadores empaquetándolos entre +comillas: +`help("%in%")` o `?"%in%"`. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Saltarse los elementos nombrados + +Saltarse o eliminar elementos con nombre es un poco más difícil. Si tratamos de omitir un elemento con nombre al negar la cadena, R se queja (de una manera un poco oscura) de que no sabe cómo tomar el valor negativo de una cadena: + + +```r +x <- c(a=5.4, b=6.2, c=7.1, d=4.8, e=7.5) # comenzamos nuevamente nombrando un vector en la misma línea +x[-"a"] +``` + +```{.error} +Error in -"a": invalid argument to unary operator +``` + +Sin embargo, podemos usar el operador `!=` (no igual) para construir un vector +con elementos lógicos, que es lo que nosotros queremos: + + +```r +x[names(x) != "a"] +``` + +```{.output} + b c d e +6.2 7.1 4.8 7.5 +``` + +Saltar varios índices con nombre es un poco más difícil. Supongamos +que queremos excluir los elementos `"a"` y `"c"`, entonces intentamos lo siguiente: + + +```r +x[names(x)!=c("a","c")] +``` + +```{.warning} +Warning in names(x) != c("a", "c"): longer object length is not a multiple of +shorter object length +``` + +```{.output} + b c d e +6.2 7.1 4.8 7.5 +``` + +R hizo *algo*, pero también nos lanzó una advertencia que debemos atender +\-¡y aparentemente *nos dió la respuesta incorrecta*! +(el elemento `"c"` se encuentra todavía en el vector). + +¿Entonces qué hizo el operador `!=` en este caso? Esa es una excelente +pregunta. + +### Reciclando + +Tomemos un momento para observar al operador de comparación en este código: + + +```r +names(x) != c("a", "c") +``` + +```{.warning} +Warning in names(x) != c("a", "c"): longer object length is not a multiple of +shorter object length +``` + +```{.output} +[1] FALSE TRUE TRUE TRUE TRUE +``` + +¿Por qué R devuelve `TRUE` como el tercer elemento de este vector, cuando +`names(x)[3] != "c"` es obviamente falso?. Cuando tú usas `!=`, R trata +de comparar cada elemento de la izquierda con el correspondiente elemento +de la derecha. ¿Qué pasa cuando tu comparas dos elementos de diferentes +longitudes? + +![](fig/06-rmd-inequality.1.png){alt='Inequality testing'} + +Cuando uno de los vectores es más corto que el otro, este se *recicla*: + +![](fig/06-rmd-inequality.2.png){alt='Inequality testing: results of recycling'} + +En este caso R **repite** `c("a", "c")` tantas veces como sea necesario +para emparejar `names(x)`, i.e. tenemos `c("a","c","a","c","a")`. Ya que +el valor reciclado `"a"`no es igual a `names(x)`, el valor de `!=` es +`TRUE`. En este caso, donde el vector de mayor longitud (5) no es múltiplo +del más pequeño (2), R lanza esta advertencia. Si +hubiéramos sido lo suficientemente desafortunados y `names(x)` tuviese seis +elementos, R *silenciosamente* hubiera hecho las cosas incorrectas (i.e., +no lo que deseábamos hacer). Esta regla de reciclaje puede introducir +**bugs** difíciles de encontrar. + +La manera de hacer que R haga lo que en verdad queremos (emparejar *cada uno* +de los elementos del argumento de la izquierda con *todos* los elementos del +argumento de la derecha) es usando el operador `%in%`. El operador `%in%` +toma cada uno de los elementos del argumento de la izquierda, en este caso +los nombres de `x`, y pegunta, "¿este elemento ocurre en el segundo argumento?" +Aquí, como queremos *excluir* los valores, nosotros también necesitamos el +operador `!` para cambiar la inclusión por una *no* inclusión: + + +```r +x[! names(x) %in% c("a","c") ] +``` + +```{.output} + b d e +6.2 4.8 7.5 +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +Seleccionar elementos de un vector que empareje con cualquier valor de +una lista es una tarea muy común en el análisis de datos. Por ejemplo, +el **data set** de *gapminder* contiene las variables `country` y +`continent`, pero no incluye información de la escala. +Supongamos que queremos extraer la información de el +sureste de Asia: ¿cómo podemos escribir una operación que resulte en un +vector lógico que sea `TRUE` para todos los países en el sureste de +Asia y `FALSE` en otros casos? + +Supongamos que se tienen los siguientes datos: + + +```r +seAsia <- c("Myanmar","Thailand","Cambodia","Vietnam","Laos") +## leer los datos de gapminder que bajamos en el episodio 2 +gapminder <- read.csv("data/gapminder-FiveYearData.csv", header=TRUE) +## extraer la columna `country` de la **data frame** (veremos esto luego); +## convertir de factor a caracter; +## y quedarse solo con los elementos no repetidos +countries <- unique(as.character(gapminder$country)) +``` + +Existe una manera incorrecta (usando solamente `==`), la cual te +dará una advertencia (*warning*); una manera enredada de hacerlo +(usando los operadores lógicos `==` y `|`) y una manera elegante +(usando `%in%`). Prueba encontrar esas maneras y explica cómo +funcionan (o no). + +::::::::::::::: solution + +## Solución al desafío 2 + +- La manera **incorrecta** de hacer este problema es `countries==seAsia`. + Esta lanza una advertencia (`"In countries == seAsia : longer object length is not a multiple of shorter object length"`) + y la respuesta incorrecta (un vector con todos los valores `FALSE`), ya + que ninguno de los valores reciclados de `seAsia` se emparejaron correctamente + para coincidir con los valores de `country`. +- La manera **enredada** (pero técnicamente correcta) de resolver + este problema es + + +```r + (countries=="Myanmar" | countries=="Thailand" | + countries=="Cambodia" | countries == "Vietnam" | countries=="Laos") +``` + +(o `countries==seAsia[1] | countries==seAsia[2] | ...`). Esto +da los valores correctos, pero esperamos que veas lo raro que se ve +(¿qué hubiera pasado si hubiéramos querido seleccionar países de una +lista mucho más larga?). + +- La mejor manera de resolver este problema es `countries %in% seAsia`, + la cual es la correcta y la más sencilla de escribir (y leer). + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Manejando valores especiales + +En algún momento encontraremos funciones en R que no pueden manejar valores +faltantes, infinito o datos indefinidos. + +Existen algunas funciones especiales que puedes usar para filtrar estos datos: + +- `is.na` regresa todas las posiciones de un **vector**, **matrix** o **data frame** + que contengan `NA` (o `NaN`) +- de la misma manera, `is.nan` y `is.infinite` hacen lo mismo para `NaN` e `Inf`. +- `is.finite` regresa todas las posiciones de un **vector**, **matrix** o **data frame** + que no contengan `NA`, `NaN` o `Inf`. +- `na.omit` filtra todos los valores faltantes de un vector + +## Haciendo subconjuntos de factores + +Habiendo explorado las distintas manera de hacer subconjuntos de vectores, ¿cómo +podemos hacer subconjuntos de otras estructuras de datos? + +Podemos hacer subconjuntos de factores de la misma manera que con los vectores. + + +```r +f <- factor(c("a", "a", "b", "c", "c", "d")) +f[f == "a"] +``` + +```{.output} +[1] a a +Levels: a b c d +``` + +```r +f[f %in% c("b", "c")] +``` + +```{.output} +[1] b c c +Levels: a b c d +``` + +```r +f[1:3] +``` + +```{.output} +[1] a a b +Levels: a b c d +``` + +Saltar elementos no quita el nivel, incluso cuando no existan datos en esa +categoría del factor: + + +```r +f[-3] +``` + +```{.output} +[1] a a c c d +Levels: a b c d +``` + +## Haciendo subconjuntos de matrices + +También podemos hacer subconjuntos de matrices usando la función `[` En este +caso toma dos argumentos: el primero se aplica a las filas y el segundo +a las columnas: + + +```r +set.seed(1) +m <- matrix(rnorm(6*4), ncol=4, nrow=6) +m[3:4, c(3,1)] +``` + +```{.output} + [,1] [,2] +[1,] 1.12493092 -0.8356286 +[2,] -0.04493361 1.5952808 +``` + +Siempre puedes dejar el primer o segundo argumento vacío para obtener todas las filas +o columnas respectivamente: + + +```r +m[, c(3,4)] +``` + +```{.output} + [,1] [,2] +[1,] -0.62124058 0.82122120 +[2,] -2.21469989 0.59390132 +[3,] 1.12493092 0.91897737 +[4,] -0.04493361 0.78213630 +[5,] -0.01619026 0.07456498 +[6,] 0.94383621 -1.98935170 +``` + +Si quisieramos acceder a solo una fila o una columna, R automáticamente +convertirá el resultado a un vector: + + +```r +m[3,] +``` + +```{.output} +[1] -0.8356286 0.5757814 1.1249309 0.9189774 +``` + +Si quieres mantener la salida como una matriz, necesitas especificar un *tercer* +argumento; `drop = FALSE`: + + +```r +m[3, , drop=FALSE] +``` + +```{.output} + [,1] [,2] [,3] [,4] +[1,] -0.8356286 0.5757814 1.124931 0.9189774 +``` + +A diferencia de los vectores, si tratamos de acceder a una fila o +columna fuera de la matriz, R arrojará un error: + + +```r +m[, c(3,6)] +``` + +```{.error} +Error in m[, c(3, 6)]: subscript out of bounds +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: **Arrays** de más dimensiones + +Cuando estamos lidiando con **arrays** multi-dimensionales, cada uno de los +argumentos de `[` corresponden a una dimensión. Por ejemplo,en un **array** +3D, los primeros tres argumentos corresponden a las filas, columnas y +profundidad. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Como las matrices son vectores, podemos también hacer subconjuntos usando +solo un argumento: + + +```r +m[5] +``` + +```{.output} +[1] 0.3295078 +``` + +Normalmente esto no es tan útil y muchas veces difícil de leer. Sin embargo +es útil notar que las matrices están acomodadas en un formato **column-major** por defecto. Esto significa que los elementos del vector están acomodados por columnas: + + +```r +matrix(1:6, nrow=2, ncol=3) +``` + +```{.output} + [,1] [,2] [,3] +[1,] 1 3 5 +[2,] 2 4 6 +``` + +Si quisieramos llenar una matriz por filas, usamos `byrow=TRUE`: + + +```r +matrix(1:6, nrow=2, ncol=3, byrow=TRUE) +``` + +```{.output} + [,1] [,2] [,3] +[1,] 1 2 3 +[2,] 4 5 6 +``` + +Podemos también hacer subconjuntos de las matrices usando los nombres de +sus filas y de sus columnas en vez de usar sus índices. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 4 + +Dado el siguiente código: + + +```r +m <- matrix(1:18, nrow=3, ncol=6) +print(m) +``` + +```{.output} + [,1] [,2] [,3] [,4] [,5] [,6] +[1,] 1 4 7 10 13 16 +[2,] 2 5 8 11 14 17 +[3,] 3 6 9 12 15 18 +``` + +1. ¿Cuál de los siguientes comandos extraerá los valores 11 y 14? + +A. `m[2,4,2,5]` + +B. `m[2:5]` + +C. `m[4:5,2]` + +D. `m[2,c(4,5)]` + +::::::::::::::: solution + +## Solución al desafío 4 + +D + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Haciendo subconjuntos de listas + +Ahora introduciremos un nuevo operador para hacer subconjuntos. Existen tres +funciones para hacer subconjuntos de listas. Ya las hemos visto cuando +aprendimos los vectores atómicos y las matrices: `[`, `[[` y `$`. + +Usando `[` siempre se obtiene una lista. Si quieres un *subconjunto* de una +lista, pero no quieres *extraer* un elemento, entonces probablemente usarás +`[`. + + +```r +xlist <- list(a = "Software Carpentry", b = 1:10, data = head(mtcars)) +xlist[1] +``` + +```{.output} +$a +[1] "Software Carpentry" +``` + +Esto regresa una *lista de un elemento*. + +Podemos hacer subconjuntos de elementos de la lista de la misma manera que +con los vectores atómicos usando `[`. Las operaciones de comparación sin +embargo no funcionan, ya que no son recursivas, estas probarán la +condición en la estructura de datos de los elementos de la lista, +y no en los elementos individuales de dichas estructuras de datos. + + +```r +xlist[1:2] +``` + +```{.output} +$a +[1] "Software Carpentry" + +$b + [1] 1 2 3 4 5 6 7 8 9 10 +``` + +Para extraer elementos individuales de la lista, tendrás que hacer uso de +la función doble corchete: `[[`. + + +```r +xlist[[1]] +``` + +```{.output} +[1] "Software Carpentry" +``` + +Nota que ahora el resultados es un vector, no una lista. + +No puedes extraer más de un elemento al mismo tiempo: + + +```r +xlist[[1:2]] +``` + +```{.error} +Error in xlist[[1:2]]: subscript out of bounds +``` + +Tampoco puedes usarlo para saltar elementos: + + +```r +xlist[[-1]] +``` + +```{.error} +Error in xlist[[-1]]: invalid negative subscript in get1index +``` + +Pero tú puedes usar los nombres para hacer subconjuntos y extraer elementos: + + +```r +xlist[["a"]] +``` + +```{.output} +[1] "Software Carpentry" +``` + +La función `$` es una manera abreviada para extraer elementos por nombre: + + +```r +xlist$data +``` + +```{.output} + mpg cyl disp hp drat wt qsec vs am gear carb +Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 +Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 +Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 +Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 +Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 +Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 5 + +Dada la siguiente lista: + + +```r +xlist <- list(a = "Software Carpentry", b = 1:10, data = head(mtcars)) +``` + +Usando tu conocimiento para hacer subconjuntos de listas y vectores, extrae +el número 2 de `xlist`. +Pista: el número 2 está contenido en el elemento "b" de la lista. + +::::::::::::::: solution + +## Solución al desafío 5 + + +```r +xlist$b[2] +``` + +```{.output} +[1] 2 +``` + + +```r +xlist[[2]][2] +``` + +```{.output} +[1] 2 +``` + + +```r +xlist[["b"]][2] +``` + +```{.output} +[1] 2 +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 6 + +Dado un modelo lineal: + + +```r +mod <- aov(pop ~ lifeExp, data=gapminder) +``` + +Extrae los grados de libertad residuales (pista: `attributes()` te puede +ayudar) + +::::::::::::::: solution + +## Solución del desafío 6 + + +```r +attributes(mod) ## `df.residual` es uno de los nombres de `mod` +``` + + +```r +mod$df.residual +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Data frames + +Recordemos que las **data frames** son listas, por lo que aplican reglas similares. +Sin embargo estos también son objetos de dos dimensiones: + +`[` con un argumento funcionará de la misma manera que para las listas, +donde cada elemento de la lista corresponde a una columna. El objeto devuelto +será una **data frame**: + + +```r +head(gapminder[3]) +``` + +```{.output} + pop +1 8425333 +2 9240934 +3 10267083 +4 11537966 +5 13079460 +6 14880372 +``` + +Similarmente, `[[` extraerá *una sola columna*: + + +```r +head(gapminder[["lifeExp"]]) +``` + +```{.output} +[1] 28.801 30.332 31.997 34.020 36.088 38.438 +``` + +Con dos argumentos, `[` se comporta de la misma manera que para las matrices: + + +```r +gapminder[1:3,] +``` + +```{.output} + country year pop continent lifeExp gdpPercap +1 Afghanistan 1952 8425333 Asia 28.801 779.4453 +2 Afghanistan 1957 9240934 Asia 30.332 820.8530 +3 Afghanistan 1962 10267083 Asia 31.997 853.1007 +``` + +Si nuestro subconjunto es una sola fila, el resultado será una **data frame** +(porque los elementos son de distintos tipos): + + +```r +gapminder[3,] +``` + +```{.output} + country year pop continent lifeExp gdpPercap +3 Afghanistan 1962 10267083 Asia 31.997 853.1007 +``` + +Pero para una sola columna el resultado será un vector (esto puede cambiarse +con el tercer argumento, `drop = FALSE`). + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 7 + +Corrige cada uno de los siguientes errores para hacer subconjuntos de +**data frames**: + +1. Extraer observaciones colectadas en el año 1957 + + + ```r + gapminder[gapminder$year = 1957,] + ``` + +2. Extraer todas las columnas excepto de la 1 a la 4 + + +```r + gapminder[,-1:4] +``` + +3. Extraer las filas donde la esperanza de vida es mayor a 80 años + + + ```r + gapminder[gapminder$lifeExp > 80] + ``` + +4. Extraer la primer fila, y la cuarta y quinta columna + (`lifeExp` y `gdpPercap`). + + + ```r + gapminder[1, 4, 5] + ``` + +5. Avanzado: extraer las filas que contienen información para los años 2002 + y 2007 + + + ```r + gapminder[gapminder$year == 2002 | 2007,] + ``` + +::::::::::::::: solution + +## Solución del desafío 7 + +Corrige cada uno de los siguientes errores para hacer subconjuntos de +**data frames**: + +1. Extraer observaciones colectadas en el año 1957 + + + ```r + # gapminder[gapminder$year = 1957,] + gapminder[gapminder$year == 1957,] + ``` + +2. Extraer todas las columnas excepto de la 1 a la 4 + + + ```r + # gapminder[,-1:4] + gapminder[,-c(1:4)] + ``` + +3. Extraer las filas donde la esperanza de vida es mayor a 80 años + + + ```r + # gapminder[gapminder$lifeExp > 80] + gapminder[gapminder$lifeExp > 80,] + ``` + +4. Extraer la primer fila, y la cuarta y quinta columna + (`lifeExp` y `gdpPercap`). + + + ```r + # gapminder[1, 4, 5] + gapminder[1, c(4, 5)] + ``` + +5. Avanzado: extraer las filas que contienen información para los años 2002 + y 2007 + + + ```r + # gapminder[gapminder$year == 2002 | 2007,] + gapminder[gapminder$year == 2002 | gapminder$year == 2007,] + gapminder[gapminder$year %in% c(2002, 2007),] + ``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 8 + +1. ¿Por qué `gapminder[1:20]` regresa un error? ¿En qué difiere de `gapminder[1:20, ]`? + +2. Crea un `data.frame` llamado `gapminder_small` que solo contenga las filas del 1 + al 9 y del 19 al 23. Puedes hacerlo en uno o dos pasos. + +::::::::::::::: solution + +## Solución al desafío 8 + +1. `gapminder` es un `data.frame` por lo que para hacer un subconjunto necesita dos + dimensiones. `gapminder[1:20, ]` genera un subconjunto de los datos de las primeras + 20 filas y todas las columnas. + +2. + +```r +gapminder_small <- gapminder[c(1:9, 19:23),] +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Los índices en R comienzan con 1, no con 0. +- Acceso a un elemento por posición usando `[]`. +- Acceso a un rango de datos usando `[min:max]`. +- Acceso a subconjuntos arbitrarios usando `[c(...)]`. +- Usar operaciones lógicas y vectores lógicos para acceder a subconjuntos de datos + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/07-control-flow.md b/07-control-flow.md new file mode 100644 index 00000000..ff58b95e --- /dev/null +++ b/07-control-flow.md @@ -0,0 +1,641 @@ +--- +title: Control de flujo +teaching: 45 +exercises: 20 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Escribir declaraciones condicionales utilizando `if()` y `else()`. +- Escribir y entender los bucles con `for()`. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo hacer elecciones dependiendo de mis datos en R? +- ¿Cómo puedo repetir operaciones en R? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Cuando estamos programando puede que queramos controlar el flujo de nuestras acciones. Esto se puede realizar +estableciendo acciones que ocurran solo si se cumple una condición o un conjunto de condiciones. +A su vez, podemos hacer que una acción ocurra un número determinado de veces. + +Hay varias maneras de controlar el flujo en R. +Para declaraciones condicionales, los enfoques más comúnmente utilizados son los **constructs**: + + +```r +# if +if (la condición es verdad) { + realizar una acción +} + +# if ... else +if (la condición es verdad) { + realizar una acción +} else { # es decir, si la condición es falsa, + realizar una acción alternativa +} +``` + +Digamos, por ejemplo, que queremos que R imprima un mensaje si una variable `x` tiene un valor en particular: + + +```r +x <- 8 + +if (x >= 10) { + print("x es mayor o igual que 10") +} + +x +``` + +```{.output} +[1] 8 +``` + +La sentencia **print** "x es mayor o igual que 10" no aparece en la consola porque x no es mayor o igual a 10. Para imprimir un mensaje diferente para numeros menores a 10, podemos agregar una sentencia **else** + + +```r +x <- 8 + +if (x >= 10) { + print("x es mayor o igual a 10") +} else { + print("x es menor a 10") +} +``` + +```{.output} +[1] "x es menor a 10" +``` + +También podemos testear múltiples condiciones usando **else if** + + +```r +x <- 8 + +if (x >= 10) { + print("x es mayor o igual a 10") +} else if (x > 5) { + print("x es mayor a 5, pero menor a 10") +} else{ + print("x es menor a 5") +} +``` + +```{.output} +[1] "x es mayor a 5, pero menor a 10" +``` + +**Importante:** cuando R evalúa las condiciones dentro de `if()` esta buscando +elementos lógicos como `TRUE` o `FALSE`. Entender esto puede ser un dolor de cabeza para +los principiantes. Por ejemplo: + + +```r +x <- 4 == 3 +if (x) { + "4 igual a 3" +} else { + "4 no es igual a 3" +} +``` + +```{.output} +[1] "4 no es igual a 3" +``` + +Como podemos observar se muestra el mensaje es igual porque el vector x es `FALSE` + + +```r +x <- 4 == 3 +x +``` + +```{.output} +[1] FALSE +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Usa una declaración `if()` para mostrar un mensaje adecuado +reportando si hay algún registro del año 2002 en +el **dataset** **`gapminder`**. +Luego haz lo mismo para el año 2012. + +::::::::::::::: solution + +## Solución al Desafío 1 + +Primero veremos una solución al Desafío 1 que no usa la función `any()`. +Primero obtenemos un vector lógico que describe que el elemento `gapminder$year` es igual a `2002`: + + +```r +gapminder[(gapminder$year == 2002),] +``` + +Luego, contamos el número de filas del data.frame `gapminder` que corresponde al año 2002: + + +```r +rows2002_number <- nrow(gapminder[(gapminder$year == 2002),]) +``` + +La presencia de cualquier registro para el año 2002 es equivalente a la petición de que `rows2002_number` sea mayor o igual a uno: + + +```r +rows2002_number >= 1 +``` + +Entonces podríamos escribir: + + +```r +if(nrow(gapminder[(gapminder$year == 2002),]) >= 1){ + print("Se encontraron registro(s) para el año 2002.") +} +``` + +Todo esto se puede hacer más rápido con `any()`. En dicho caso la condición lógica se puede expresar como: + + +```r +if(any(gapminder$year == 2002)){ + print("Se encontraron registro(s) para el año 2002.") +} +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +¿Alguien recibió un mensaje de advertencia como este? + + +```{.error} +Error in eval(expr, envir, enclos): object 'gapminder' not found +``` + +Si tu condición se evalúa como un vector con más de un elemento lógico, +la función `if()` todavía se ejecutará, pero solo evaluará la condición en el primer +elemento. Aquí debes asegurarte que tu condición sea de longitud 1. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Tip: `any()` y `all()` + +La función `any()` devolverá TRUE si hay al menos un valor +TRUE dentro del vector, en caso contrario devolverá `FALSE`. +Esto se puede usar de manera similar al operador `%in%`. +La función `all()`, como el nombre sugiere, devolvera `TRUE` siempre y cuando todos los valores en +el vector son `TRUE`. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Operaciones repetidas + +Si quieres iterar sobre un conjunto de valores, el orden de la iteración es importante y debes realizar +la misma operación en cada uno, un bucle `for()` es lo que estas buscando. +Vimos los bucles `for()` en las lecciones anteriores de terminal. Si bien esta es la +operación de bucle más flexible es también la más difícil de usar correctamente. +Evita usar bucles `for()` a menos que el orden de la iteración sea importante +como cuando el cálculo de cada iteración dependa del resultado de la iteración previa. + +La estructura básica de un bucle `for()` es: + + +```r +for(iterador in conjunto de valores){ + haz alguna acción +} +``` + +Por ejemplo: + + +```r +for(i in 1:10){ + print(i) +} +``` + +```{.output} +[1] 1 +[1] 2 +[1] 3 +[1] 4 +[1] 5 +[1] 6 +[1] 7 +[1] 8 +[1] 9 +[1] 10 +``` + +El rango `1:10` crea un vector sobre la marcha; puedes iterar +sobre cualquier otro vector también. + +Podemos usar un bucle `for()` anidado con otro bucle `for()` para iterar sobre dos cosas +a la vez. + + +```r +for(i in 1:5){ + for(j in c('a', 'b', 'c', 'd', 'e')){ + print(paste(i,j)) + } +} +``` + +```{.output} +[1] "1 a" +[1] "1 b" +[1] "1 c" +[1] "1 d" +[1] "1 e" +[1] "2 a" +[1] "2 b" +[1] "2 c" +[1] "2 d" +[1] "2 e" +[1] "3 a" +[1] "3 b" +[1] "3 c" +[1] "3 d" +[1] "3 e" +[1] "4 a" +[1] "4 b" +[1] "4 c" +[1] "4 d" +[1] "4 e" +[1] "5 a" +[1] "5 b" +[1] "5 c" +[1] "5 d" +[1] "5 e" +``` + +En lugar de mostrar los resultados en la pantalla podríamos guardarlos en un nuevo objeto. + + +```r +output_vector <- c() +for(i in 1:5){ + for(j in c('a', 'b', 'c', 'd', 'e')){ + temp_output <- paste(i, j) + output_vector <- c(output_vector, temp_output) + } +} +output_vector +``` + +```{.output} + [1] "1 a" "1 b" "1 c" "1 d" "1 e" "2 a" "2 b" "2 c" "2 d" "2 e" "3 a" "3 b" +[13] "3 c" "3 d" "3 e" "4 a" "4 b" "4 c" "4 d" "4 e" "5 a" "5 b" "5 c" "5 d" +[25] "5 e" +``` + +Este enfoque puede ser útil, pero aumentar o incrementar tus resultados (es decir, construir el objeto resultante de forma incremental) es computacionalmente ineficiente por lo que conviene evitarlo cuando estés iterando a través de muchos valores. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Tip: no incrementes tus resultados + +Una de las cosas que más frecuentemente hace tropezar tanto a los principiantes como +a los usuarios experimentados de R es la construcción de un objeto de resultados +(vector, lista, matriz, data frame) a medida que tu bucle for progresa. +Las computadoras son muy malas para manejar esto lo cual puede hacer que tus cálculos +se enlentezcan rápidamente. En este caso es mejor definir un objeto de +resultados vacío con las dimensiones apropiadas. +Si sabes que el resultado final se almacenará en una matriz como la +anterior es una buena idea crear una matriz vacía con 5 filas y 5 columnas y luego en cada iteración +almacenar los resultados en la ubicación adecuada. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Una mejor manera es definir el objeto de salida (vacío) antes de completar los valores. +Aunque para este ejemplo parece más complicado, es aún más eficiente. + + +```r +output_matrix <- matrix(nrow=5, ncol=5) +j_vector <- c('a', 'b', 'c', 'd', 'e') +for(i in 1:5){ + for(j in 1:5){ + temp_j_value <- j_vector[j] + temp_output <- paste(i, temp_j_value) + output_matrix[i, j] <- temp_output + } +} +output_vector2 <- as.vector(output_matrix) +output_vector2 +``` + +```{.output} + [1] "1 a" "2 a" "3 a" "4 a" "5 a" "1 b" "2 b" "3 b" "4 b" "5 b" "1 c" "2 c" +[13] "3 c" "4 c" "5 c" "1 d" "2 d" "3 d" "4 d" "5 d" "1 e" "2 e" "3 e" "4 e" +[25] "5 e" +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Tip: Bucles While + +Algunas veces tendrás la necesidad de repetir una operación hasta que +cierta condición se cumpla. Puedes hacer esto con un bucle `while()`. + + +```r +while(mientras esta condición es verdad){ + haz algo +} +``` + +A modo de ejemplo aquí hay un bucle while que genera números aleatorios a +partir de una distribución uniforme (la función `runif()` ) entre 0 y 1 hasta +que obtiene uno que es menor a 0.1. + + +```r +z <- 1 +while(z > 0.1){ + z <- runif(1) + print(z) +} +``` + +Los bucles `while()` no siempre serán la elección apropiada. Debes ser +particularmente cuidadoso de que tu condición se cumpla y no terminar en un +bucle infinito. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +Compara los objetos output\_vector y output\_vector2. ¿Son lo mismo? Si no, ¿por qué no? +¿Cómo cambiarías el último bloque de código para hacer output\_vector2 igual a output\_vector? + +::::::::::::::: solution + +## Solución al Desafío 2 + +Podemos verificar si dos vectores son idénticos usando la función `all()` : + + +```r +all(output_vector == output_vector2) +``` + +Sin embargo todos los elementos de `output_vector` se pueden encontrar en `output_vector2`: + + +```r +all(output_vector %in% output_vector2) +``` + +y viceversa: + + +```r +all(output_vector2 %in% output_vector) +``` + +Por lo tanto, los elementos en `output_vector` y `output_vector2` están en distinto orden. +Esto es porque `as.vector ()` genera los elementos leyendo la matriz de entrada por columnas. +Si observamos `output_matrix` podemos notar que deseamos obtener sus elementos ordenados por filas. +La solución es transponer la `output_matrix`. Podemos hacerlo llamando a la función de transposición +`t ()` o ingresando los elementos en el orden correcto. +La primera solución requiere cambiar el original + + +```r +output_vector2 <- as.vector(output_matrix) +``` + +por + + +```r +output_vector2 <- as.vector(t(output_matrix)) +``` + +La segunda solución requiere cambiar + + +```r +output_matrix[i, j] <- temp_output +``` + +por + + +```r +output_matrix[j, i] <- temp_output +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +Escribe un **script** que a través de bucles recorra los datos `gapminder` por continente e imprima +si la esperanza de vida media es menor o mayor de 50 +años. + +::::::::::::::: solution + +## Solución al Desafío 3 + +**Paso 1**: Queremos asegurarnos de que podamos extraer todos los valores únicos del vector continente + + +```r +gapminder <- read.csv("data/gapminder-FiveYearData.csv") +unique(gapminder$continent) +``` + +**Paso 2**: También tenemos que recorrer cada uno de estos continentes y calcular la esperanza de vida promedio para cada "subconjunto" de datos. +Podemos hacer eso de la siguiente manera: + +1. Recorre cada uno de los valores únicos de 'continente' +2. Para cada valor de continente, crea una variable temporal que almacene la vida útil para ese subconjunto, +3. Regresar la expectativa de vida calculada al usuario imprimiendo el resultado: + + +```r +for( iContinent in unique(gapminder$continent) ){ + tmp <- mean(subset(gapminder, continent==iContinent)$lifeExp) + cat("Average Life Expectancy in", iContinent, "is", tmp, "\n") + rm(tmp) +} +``` + +**Paso 3**: El ejercicio solo requiere que se imprima el resultado si la expectativa de vida promedio es menor a 50 o superior a 50. Por lo tanto, debemos agregar una condición 'if' antes de imprimir, lo cual evalúa si la expectativa de vida promedio calculada es superior o inferior a un umbral, e imprime una salida condicional en el resultado. +Necesitamos corregir (3) desde arriba: + +3a. Si la esperanza de vida calculada es menor que algún umbral (50 años), devuelve el continente e imprime la frase "la esperanza de vida es menor que el umbral", de lo contrario devuelve el continente e imprime la frase "la esperanza de vida es mayor que el umbral": + + +```r +thresholdValue <- 50 + +for( iContinent in unique(gapminder$continent) ){ + tmp <- mean(subset(gapminder, continent==iContinent)$lifeExp) + + if(tmp < thresholdValue){ + cat("Average Life Expectancy in", iContinent, "is less than", thresholdValue, "\n") + } + else{ + cat("Average Life Expectancy in", iContinent, "is greater than", thresholdValue, "\n") + } # end if else condition + rm(tmp) + } # end for loop +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 4 + +Modifica el **script** del Desafío 4 para obtener resultados para cada uno de los +países. En esta oportunidad que imprima si la esperanza de vida es menor que 50, se encuentra entre 50 y 70 o es mayor que 70. + +::::::::::::::: solution + +## Solución al Desafío 4 + +Modificamos nuestra solución al Reto 3 agregando ahora dos umbrales, `lowerThreshold` y` upperThreshold` y extendiendo nuestras declaraciones if-else: + + +```r + lowerThreshold <- 50 + upperThreshold <- 70 + +for( iCountry in unique(gapminder$country) ){ + tmp <- mean(subset(gapminder, country==iCountry)$lifeExp) + + if(tmp < lowerThreshold){ + cat("Average Life Expectancy in", iCountry, "is less than", lowerThreshold, "\n") + } + else if(tmp > lowerThreshold && tmp < upperThreshold){ + cat("Average Life Expectancy in", iCountry, "is between", lowerThreshold, "and", upperThreshold, "\n") + } + else{ + cat("Average Life Expectancy in", iCountry, "is greater than", upperThreshold, "\n") + } + rm(tmp) +} +``` + +```{.error} +Error in eval(expr, envir, enclos): object 'gapminder' not found +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 5 - Avanzado + +Escribir un script que con un bucle recorra cada país en el **dataset** +**`gapminder`**, probar si el país comienza con una 'B' y graficar la +esperanza de vida contra el tiempo como un gráfico de líneas si la esperanza +de vida media es menor de 50 años. + +::::::::::::::: solution + +## Solución para el Desafío 5 + +Lo primero que vamos a hacer es usar el comando `grep` que se introdujo en +la lección Shell de Unix para encontrar países que comiencen con" B "." + +Si seguimos la lección de Shell de Unix podríamos vernos tentados de probar +lo siguiente + + +```r +grep("^B", unique(gapminder$country)) +``` + +Pero cuando evaluamos este comando obtenemos los índices de la variable del +factor `country` que comienza con "B". +Para obtener los valores, debemos agregar la opción `value = TRUE` al +comando` grep`: + + +```r +grep("^B", unique(gapminder$country), value=TRUE) +``` + +A continuación almacenaremos estos países en una variable llamada +candidateCountries y luego con un bucle recorreremos cada entrada en la +variable. + +Dentro del bucle se evaluará la expectativa de vida promedio para cada país +y de ser menor a 50 usamos un gráfico base para trazar la evolución de la +expectativa de vida promedio: + + +```r +thresholdValue <- 50 +candidateCountries <- grep("^B", unique(gapminder$country), value=TRUE) + +for( iCountry in candidateCountries){ + tmp <- mean(subset(gapminder, country==iCountry)$lifeExp) + + if(tmp < thresholdValue){ + cat("Average Life Expectancy in", iCountry, "is less than", + thresholdValue, "plotting life expectancy graph... \n") + + with(subset(gapminder, country==iCountry), + plot(year,lifeExp, + type="o", + main = paste("Life Expectancy in", iCountry, "over time"), + ylab = "Life Expectancy", + xlab = "Year" + ) # end plot + ) # end with + } # end for loop + rm(tmp) + } +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Usar `if` y `else` para realizar elecciones. +- Usar `for` para operaciones repetidas. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/08-plot-ggplot2.md b/08-plot-ggplot2.md new file mode 100644 index 00000000..d9f214a8 --- /dev/null +++ b/08-plot-ggplot2.md @@ -0,0 +1,554 @@ +--- +title: Creando gráficas con calidad para publicación con ggplot2 +teaching: 60 +exercises: 20 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Ser capaz de utilizar ggplot2 para generar gráficos con calidad para publicación. +- Entender la gramática básica de los gráficos, incluyendo estética y capas geométricas, agregando estadísticas, transformando las escalas y los colores, o dividiendo por grupos. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo crear gráficos con calidad para publicación en R? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +Graficar nuestros datos es una de las mejores maneras +para explorarlos y para observar las relaciones que existen entre las variables. + +En R existen tres sistemas principales encargados de hacer gráficos, +el sistema de ploteo [base], el paquete [lattice] +y el paquete [ggplot2]. + +Hoy aprenderemos acerca de **`ggplot2`**, que permite de manera sencilla crear gráficos +complejos a partir de un conjunto de datos. Este paquete provee una estructura para que podamos especificar +qué variables graficar, cómo deben ser presentadas y otras propiedades visuales generales +([consulta la guía rápida de funciones](https://raw.githubusercontent.com/rstudio/cheatsheets/master/translations/spanish/data-visualization_es.pdf)). + +De esta manera, sólo necesitamos realizar cambios mínimos si los datos sufren alguna modificación +o si decidimos pasar, por ejemplo, de un gráfico de barras a un diagrama de dispersión. +Esto ayuda a crear gráficos con calidad para publicación con pocos ajustes adicionales. + +**`ggplot2`** se basa en la *gramática de gráficos*, una idea que plantea que +cualquier gráfico puede expresarse a partir de la combinación de estos componentes: +un conjunto de **datos**, un **sistema de coordenadas** y un conjunto de **geoms** (que determinan la representación visual de los datos). + +La clave para entender **`ggplot2`** es pensar en una figura como un conjunto de capas. +Esta idea podría resultarte familiar si has usado un programa de edición de imágenes como +Photoshop, Illustrator o Inkscape. Esto quiere decir que los gráficos de **`ggplot2`** +se construyen paso a paso agregando nuevos elementos o capas, +resultando en una gran flexibilidad para la personalización de los mismos. + +Para construir un ggplot, emplearemos esta plantilla básica que puede usarse para distintos tipos de +gráficos: + +``` +ggplot(data = , mapping = aes()) + () +``` + +- Usa la función `ggplot()` para vincular el gráfico a un conjunto de datos específico a través + del argumento `data`. A las funciones de **`ggplot2`** les gusta trabajar con datos en *formato largo*, es decir, una columna para cada variable y una fila para cada observación. Tener datos bien estructurados te ahorrará mucho tiempo a la hora de realizar gráficos con **`ggplot2`**. Además, todos los argumentos + que le pasemos a la función `ggplot()` serán considerados como opciones *globales* en nuestro gráfico, + lo cual significa que estas opciones son válidas para todas sus capas: + + + + +```r +library("ggplot2") +ggplot(data = gapminder) +``` + +- Define un mapeo (usando la función `aes()` dentro de `ggplot()`) para seleccionar las variables a graficar y especificar cómo deben ser presentadas, por ejemplo, en los ejes x/y o como característicales tales como tamaño, forma, color, etc. `aes()` le dice a `ggplot` cómo se relaciona cada una de las variables en los **datos** con las propiedades + **aesthetic** (estéticas) de la figura. En este caso, le decimos a `ggplot` que queremos graficar la columna "gdpPercap" del **data frame** gapminder en el eje X, y la columna + "lifeExp" en el eje Y. Nota que no necesitamos indicar explícitamente estas columnas en la función `aes` + (e.g. `x = gapminder[, "gdpPercap"]`), ¡esto es debido a que `ggplot` es suficientemente listo para + buscar esa columna en los **datos**!: + + +```r +ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp)) +``` + +- Agrega *geoms*, que indican cómo se representan de los datos en el gráfico (puntos, líneas, barras). **`ggplot2`** ofrece muchos geoms diferentes, algunos comúnmente utilizados son: + + ``` + * `geom_point()` para diagramas de dispersión, gráficos de puntos, etc. + * `geom_boxplot()` para diagramas de caja y bigotes. + * `geom_line()` para líneas de tendencias, series de tiempo, etc. + ``` + + Para agregar un geom, usa el operador `+`. ¡Podemos agregar varios geoms unidos a través de múltiples operadores `+`! Observa que en la figura anterior, llamar a la función **`ggplot`** no fue suficiente para obtener un gráfico, debemos agregar un geom. Podemos usar **`geom_point`** para representar visualmente la relación entre **x** y **y** como un gráfico de dispersión de puntos (**scatterplot**). + + +```r +ggplot(data = gapminder, mapping = aes(x = gdpPercap, y = lifeExp)) + + geom_point() +``` + + + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Modifica el ejemplo anterior de manera que en la figura se muestre +como la esperanza de vida ha cambiado a través del tiempo: + + +```r +ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) + geom_point() +``` + +Pista: El **dataset** gapminder tiene una columna llamada "year", la cual +debe aparecer en el eje X. + +::::::::::::::: solution + +## Solución al desafío 1 + +Modifica el ejemplo de manera que en la figura se muestre +como la esperanza de vida ha cambiado a través del tiempo: + +Esta es una posible solución: + + +```r +ggplot(data = gapminder, aes(x = year, y = lifeExp)) + geom_point() +``` + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +En los ejemplos y desafíos anteriores hemos usado la función `aes` para decirle al `geom_point` +cuáles serán las posiciones **x** y **y** para cada punto. Otra propiedad **aesthetic** que podemos modificar +es el *color*. Modifica el código del desafío anterior para **colorear** los puntos de acuerdo a la columna +"continent". ¿Qué tendencias observas en los datos? ¿Son lo que esperabas? + +::::::::::::::: solution + +## Solución al desafío 2 + +En los ejemplos y desafios anteriores hemos usado la función `aes` para decirle al `geom_point` +cuáles serán las posiciones **x** y **y** para cada punto. Otra propiedad **aesthetic** que podemos modificar +es el *color*. Modifica el código del desafío anterior para **colorear** los puntos de acuerdo a la columna +"continent". ¿Qué tendencias observas en los datos? ¿Son lo que esperabas? + + +```r +ggplot(data = gapminder, aes(x = year, y = lifeExp, color=continent)) + + geom_point() +``` + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Capas + +Un gráfico de dispersión probablemente no es la mejor manera de visualizar el cambio a través del tiempo. +En vez de eso, vamos a decirle a `ggplot` que queremos visualizar los datos como un diagrama de línea (line plot): + + +```r +ggplot(data = gapminder, aes(x=year, y=lifeExp, by=country, color=continent)) + + geom_line() +``` + + + +En vez de agregar una capa `geom_point`, hemos agregado una capa `geom_line`. +Además, hemos agregado el argumento **aesthetic** **by**, el cual le dice a `ggplot` que +debe dibujar una línea para cada país. + +Pero, ¿qué pasa si queremos visualizar ambos, puntos y líneas en la misma gráfica? +Simplemente tenemos que agregar otra capa al gráfico: + + +```r +ggplot(data = gapminder, aes(x=year, y=lifeExp, by=country, color=continent)) + + geom_line() + geom_point() +``` + + + +Es importante notar que cada capa se dibuja encima de la capa anterior. En este ejemplo, +los puntos se han dibujado *sobre* las líneas. A continuación observamos una demostración: + + +```r +ggplot(data = gapminder, aes(x=year, y=lifeExp, by=country)) + + geom_line(aes(color=continent)) + geom_point() +``` + + + +En este ejemplo, el mapeo **aesthetic** de **color** se ha movido de las opciones globales de la gráfica en +`ggplot` a la capa `geom_line` y, por lo tanto, ya no es válido para los puntos. +Ahora podemos ver claramente que los puntos se dibujan sobre las líneas. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Asignando un **aesthetic** a un valor en vez de a un mapeo + +Hasta ahora, hemos visto cómo usar un **aesthetic** (como **color**) como un *mapeo* entre una variable de los datos +y su representación visual. Por ejemplo, cuando usamos `geom_line(aes(color=continent))`, ggplot le asignará +un color diferente a cada continente. +Pero, ¿qué tal si queremos cambiar el color de todas las líneas a azul? Podrías pensar que +`geom_line(aes(color="blue"))` debería funcionar, pero no es así. Dado que no queremos crear un mapeo hacia una variable +específica, simplemente debemos cambiar la especificación de color afuera de la función `aes()`, de esta manera: +`geom_line(color="blue")`. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +Intercambia el orden de las capas de los puntos y líneas del ejemplo anterior. ¿Qué sucede? + +::::::::::::::: solution + +## Solución a desafío 3 + +Intercambia el orden de las capas de los puntos y líneas del ejemplo anterior. ¿Qué sucede? + + +```r +ggplot(data = gapminder, aes(x=year, y=lifeExp, by=country)) + + geom_point() + geom_line(aes(color=continent)) +``` + + + +¡Las líneas ahora están dibujadas sobre los puntos! + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Transformaciones y estadísticas + +`ggplot` también facilita sobreponer modelos estadísticos a los datos. +Para demostrarlo regresaremos a nuestro primer ejemplo: + + +```r +ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp, color=continent)) + + geom_point() +``` + + + +En este momento es difícil ver las relaciones entre los puntos debido a algunos +valores altamente atípicos de la variable GDP per capita. Podemos cambiar la escala de unidades del eje X +usando las funciones de **escala**. Estas funciones controlan la relación entre los valores +de los datos y los valores visuales de un **aesthetic**. También podemos modificar la transparencia +de los puntos, usando la función *alpha*, la cual es especialmente útil cuando tienes una +gran cantidad de datos fuertemente conglomerados. + + +```r +ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) + + geom_point(alpha = 0.5) + scale_x_log10() +``` + + + +La función `log10` aplica una transformación sobre los valores de la columna "gdpPercap" +antes de presentarlos en el gráfico, de manera que cada múltiplo de 10 ahora +corresponde a un incremento de 1 en la escala transformada, e.g. un GDP per capita de 1,000 +se convierte en un 3 en el eje Y, un valor de 10,000 corresponde a un valor de 4 en el eje Y, y así sucesivamente. +Esto facilita visualizar la dispersión de los datos sobre el eje X. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia Recordatorio: Asignando un **aesthetic** a un valor en vez de a un mapeo + +Nota que usamos `geom_point(alpha = 0.5)`. Como menciona la sugerencia anterior, +cambiar una especificación afuera de la función `aes()` causará que este valor sea usado +para todos los puntos, que es exactamente lo que queremos en este caso. Sin embargo, como cualquier otra +especificación **aesthetic**, *alpha* puede ser mapeado hacia una variable de los datos. Por ejemplo, +podemos asignar una transparencia diferente a cada continente usando `geom_point(aes(alpha = continent))`. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Podemos ajustar una relación simple a los datos agregando otra capa, +`geom_smooth`: + + +```r +ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) + + geom_point() + scale_x_log10() + geom_smooth(method="lm") +``` + +```{.output} +`geom_smooth()` using formula = 'y ~ x' +``` + + + +Podemos hacer la línea más gruesa *configurando* el argumento **aesthetic** **tamaño** en la capa `geom_smooth`: + + +```r +ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) + + geom_point() + scale_x_log10() + geom_smooth(method="lm", size=1.5) +``` + +```{.warning} +Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0. +ℹ Please use `linewidth` instead. +This warning is displayed once every 8 hours. +Call `lifecycle::last_lifecycle_warnings()` to see where this warning was +generated. +``` + +```{.output} +`geom_smooth()` using formula = 'y ~ x' +``` + + + +Existen dos formas en las que un *aesthetic* puede ser especificado. Aquí *configuramos* el +**aesthetic** **tamaño** pasándolo como un argumento a `geom_smooth`. Previamente en la lección +habíamos usado la función `aes` para definir un *mapeo* entre alguna variable de los datos y su representación visual. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 4a + +Modifica el color y el tamaño de los puntos en la capa puntos en el ejemplo anterior + +Pista: No uses la función `aes`. + +::::::::::::::: solution + +## Solución al desafío 4a + +Modifica el color y el tamaño de los puntos en la capa puntos en el ejemplo anterior + +Pista: No uses la función `aes`. + + +```r +ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp)) + + geom_point(size=3, color="orange") + scale_x_log10() + + geom_smooth(method="lm", size=1.5) +``` + +```{.output} +`geom_smooth()` using formula = 'y ~ x' +``` + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 4b + +Modifica tu solución al Desafío 4a de manera que ahora los puntos +tengan una forma diferente y estén coloreados de acuerdo al continente +incluyendo líneas de tendencia. + +Pista: El argumento color puede ser usado dentro de **aesthetic** + +::::::::::::::: solution + +## Solución al desafío 4b + +Modifica tu solución al Desafío 4a de manera que ahora los puntos +tengan una forma diferente y estén coloreados de acuerdo al continente +incluyendo líneas de tendencia. + +Pista: El argumento color puede ser usado dentro de **aesthetic** + + +```r +ggplot(data = gapminder, aes(x = gdpPercap, y = lifeExp, color = continent)) + +geom_point(size=3, shape=17) + scale_x_log10() + +geom_smooth(method="lm", size=1.5) +``` + +```{.output} +`geom_smooth()` using formula = 'y ~ x' +``` + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Figuras en múltiples paneles + +Anteriormente visualizamos el cambio en la esperanza de vida a lo largo del tiempo para cada uno de los países +en un solo gráfico. Como una alternativa, podemos dividir este gráfico en múltiples paneles al agregar una capa **facet**, +enfocándonos únicamente en aquellos países con nombres que empiezan con la letra "A" o "Z". + +::::::::::::::::::::::::::::::::::::::::: callout + +## Pista + +Empezamos por subdividir los datos. Usamos la función `substr` para extraer una parte de una secuencia de caracteres; +extrayendo las letras que ocurran de la posición `start` hasta `stop`, inclusive, del vector `gapminder$country`. +El operador `%in%` nos permite hacer múltiples comparaciones y evita que tengamos que escribir +una condición muy larga para subdividir los datos (en este caso, `starts.with %in% c("A", "Z")` +es equivalente a `starts.with == "A" | starts.with == "Z"`) + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + +```r +starts.with <- substr(gapminder$country, start = 1, stop = 1) +az.countries <- gapminder[starts.with %in% c("A", "Z"), ] +ggplot(data = az.countries, aes(x = year, y = lifeExp, color=continent)) + + geom_line() + facet_wrap( ~ country) +``` + + + +La capa `facet_wrap` toma una "fórmula" como argumento, lo cual se indica por el símbolo `~`. +Esto le dice a R que debe dibujar un panel para cada valor único de la columna "country" +del **dataset** gapminder. + +## Modificando texto + +Para limpiar esta figura y que quede lista para publicar necesitamos cambiar algunos elementos de texto. +El eje X está demasiado saturado, y el nombre del eje Y debería ser "Esperanza de vida", +en vez del nombre que aparece para esa columna en el **data frame**. + +Podemos hacer todo lo anterior agregando un par de capas. La capa **theme** controla el texto de los ejes, +y el tamaño del texto. Las etiquetas de los ejes, el título del gráfico y el título para todas las +leyendas pueden ser configurados utilizando la función `labs`. Los títulos de las leyendas son configurados +haciendo referencia a los mismos nombres que utilizamos en la especificación `aes`. Entonces, en el siguiente ejemplo +el título de la leyenda de los colores de las líneas se define utilizando `color = "Continent"`, mientras que el título +de la leyenda del color del relleno se definiría utilizando `fill = "MyTitle"`. + + +```r +ggplot(data = az.countries, aes(x = year, y = lifeExp, color=continent)) + + geom_line() + facet_wrap( ~ country) + + labs( + x = "Year", # título del eje x + y = "Life expectancy", # título del eje y + title = "Figure 1", # título principal de la figura + color = "Continent" # título de la leyenda + ) + + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank()) +``` + + + +## Exportando una gráfica + +La función `ggsave()` permite exportar una gráfica creada con ggplot. Puedes especificar la dimensión y la resolución de +tu gráfica ajustando los argumentos apropiados (`width`, `height` y `dpi`) para crear gráficas de gran calidad para publicar. +Para poder guardar la gráfica de arriba, primero tenemos que asignarla a una variable `lifeExp_plot`, y luego decirle a +`ggsave` que guarde la gráfica en formato `png` a un directorio llamado `results`. (Asegúrate de que tienes una carpeta +llamada `results/` en tu directorio de trabajo.) + + +```r +lifeExp_plot <- ggplot(data = az.countries, aes(x = year, y = lifeExp, color=continent)) + + geom_line() + facet_wrap( ~ country) + + labs( + x = "Year", # título del eje x + y = "Life expectancy", # título del eje y + title = "Figure 1", # título principal de la figura + color = "Continent" # título de la leyenda + ) + + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank()) +ggsave(filename = "results/lifeExp.png", plot = lifeExp_plot, width = 12, height = 10, dpi = 300, units = "cm") +``` + +```{.error} +Error in grid.newpage(): could not open file 'results/lifeExp.png' +``` + +Hay dos cosas agradables acerca de `ggsave`. Primero, usa la última gráfica por default, así que si omites el argumento `plot`, +`ggsave` automáticamente guardará la última gráfica que creaste con `ggplot`. +En segundo lugar, `ggsave` trata de determinar el formato en que quieres guardar la gráfica a partir de la extensión provista +en el nombre del archivo (por ejemplo `.png` or `.pdf`). Si es necesario, puedes especificar el formato explícitamente +en el argumento `device`. + +Esta lección es una prueba de lo que puedes hacer utilizando `ggplot2`. RStudio proporciona +una [hoja de ayuda][cheat] realmente útil de las diferentes capas disponibles, +una documentación más extensa se encuentra disponible en el [sitio web de ggplot2][ggplot-doc]. +Finalmente, si no tienen idea de cómo cambiar algún detalle, una búsqueda rápida en Google +te llevarán a Stack Overflow donde encuentras preguntas y respuestas ¡con código reusable que puedes modificar! + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 5 + +Crea una gráfica de densidad de GDP per cápita, en la que el color del relleno cambie por continente. + +Avanzado: + +- Transforma el eje X para visualizar mejor la dispersión de los datos. +- Agrega una capa **facet** para generar gráficos de densidad con un panel para cada año. + +::::::::::::::: solution + +## Solución al desafío 5 + +Crea una gráfica de densidad de GDP per cápita, en la que el color del relleno cambie por continente. + +Avanzado: + +- Transforma el eje X para visulaizar mejor la dispersión de los datos. +- Agrega una capa **facet** para generar gráficos de densidad con un panel para cada año. + + +```r +ggplot(data = gapminder, aes(x = gdpPercap, fill=continent)) + + geom_density(alpha=0.6) + facet_wrap( ~ year) + scale_x_log10() +``` + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +[base]: https://www.statmethods.net/graphs/ +[lattice]: https://www.statmethods.net/advgraphs/trellis.html +[ggplot2]: https://www.statmethods.net/advgraphs/ggplot2.html +[cheat]: https://www.rstudio.com/wp-content/uploads/2015/03/ggplot2-cheatsheet.pdf +[ggplot-doc]: https://docs.ggplot2.org/current/ + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Usar `ggplot2` para crear gráficos. +- Piensa cada gráfico como capas: estética, geometría, estadisticas, transformaciones de escala, y agrupamiento. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/09-vectorization.md b/09-vectorization.md new file mode 100644 index 00000000..767d1661 --- /dev/null +++ b/09-vectorization.md @@ -0,0 +1,425 @@ +--- +title: Vectorización +teaching: 10 +exercises: 15 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Entender las operaciones vertorizadas en R. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo operar sobre todos los elementos de un vector a la vez? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +La mayoría de las funciones en R están vectorizadas, lo que significa que la función +operará sobre todos los elementos de un vector sin necesidad de hacer un bucle a través +de cada elemento y actuar sobre cada uno de ellos. Esto hace la escritura de código más +concisa, fácil de leer y menos propenso a errores. + + +```r +x <- 1:4 +x * 2 +``` + +```{.output} +[1] 2 4 6 8 +``` + +La multiplicación se aplicó a cada elemento del vector. + +También podemos sumar dos vectores juntos: + + +```r +y <- 6:9 +x + y +``` + +```{.output} +[1] 7 9 11 13 +``` + +Cada elemento de `x` fue sumado a su correspondiente elemento de `y`: + + +```r +x: 1 2 3 4 + + + + + +y: 6 7 8 9 +--------------- + 7 9 11 13 +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Probemos esto en la columna `pop` del **dataset** `gapminder`. + +Haz una nueva columna en el **data frame** `gapminder` que +contiene la población en unidades de millones de personas. +Comprueba el principio o el final del **data frame** para asegurar +que funcionó. + +::::::::::::::: solution + +## Solución al desafío 1 + +Intenta esto en la columna `pop` del **dataset** `gapminder`. + +Haz una nueva columna en el **data frame** `gapminder` que +contiene población en unidades de millones de personas. +Comprueba el principio o el final del **data frame** para asegurar +que funcionó. + + +```r +gapminder$pop_millions <- gapminder$pop / 1e6 +head(gapminder) +``` + +```{.output} + country year pop continent lifeExp gdpPercap pop_millions +1 Afghanistan 1952 8425333 Asia 28.801 779.4453 8.425333 +2 Afghanistan 1957 9240934 Asia 30.332 820.8530 9.240934 +3 Afghanistan 1962 10267083 Asia 31.997 853.1007 10.267083 +4 Afghanistan 1967 11537966 Asia 34.020 836.1971 11.537966 +5 Afghanistan 1972 13079460 Asia 36.088 739.9811 13.079460 +6 Afghanistan 1977 14880372 Asia 38.438 786.1134 14.880372 +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +En una sola gráfica, traza la población, en +millones, en comparación con el año, para todos los países. No te preocupes en +identificar qué país es cuál. + +Repite el ejercicio, graficando sólo para China, India, e +Indonesia. Nuevamente, no te preocupes acerca de cuál es cuál. + +::::::::::::::: solution + +## Solución al desafío 2 + +Recuerda tus habilidades de graficación al crear una gráfica con la población en millones en comparación con el año. + + +```r +ggplot(gapminder, aes(x = year, y = pop_millions)) + + geom_point() +``` + + + +```r +countryset <- c("China","India","Indonesia") +ggplot(gapminder[gapminder$country %in% countryset,], + aes(x = year, y = pop_millions)) + + geom_point() +``` + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Operadores de comparación, operadores lógicos y muchas otras funciones también están +vectorizadas: + +**Operadores de Comparación** + + +```r +x > 2 +``` + +```{.output} +[1] FALSE FALSE TRUE TRUE +``` + +**Operadores Lógicos** + + +```r +a <- x > 3 # o, para más claridad, a <- (x > 3) +a +``` + +```{.output} +[1] FALSE FALSE FALSE TRUE +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: algunas funciones útiles para vectores lógicos + +`any()` devuelve `TRUE` si *algún* elemento del vector es `TRUE` +`all()` devuelve `TRUE` si *todos* los elementos del vector son `TRUE` + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +La mayoría de las funciones también operan elemento por elemento en los vectores: + +**Funciones** + + +```r +x <- 1:4 +log(x) +``` + +```{.output} +[1] 0.0000000 0.6931472 1.0986123 1.3862944 +``` + +Operaciones vectorizadas en matrices: + + +```r +m <- matrix(1:12, nrow=3, ncol=4) +m * -1 +``` + +```{.output} + [,1] [,2] [,3] [,4] +[1,] -1 -4 -7 -10 +[2,] -2 -5 -8 -11 +[3,] -3 -6 -9 -12 +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: multiplicación elemento por elemento vs. multiplicación de matriz + +Muy importante: el operador`*` te da una multiplicación de elemento por elemento! +Para hacer multiplicación de matrices, necesitás usar el operador `%*%`: + + +```r +m %*% matrix(1, nrow=4, ncol=1) +``` + +```{.output} + [,1] +[1,] 22 +[2,] 26 +[3,] 30 +``` + +```r +matrix(1:4, nrow=1) %*% matrix(1:4, ncol=1) +``` + +```{.output} + [,1] +[1,] 30 +``` + +Para saber más sobre Álgebra de matrices, ver [Quick-R reference guide](https://www.statmethods.net/advstats/matrix.html) + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +Dada la siguiente matriz: + + +```r +m <- matrix(1:12, nrow=3, ncol=4) +m +``` + +```{.output} + [,1] [,2] [,3] [,4] +[1,] 1 4 7 10 +[2,] 2 5 8 11 +[3,] 3 6 9 12 +``` + +Escribe lo que crees que sucederá cuando se ejecute: + +1. `m ^ -1` +2. `m * c(1, 0, -1)` +3. `m > c(0, 20)` +4. `m * c(1, 0, -1, 2)` + +¿Obtuviste la salida que esperabas? Si no, pregunta a un ayudante! + +::::::::::::::: solution + +## Solución al desafío 3 + +Dada la siguiente matriz: + + +```r +m <- matrix(1:12, nrow=3, ncol=4) +m +``` + +```{.output} + [,1] [,2] [,3] [,4] +[1,] 1 4 7 10 +[2,] 2 5 8 11 +[3,] 3 6 9 12 +``` + +Escribe lo que piensas que sucederá cuando ejecutes: + +1. `m ^ -1` + + +```{.output} + [,1] [,2] [,3] [,4] +[1,] 1.0000000 0.2500000 0.1428571 0.10000000 +[2,] 0.5000000 0.2000000 0.1250000 0.09090909 +[3,] 0.3333333 0.1666667 0.1111111 0.08333333 +``` + +2. `m * c(1, 0, -1)` + + +```{.output} + [,1] [,2] [,3] [,4] +[1,] 1 4 7 10 +[2,] 0 0 0 0 +[3,] -3 -6 -9 -12 +``` + +3. `m > c(0, 20)` + + +```{.output} + [,1] [,2] [,3] [,4] +[1,] TRUE FALSE TRUE FALSE +[2,] FALSE TRUE FALSE TRUE +[3,] TRUE FALSE TRUE FALSE +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 4 + +Estamos interesados en encontrar la suma de la +siguiente secuencia de fracciones: + + +```r + x = 1/(1^2) + 1/(2^2) + 1/(3^2) + ... + 1/(n^2) +``` + +Esto sería tedioso de escribir, e imposible para valores altos de +n. Usa vectorización para calcular x cuando n=100. ¿Cuál es la suma cuando +n=10.000? + +::::::::::::::: solution + +## Solución al desafío 4 + +Estamos interesados en encontrar la suma de la +siguiente secuencia de fracciones: + + +```r + x = 1/(1^2) + 1/(2^2) + 1/(3^2) + ... + 1/(n^2) +``` + +Esto sería tedioso de escribir, e imposible para +valores altos de n. +¿Puedes usar vectorización para calcular x, cuando n=100? +¿Qué tal cuando n=10,000? + + +```r +sum(1/(1:100)^2) +``` + +```{.output} +[1] 1.634984 +``` + +```r +sum(1/(1:1e04)^2) +``` + +```{.output} +[1] 1.644834 +``` + +```r +n <- 10000 +sum(1/(1:n)^2) +``` + +```{.output} +[1] 1.644834 +``` + +Podemos obtener el mismo resultado usando una función: + + +```r +inverse_sum_of_squares <- function(n) { + sum(1/(1:n)^2) +} +inverse_sum_of_squares(100) +``` + +```{.output} +[1] 1.634984 +``` + +```r +inverse_sum_of_squares(10000) +``` + +```{.output} +[1] 1.644834 +``` + +```r +n <- 10000 +inverse_sum_of_squares(n) +``` + +```{.output} +[1] 1.644834 +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Uso de operaciones vectorizadas en lugar de bucles. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/10-functions.md b/10-functions.md new file mode 100644 index 00000000..77a49e17 --- /dev/null +++ b/10-functions.md @@ -0,0 +1,685 @@ +--- +title: Funciones +teaching: 45 +exercises: 15 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Definir una función que usa argumentos. +- Obtener un valor a partir de una función. +- Revisar argumentos con `stopifnot()` en las funciones. +- Probar una función. +- Establecer valores por defecto para los argumentos de las funciones. +- Explicar por qué debemos dividir programas en funciones pequeñas y de propósitos únicos. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo escribir una nueva función en R? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +::::::::::::::::::::::::::::::::::::::: checklist + +## Palabras clave + +Comando : Traducción + +`stopifnot` : para si no + +`NULL` : nulo + +`paste` : pegar + +`TRUE` : verdadero + +`FALSE` : falso + +`source` : fuente + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Si tuviéramos un único conjunto de datos para analizar, probablemente sería más rápido cargar el archivo en una hoja de cálculo y usarla para graficar estadísticas simples. Sin embargo, los datos `gapminder` son actualizados periódicamente, y podríamos querer volver a bajar esta información actualizada más adelante y re-analizar los datos. También podríamos obtener datos similares de una fuente distinta en el futuro. + +En esta lección, aprenderás cómo escribir una función de forma que seamos capaces de repetir varias operaciones con un comando único. + +::::::::::::::::::::::::::::::::::::::::: callout + +## ¿Qué es una función? + +Las funciones reúnen una secuencia de operaciones como un todo, almacenandola para +su uso continuo. Las funciones proveen: + +- un nombre que podemos recordar y usar para invocarla +- una solución para la necesidad de recordar operaciones individuales +- un conjunto definido de **inputs** y **outputs** esperados +- una mayor conexión con el ambiente de programación + +Como el componente básico de la mayoría de los lenguajes de programación, las funciones definidas por el usuario constituyen la "programación" de cualquier abstracción que puedas hacer. Si has escrito una función, eres ya todo un programador. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Definiendo una función + +Empecemos abriendo un nuevo **script** de R en el directorio `functions/` y nombrémosle functions-lesson.R. + + +```r +my_sum <- function(a, b) { + the_sum <- a + b + return(the_sum) +} +``` + +Definamos una función `fahr_a_kelvin()` que convierta temperaturas de +Fahrenheit a Kelvin: + + +```r +fahr_to_kelvin <- function(temp) { + kelvin <- ((temp - 32) * (5 / 9)) + 273.15 + return(kelvin) +} +``` + +Definimos `fahr_a_kelvin()` asignándola al **output** de `function`. La +lista de los nombres de los argumentos se encuentran entre paréntesis. Luego, el +[cuerpo](../learners/reference.md#function-body) de la función--los +comandos que son ejecutados cuando se corre--se encuentran entre paréntesis curvos +(`{}`). Los comandos en el cuerpo se indentan con dos espacios. Esto hace que +el código sea legible sin afectar su funcionalidad. + +Cuando utilizamos la función, los valores que definimos como argumentos se asignan a +esas variables para que podamos usarlos dentro de la función. Dentro de la +función, usamos un [return +statement](../learners/reference.md#return-statement) para devolver un resultado a +quien lo solicitó. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia + +Una característica única de R es que el **return statement** no es necesario. +R automáticamente devuelve cualquier variable que esté en la última línea del cuerpo +de la función. Pero por claridad, nosotros explícitamente definiremos el +**return statement**. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Tratemos de correr nuestra función. +Llamamos nuestra propia función de la misma manera que llamamos cualquier otra: + + +```r +# Punto de congelación del agua +fahr_to_kelvin(32) +``` + +```{.output} +[1] 273.15 +``` + + +```r +# Punto de ebullición del agua +fahr_to_kelvin(212) +``` + +```{.output} +[1] 373.15 +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Escribe una función llamada `kelvin_a_celsius()` que toma la temperatura en +grados Kelvin y devuelve la temperatura en Celsius. + +Pista: Para convertir de Kelvin a Celsius se debe restar 273.15 + +::::::::::::::: solution + +## Solución al desafío 1 + +Escribe una función llamada `kelvin_a_celsius()` que toma la temperatura en grados +Kelvin y devuelve la temperatura en Celsius. + + +```r +kelvin_to_celsius <- function(temp) { + celsius <- temp - 273.15 + return(celsius) +} +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Combinando funciones + +El poder real de las funciones proviene de mezclarlas y combinarlas en +pedazos de código aún mas grandes para lograr el resultado que buscamos. + +Definamos dos funciones que convertirán la temperatura de Fahrenheit a +Kelvin, y de Kelvin a Celsius: + + +```r +fahr_to_kelvin <- function(temp) { + kelvin <- ((temp - 32) * (5 / 9)) + 273.15 + return(kelvin) +} + +kelvin_to_celsius <- function(temp) { + celsius <- temp - 273.15 + return(celsius) +} +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +Define la función para convertir directamente de Fahrenheit a Celsius, +reutilizando las dos funciones de arriba (o utilizando tus propias funciones +si lo prefieres). + +::::::::::::::: solution + +## Solución a desafío 2 + +Define la función para convertir directamente de Fahrenheit a Celsius, +reutilizando las dos funciones de arriba. + + +```r +fahr_to_celsius <- function(temp) { + temp_k <- fahr_to_kelvin(temp) + result <- kelvin_to_celsius(temp_k) + return(result) +} +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Interludio: Programación defensiva + +Ahora que hemos empezado a apreciar cómo las funciones proporcionan una manera eficiente de hacer que el código R sea reutilizable +y modular, debemos tener en cuenta que es importante garantizar que las funciones solo funcionen en los casos de uso previstos. +Revisar los parámetros de las funciones está relacionado con el concepto de *programación defensiva*. +La programación defensiva nos alienta a probar las condiciones frecuentemente y arrojar un +error si algo está mal. Estas pruebas se conocen como **assertion statements** porque queremos +asegurarnos de que una determinada condición es `TRUE` antes de proceder. +Esto facilita la depuración porque nos dan una mejor idea de dónde se originan los errores. + +### Probando condiciones con `stopifnot()` + +Empecemos por re-examinar `fahr_a_kelvin()`, nuestra función para convertir +temperaturas de Fahrenheit a Kelvin. Estaba definida de la siguiente manera: + + +```r +fahr_to_kelvin <- function(temp) { + kelvin <- ((temp - 32) * (5 / 9)) + 273.15 + return(kelvin) +} +``` + +Para que esta función trabaje como se desea, el argumento `temp` debe ser un valor `numeric`; de lo contrario, el procedimiento +matemático para convertir entre las dos escalas de temperatura no funcionará. Para crear un error, podemos usar la función +`stop()`. Por ejemplo, dado que el argumento `temp` debe ser un vector `numeric`, podríamos +probarlo con un condicional `if` y devolver un error si la +condición no se cumple. Podríamos agregar esto a nuestra función de la siguiente manera: + + +```r +fahr_to_kelvin <- function(temp) { + if (!is.numeric(temp)) { + stop("temp must be a numeric vector.") + } + kelvin <- ((temp - 32) * (5 / 9)) + 273.15 + return(kelvin) +} +``` + +Si tuviéramos muchas condiciones o argumentos para revisar, podría llevar muchas líneas +de código probarlas todas. Afortunadamente R provee la función de conveniencia +`stopifnot()`. Podemos listar todos los requerimientos que deben ser evaluados como `TRUE`; +`stopifnot()` arroja un error si encuentra uno que sea `FALSE`. +Listar estas condiciones tiene como objetivo secundario el generar documentación extra para la función. + +Hagamos la programación defensiva con `stopifnot()` agregando aseveraciones para +probar el **input** a nuestra función `fahr_a_kelvin()`. + +Queremos asegurar lo siguiente: `temp` es un vector numérico. Lo podemos hacer de la siguiente manera: + + +```r +fahr_to_kelvin <- function(temp) { + stopifnot(is.numeric(temp)) + kelvin <- ((temp - 32) * (5 / 9)) + 273.15 + return(kelvin) +} +``` + +Aún funciona si se le da un **input** adecuado. + + +```r +# Punto de congelación del agua +fahr_to_kelvin(temp = 32) +``` + +```{.output} +[1] 273.15 +``` + +Pero falla instantáneamente si se le da un **input** inapropiado. + + +```r +# La métrica es un factor en lugar de numeric +fahr_to_kelvin(temp = as.factor(32)) +``` + +```{.error} +Error in fahr_to_kelvin(temp = as.factor(32)): is.numeric(temp) is not TRUE +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +Usar programación defensiva para asegurar que nuestra función `fahr_a_celsius()` +arroja inmediatamente un error si el argumento `temp` se especifica +inadecuadamente. + +::::::::::::::: solution + +## Solución al desafío 3 + +Extender la definición previa de nuestra función agregándole una llamada explícita +a `stopifnot()`. Dado que `fahr_a_celsius()` es una composición de otras dos +funciones, hacer pruebas a la función hace redundante el agregar pruebas a cada una de las +dos funciones que la componen. + + +```r +fahr_to_celsius <- function(temp) { + stopifnot(!is.numeric(temp)) + temp_k <- fahr_to_kelvin(temp) + result <- kelvin_to_celsius(temp_k) + return(result) +} +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Más sobre combinar funciones + +Ahora vamos a definir una función que calcula el Producto Interno Bruto ("GDP" en la base de datos, por sus siglas en inglés +Gross Domestic Product) de un país a partir de los datos disponibles en nuestro conjunto de datos: + + +```r +# Toma un dataset y multiplica la columna de población +# por la columna de GDP per capita +calcGDP <- function(dat) { + gdp <- dat$pop * dat$gdpPercap + return(gdp) +} +``` + +Definimos `calcGDP()` asignándola al **output** de `function`. La lista de +los nombres de los argumentos se encuentran entre paréntesis. Luego, el +cuerpo de la función--las instrucciones que se ejecutan cuando se llama a la función-- se encuentran entre llaves (`{}`). + +Hemos indentado los comandos en el cuerpo con dos espacios. Esto hace que el código +sea mas fácil de leer sin afectar su funcionamiento. + +Cuando utilizamos la función, los valores que le pasamos se asignan como argumentos, +que se convierten en variables dentro del cuerpo de la función. + +Dentro de la función, usamos la función `return()` para obtener el resultado. + +Esta función `return()` es opcional: R automáticamente devolverá el resultado de cualquier +comando que se ejecute en la última línea de la función. + + +```r +calcGDP(head(gapminder)) +``` + +```{.output} +[1] 6567086330 7585448670 8758855797 9648014150 9678553274 11697659231 +``` + +Eso no es muy informativo. Agreguemos algunos argumentos más para poder extraer +por año y país. + + +```r +# Toma un dataset y multiplica la columna de población +# por la columna de GDP per capita +calcGDP <- function(dat, year=NULL, country=NULL) { + if(!is.null(year)) { + dat <- dat[dat$year %in% year, ] + } + if (!is.null(country)) { + dat <- dat[dat$country %in% country,] + } + gdp <- dat$pop * dat$gdpPercap + + new <- cbind(dat, gdp=gdp) + return(new) +} +``` + +Si has estado escribiendo estas funciones en un **script** de R aparte +(¡una buena idea!), puedes cargar las funciones en nuestra sesión de R +usando la función `source()`: + + +```r +source("functions/functions-lesson.R") +``` + +Ok, entonces están pasando muchas cosas en esta función ahora. En pocas palabras, ahora +la función filtra un subconjunto de datos por año si el argumento año no está vacío, +luego filtra un subconjunto de los resultados por país si el argumento país no está vacío. +Luego calcula el GDP de los datos filtrados resultado de los dos +pasos anteriores. La función luego agrega el valor calculado de GDP como una nueva columna +en los datos filtrados y devuelve esto como el resultado final. Puedes ver que el **output** +es mucho más informativo que un vector numérico. + +Veamos qué sucede cuando especificamos el año: + + +```r +head(calcGDP(gapminder, year=2007)) +``` + +```{.output} + country year pop continent lifeExp gdpPercap gdp +12 Afghanistan 2007 31889923 Asia 43.828 974.5803 31079291949 +24 Albania 2007 3600523 Europe 76.423 5937.0295 21376411360 +36 Algeria 2007 33333216 Africa 72.301 6223.3675 207444851958 +48 Angola 2007 12420476 Africa 42.731 4797.2313 59583895818 +60 Argentina 2007 40301927 Americas 75.320 12779.3796 515033625357 +72 Australia 2007 20434176 Oceania 81.235 34435.3674 703658358894 +``` + +O para un país específico: + + +```r +calcGDP(gapminder, country="Australia") +``` + +```{.output} + country year pop continent lifeExp gdpPercap gdp +61 Australia 1952 8691212 Oceania 69.120 10039.60 87256254102 +62 Australia 1957 9712569 Oceania 70.330 10949.65 106349227169 +63 Australia 1962 10794968 Oceania 70.930 12217.23 131884573002 +64 Australia 1967 11872264 Oceania 71.100 14526.12 172457986742 +65 Australia 1972 13177000 Oceania 71.930 16788.63 221223770658 +66 Australia 1977 14074100 Oceania 73.490 18334.20 258037329175 +67 Australia 1982 15184200 Oceania 74.740 19477.01 295742804309 +68 Australia 1987 16257249 Oceania 76.320 21888.89 355853119294 +69 Australia 1992 17481977 Oceania 77.560 23424.77 409511234952 +70 Australia 1997 18565243 Oceania 78.830 26997.94 501223252921 +71 Australia 2002 19546792 Oceania 80.370 30687.75 599847158654 +72 Australia 2007 20434176 Oceania 81.235 34435.37 703658358894 +``` + +O ambos: + + +```r +calcGDP(gapminder, year=2007, country="Australia") +``` + +```{.output} + country year pop continent lifeExp gdpPercap gdp +72 Australia 2007 20434176 Oceania 81.235 34435.37 703658358894 +``` + +Veamos paso a paso el cuerpo de la función: + + +```r +calcGDP <- function(dat, year=NULL, country=NULL) { +``` + +Aquí hemos agregado dos argumentos, año y país. Hemos establecido +*argumentos predeterminados* para ambos como NULL usando el operador = +en la definición de la función. Esto significa que esos argumentos tomarán esos valores +a menos que el usuario especifique lo contrario. + + +```r + if(!is.null(year)) { + dat <- dat[dat$year %in% year, ] + } + if (!is.null(country)) { + dat <- dat[dat$country %in% country,] + } +``` + +Aquí verificamos si cada argumento adicional se define como `null`, y cuando no sea +`null` se sobreescriben los datos almacenados en `dat` por un subconjunto de datos determinados por el +argumento not-`null`. + +Hacemos esto para que nuestra función sea más flexible para más adelante. Podemos pedirle que +calcule el GDP para: + +- El **dataset** completo; +- Un solo año; +- Un solo país; +- Una combinación única de año y país. + +Al utilizar el operador `%in%`, también podemos asignarle múltiples años o países a estos +argumentos. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Pasar por valor + +Las funciones en R casi siempre hacen copias de los datos para operar dentro +del cuerpo de una función. Cuando modificamos `dat` dentro de la función +estamos modificando la copia del **dataset** gapminder almacenado en `dat`, +y no la variable original que asignamos como el primer argumento. + +Eso se llama ****pasar por valor**** y hace la escritura del código mucho más segura: +puedes estar seguro que cualquier cambio que hagas dentro del +cuerpo de la función, se mantendrá dentro de la función. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Alcance de la función + +Otro concepto importante es el alcance: las variables (¡o funciones!) que +creas o modificas dentro del cuerpo de una función sólo existen durante +el tiempo de ejecución de la función. Cuando llamamos `calcGDP()`, las variables `dat`, +`gdp` y `new` sólo existen dentro del cuerpo de la función. Incluso, si +tenemos variables con el mismo nombre en nuestra sesión interactiva de R, éstas no +son modificadas en ninguna manera cuando se ejecuta la función. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + +```r + gdp <- dat$pop * dat$gdpPercap + new <- cbind(dat, gdp=gdp) + return(new) +} +``` + +Finalmente, calculamos GDP en nuestro nuevo subconjunto de datos, y creamos una nueva **dataframe** +con esta columna agregada. Esto significa que cuando llamamos a la función, en el resultado +podemos ver el contexto de los valores GDP obtenidos, lo que es mucho mejor que +nuestro primer intento cuando habíamos obtenido un vector de números. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +Probar tu función GDP calculando el GDP para Nueva Zelandia ("New Zealand") en 1987. ¿Cómo +difiere del GDP de Nueva Zelandia en 1952? + +::::::::::::::: solution + +## Solución al desafío 3 + + +```r + calcGDP(gapminder, year = c(1952, 1987), country = "New Zealand") +``` + +GDP para Nueva Zelandia en 1987: 65050008703 + +GDP para Nueva Zelandia en 1952: 21058193787 + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 4 + +La función `paste()` puede ser usada para combinar texto, ej.: + + +```r +best_practice <- c("Write", "programs", "for", "people", "not", "computers") +paste(best_practice, collapse=" ") +``` + +```{.output} +[1] "Write programs for people not computers" +``` + +Escribir una función `fence()` que tome dos vectores como argumentos, llamados +`text` y `wrapper`, y muestra el texto flanqueado del `wrapper`: + + +```r +fence(text=best_practice, wrapper="***") +``` + +*Nota:* la función `paste()` tiene un argumento llamado `sep`, que especifica +el separador de texto. Por defecto es un espacio: " ". El valor por defecto de la función +`paste0()` es sin espacio "". + +::::::::::::::: solution + +## Solución al desafío 4 + +Escribir una función `fence()` que toma dos vectores como argumentos, llamados +`text` y `wrapper`, e imprime el texto flanqueado del `wrapper`: + + +```r +fence <- function(text, wrapper){ + text <- c(wrapper, text, wrapper) + result <- paste(text, collapse = " ") + return(result) +} +best_practice <- c("Write", "programs", "for", "people", "not", "computers") +fence(text=best_practice, wrapper="***") +``` + +```{.output} +[1] "*** Write programs for people not computers ***" +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia + +R tiene algunos aspectos únicos que pueden ser explotados cuando se realizan +operaciones más complicadas. No escribiremos nada que requiera el conocimiento de estos +conceptos más avanzados. En el futuro, cuando te sientas cómodo escribiendo funciones +en R, puedes aprender más leyendo el +[Manual de lenguaje de R][man] o este [capítulo] de +[Advanced R Programming][adv-r] de Hadley Wickham. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Probar y documentar + +Es importante probar las funciones así como documentarlas: +la documentación ayuda, tanto a tí como a otros, a entender cuál es el propósito +de la función y cómo usarla; además es importante +asegurarse que la función realmente haga +lo que tú piensas que hace. + +Cuando recién comiences, tu flujo de trabajo probablemente luzca +algo así: + +1. Escribir una función +2. Comentar partes de la función para documentar su comportamiento +3. Cargar el archivo **source** +4. Experimentar con ella en la consola para asegurarte que se comporta tal como tu esperas. +5. Hacer los arreglos necesarios +6. Volver a probar y repetir. + +La documentación formal para las funciones, escritas en archivos `.Rd` +aparte, se transforman en la documentación que ves en los archivos de ayuda. +El paquete [roxygen2] le permite a los programadores de R escribir la +documentación junto con el código, y luego procesarlo para generar los archivos `.Rd` +apropiados. Quizás quieras cambiarte a este método más formal de escribir +la documentación cuando empieces a escribir proyectos de R más complicados. + +Pruebas automatizadas formales se pueden escribir usando el paquete [testthat]. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +[man]: https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Environment-objects +[capítulo]: https://adv-r.had.co.nz/Environments.html +[adv-r]: https://adv-r.had.co.nz/ +[roxygen2]: https://cran.r-project.org/web/packages/roxygen2/vignettes/rd.html +[testthat]: https://r-pkgs.had.co.nz/tests.html + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Usar `function` para definir una nueva función en R. +- Usar parámetros para ingresar valores dentro de las funciones. +- Usar `stopifnot()` para revisar los argumentos de una función en R de manera flexible. +- Cargar funciones dentro de programas empleando `source()`. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/11-writing-data.md b/11-writing-data.md new file mode 100644 index 00000000..93800c84 --- /dev/null +++ b/11-writing-data.md @@ -0,0 +1,230 @@ +--- +title: Guardando datos +teaching: 10 +exercises: 10 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Ser capaz de guardar gráficos y datos desde R. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo guardar gráficos y datos creados en R? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +::::::::::::::::::::::::::::::::::::::: checklist + +## Palabras clave + +Comando : Traducción + +`write.table` : escribir tabla + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Guardando gráficos + +Ya hemos visto como guardar el gráfico más reciente que creaste con el paquete `ggplot2` +usando el comando `ggsave`. A manera de recordatorio, aquí está el código: + + +```r +ggsave("My_most_recent_plot.pdf") +``` + +Puedes guardar un gráfico desde Rstudio usando el botón de 'Export' en la +ventana de 'Plot'. Esto te dará la opción de guardarlo como .pdf, .png, .jpg +u otros formatos de imágenes. + +Puede que quieras guardar los gráficos sin visualizarlos previamente +en la ventana de 'Plot'. Quizás quieras hacer un documento pdf con varias +páginas: por ejemplo, cada una con un gráfico distinto. O quizás estás +iterando sobre distintos subconjuntos de un archivo, graficando los datos +de cada subconjunto y quieres guardar cada una de los gráficos. En estos casos obviamente no +puedes detener la iteración en cada paso para dar clic en 'Export' para +cada uno. + +En dicho caso conviene usar un método más flexible. La función `pdf` crea un +nuevo pdf del cual puedes controlar el tamaño y la resolución usando los +argumentos específicos de esta función. + + +```r +pdf("Life_Exp_vs_time.pdf", width=12, height=4) +ggplot(data=gapminder, aes(x=year, y=lifeExp, colour=country)) + + geom_line() + + theme(legend.position = "none") + +# ¡Tienes que asegurarte de cerrar el pdf! Para ello usas el comando: + +dev.off() +``` + +Abre este documento y echa un vistazo. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Vuelve a escribir el comando 'pdf', pero esta vez emplea el término **facet** (sugerencia: usa `facet_grid`) con los +mismos datos. Esto te permitirá visualizar en un gráfico los datos por continente y guardarlos en un pdf. + +::::::::::::::: solution + +## Solución al desafío 1 + + +```r +pdf("Life_Exp_vs_time.pdf", width = 12, height = 4) +p <- ggplot(data = gapminder, aes(x = year, y = lifeExp, colour = country)) + + geom_line() + + theme(legend.position = "none") +p +p + facet_grid(. ~continent) +dev.off() +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Los comandos como `jpeg`y `png` entre otros son usados de manera similar para producir +documentos en los correspondientes formatos. + +## Guardando datos + +En algún momento puede que también quieras guardar datos desde R. + +Para ello podes usar la función `write.table`, que es muy similar a la +función `read.table` que se presentó anteriormente. + +Vamos a crear un **script** para limpiar datos. En este análisis, vamos a +enfocarnos solamente en los datos de **gapminder** para Australia: + + +```r +aust_subset <- gapminder[gapminder$country == "Australia",] + +write.table(aust_subset, + file="cleaned-data/gapminder-aus.csv", + sep="," +) +``` + +Ahora regresemos a la terminal para dar un vistazo a los datos y +asegurarnos que se vean bien: + + +```bash +head cleaned-data/gapminder-aus.csv +``` + +```{.output} +"country","year","pop","continent","lifeExp","gdpPercap" +"61","Australia",1952,8691212,"Oceania",69.12,10039.59564 +"62","Australia",1957,9712569,"Oceania",70.33,10949.64959 +"63","Australia",1962,10794968,"Oceania",70.93,12217.22686 +"64","Australia",1967,11872264,"Oceania",71.1,14526.12465 +"65","Australia",1972,13177000,"Oceania",71.93,16788.62948 +"66","Australia",1977,14074100,"Oceania",73.49,18334.19751 +"67","Australia",1982,15184200,"Oceania",74.74,19477.00928 +"68","Australia",1987,16257249,"Oceania",76.32,21888.88903 +"69","Australia",1992,17481977,"Oceania",77.56,23424.76683 +``` + +Mmm, eso no era precisamente lo que queríamos. ¿De dónde vinieron todas +esas comillas?. Los números de línea tampoco tienen sentido. + +Veamos el archivo de ayuda para investigar como podemos cambiar este +comportamiento. + + +```r +?write.table +``` + +Salvo que configuremos otra cosa, los vectores **character** aparecen de forma predeterminada entre comillas cuando se +guardan en un archivo. También se guardan los nombres de los renglones y las +columnas. + +Cambiemos esto: + + +```r +write.table( + gapminder[gapminder$country == "Australia",], + file="cleaned-data/gapminder-aus.csv", + sep=",", quote=FALSE, row.names=FALSE +) +``` + +Ahora echemos de nuevo un vistazo a los datos usando nuestras habilidades en +la terminal: + + +```bash +head cleaned-data/gapminder-aus.csv +``` + +```{.output} +country,year,pop,continent,lifeExp,gdpPercap +Australia,1952,8691212,Oceania,69.12,10039.59564 +Australia,1957,9712569,Oceania,70.33,10949.64959 +Australia,1962,10794968,Oceania,70.93,12217.22686 +Australia,1967,11872264,Oceania,71.1,14526.12465 +Australia,1972,13177000,Oceania,71.93,16788.62948 +Australia,1977,14074100,Oceania,73.49,18334.19751 +Australia,1982,15184200,Oceania,74.74,19477.00928 +Australia,1987,16257249,Oceania,76.32,21888.88903 +Australia,1992,17481977,Oceania,77.56,23424.76683 +``` + +¡Ahora se ve mejor! + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +Escribe un **script** para limpiar estos datos, filtrando los datos de +**gapminder** que fueron colectados desde 1990. + +Usa este **script** para guardar este nuevo subconjunto de datos en el +directorio `cleaned-data`. + +::::::::::::::: solution + +## Solución al desafío 2 + + +```r +write.table( + gapminder[gapminder$year > 1990, ], + file = "cleaned-data/gapminder-after1990.csv", + sep = ",", quote = FALSE, row.names = FALSE +) +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Guardar gráficos desde RStudio usando el botón de 'Export'. +- Usar `write.table` para guardar datos tabulares. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/12-plyr.md b/12-plyr.md new file mode 100644 index 00000000..763a7ab1 --- /dev/null +++ b/12-plyr.md @@ -0,0 +1,427 @@ +--- +title: División y combinación de data frames con plyr +teaching: 30 +exercises: 30 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Estar apto a usar la estrategia divide-aplica-combina para el análisis de datos. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo hacer diferentes cálculos sobre diferentes conjuntos de datos? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +Previamente vimos como puedes usar funciones para simplificar tu código. +Definimos la función `calcGDP`, la cual toma el **dataset** gapminder, y multiplica la columna de población por la columna GDP per cápita. También definimos argumentos adicionales de modo que pudiéramos filtrar por `"year"` o por `"country"`: + + +```r +# Toma un dataset y multiplica la columna population con +# la columna GDP per cápita. +calcGDP <- function(dat, year=NULL, country=NULL) { + if(!is.null(year)) { + dat <- dat[dat$year %in% year, ] + } + if (!is.null(country)) { + dat <- dat[dat$country %in% country,] + } + gdp <- dat$pop * dat$gdpPercap + + new <- cbind(dat, gdp=gdp) + return(new) +} +``` + +Una tarea común que encontrarás mientras trabajes con datos, es que querrás hacer cálculos en diferentes grupos sobre los datos. En el ejemplo de arriba, simplemente calculamos el GDP por multiplicar dos columnas juntas. ¿Pero qué tal si queremos calcular la media GDP por continente?   + +Podríamos ejecutar `calcGDP` y entonces tomar la media de cada continente: + + +```r +withGDP <- calcGDP(gapminder) +mean(withGDP[withGDP$continent == "Africa", "gdp"]) +``` + +```{.output} +[1] 20904782844 +``` + +```r +mean(withGDP[withGDP$continent == "Americas", "gdp"]) +``` + +```{.output} +[1] 379262350210 +``` + +```r +mean(withGDP[withGDP$continent == "Asia", "gdp"]) +``` + +```{.output} +[1] 227233738153 +``` + +Pero esto no es muy *bonito*. Sí, por usar una función, has reducido substancialmente la cantidad de repeticiones. Esto **es** bonito. Pero aún hay repeticiones. La repetición te costará tiempo, tanto ahora como más tarde, y potencialmente introducirás algunos errores desagradables. + +Podriamos escribir una nueva función que sea flexible como `calcGDP`, pero esta también requiere una gran cantidad de esfuerzo y pruebas para hacerlo bien. + +El problema abstracto que estamos encontrando aquí es conocido como "divide-aplica-combina (*split-apply-combine*)": + +![](fig/12-plyr-fig1.png){alt='Split apply combine'} + +Nosotros queremos dividir (*split*) nuestros datos dentro de grupos, en este caso continentes, aplicar (*apply*) algunos cálculos sobre este grupo y, opcionalmente, combinar (*combine*) los resultados más tarde. + +## El paquete `plyr` + +Para aquellos que han usado antes R, es posible que estén familiarizados con la familia de funciones `apply`. Mientras que las funciones integradas de R funcionan, vamos a introducirte a otro método para resolver el problema +"split-apply-combine". El paquete [plyr](https://had.co.nz/plyr/) proporciona un conjunto de funciones que encontramos más amigables de usar para resolver este problema. + +Instalamos este paquete en un desafío anterior. Vamos a cargarlo ahora: + + +```r +library("plyr") +``` + +Plyr tiene una función para operar sobre listas o `**lists**` , `**data.frames**` y `**arrays**` (matrices, o vectores n-dimensional). Cada función realiza: + +1. Una operación de división (**split**ting). +2. Aplica (**apply**) una función sobre cada una de las partes a la vez. +3. Recombina (re**combine**) los datos de salida como un simple objeto de datos. + +Las funciones se nombran en función de la estructura de datos que esperan como entrada, y la estructura de datos que desea devolver como salida: [a]rray, [l]ist, o [d]ata.frame. La primera letra corresponde a la estructura de datos de entrada, la segunda letra a la estructura de datos de salida, y luego el resto de la función se llama "ply". + +Esto nos da 9 funciones básicas \*\*ply. Hay adicionalmente un árbol de funciones las cuales solo realizarán la división y aplicación de los pasos y ningún paso combinado. Ellas son nombradas por sus datos de entrada y representan una salida nula con un `_` (Ver tabla) + +Note que el uso de "array" de plyr es diferente a R, un array en ply puede incluir a vector o matriz. + +![](fig/12-plyr-fig2.png){alt='Full apply suite'} + +Cada una de las funciones de xxply (`daply`,` ddply`, `llply`,` laply`, ...) tiene la misma estructura y 4 características clave: + + +```r +xxply(.data, .variables, .fun) +``` + +- La primera letra del nombre de la función da el tipo de la entrada y el segundo da el tipo de la salida. +- `.data` – Es el objeto de datos a ser procesado +- `.variables` – identifica la variable para hacer la división +- `.fun` – Da la función a ser llamada para cada pieza + +Ahora podemos calcular rápidamente la media GDP por `"continent"`: + + +```r +ddply( + .data = calcGDP(gapminder), + .variables = "continent", + .fun = function(x) mean(x$gdp) +) +``` + +```{.output} + continent V1 +1 Africa 20904782844 +2 Americas 379262350210 +3 Asia 227233738153 +4 Europe 269442085301 +5 Oceania 188187105354 +``` + +Veamos el código anterior: + +- La función `ddply` recibe de entrada un `data.frame` (La función empieza con una **d**) y regresa otro `data.frame` (la 2da letra es una **d**) +- El primer argumento que dimos fue el `data.frame` en el que queríamos operar: en este caso, los datos del `gapminder`. Primero llamamos a la función `calcGDP` para agregar la columna` gdp` a nuestra variable *data*. +- El segundo argumento indica nuestro criterio para dividir: En este caso la columna `"continent"`. Ten en cuenta que le dimos el nombre de la columna, no los valores de la columna como habíamos hecho previamente con los subconjuntos. `Plyr` se encarga de los detalles de la implementación por ti. +- El tercer argumento es la función que queremos aplicar a cada grupo de datos. Tenemos que definir nuestra propia función corta aquí: cada subconjunto de datos va almacenado en `x`, el primer argumento de la función. Esta es una función anónima: no la hemos definido en otra parte y no tiene nombre. Solo existe en el ámbito de nuestro llamado a `ddply`. + +¿Qué pasa si queremos un tipo diferente de estructura de datos de salida?: + + +```r +dlply( + .data = calcGDP(gapminder), + .variables = "continent", + .fun = function(x) mean(x$gdp) +) +``` + +```{.output} +$Africa +[1] 20904782844 + +$Americas +[1] 379262350210 + +$Asia +[1] 227233738153 + +$Europe +[1] 269442085301 + +$Oceania +[1] 188187105354 + +attr(,"split_type") +[1] "data.frame" +attr(,"split_labels") + continent +1 Africa +2 Americas +3 Asia +4 Europe +5 Oceania +``` + +Llamamos a la misma función otra vez, pero cambiamos la segunda letra por una `l`, asi que la salida fue regresada como una lista. + +Podemos especificar múltiples columnas para agrupar: + + +```r +ddply( + .data = calcGDP(gapminder), + .variables = c("continent", "year"), + .fun = function(x) mean(x$gdp) +) +``` + +```{.output} + continent year V1 +1 Africa 1952 5992294608 +2 Africa 1957 7359188796 +3 Africa 1962 8784876958 +4 Africa 1967 11443994101 +5 Africa 1972 15072241974 +6 Africa 1977 18694898732 +7 Africa 1982 22040401045 +8 Africa 1987 24107264108 +9 Africa 1992 26256977719 +10 Africa 1997 30023173824 +11 Africa 2002 35303511424 +12 Africa 2007 45778570846 +13 Americas 1952 117738997171 +14 Americas 1957 140817061264 +15 Americas 1962 169153069442 +16 Americas 1967 217867530844 +17 Americas 1972 268159178814 +18 Americas 1977 324085389022 +19 Americas 1982 363314008350 +20 Americas 1987 439447790357 +21 Americas 1992 489899820623 +22 Americas 1997 582693307146 +23 Americas 2002 661248623419 +24 Americas 2007 776723426068 +25 Asia 1952 34095762661 +26 Asia 1957 47267432088 +27 Asia 1962 60136869012 +28 Asia 1967 84648519224 +29 Asia 1972 124385747313 +30 Asia 1977 159802590186 +31 Asia 1982 194429049919 +32 Asia 1987 241784763369 +33 Asia 1992 307100497486 +34 Asia 1997 387597655323 +35 Asia 2002 458042336179 +36 Asia 2007 627513635079 +37 Europe 1952 84971341466 +38 Europe 1957 109989505140 +39 Europe 1962 138984693095 +40 Europe 1967 173366641137 +41 Europe 1972 218691462733 +42 Europe 1977 255367522034 +43 Europe 1982 279484077072 +44 Europe 1987 316507473546 +45 Europe 1992 342703247405 +46 Europe 1997 383606933833 +47 Europe 2002 436448815097 +48 Europe 2007 493183311052 +49 Oceania 1952 54157223944 +50 Oceania 1957 66826828013 +51 Oceania 1962 82336453245 +52 Oceania 1967 105958863585 +53 Oceania 1972 134112109227 +54 Oceania 1977 154707711162 +55 Oceania 1982 176177151380 +56 Oceania 1987 209451563998 +57 Oceania 1992 236319179826 +58 Oceania 1997 289304255183 +59 Oceania 2002 345236880176 +60 Oceania 2007 403657044512 +``` + + +```r +daply( + .data = calcGDP(gapminder), + .variables = c("continent", "year"), + .fun = function(x) mean(x$gdp) +) +``` + +```{.output} + year +continent 1952 1957 1962 1967 1972 + Africa 5992294608 7359188796 8784876958 11443994101 15072241974 + Americas 117738997171 140817061264 169153069442 217867530844 268159178814 + Asia 34095762661 47267432088 60136869012 84648519224 124385747313 + Europe 84971341466 109989505140 138984693095 173366641137 218691462733 + Oceania 54157223944 66826828013 82336453245 105958863585 134112109227 + year +continent 1977 1982 1987 1992 1997 + Africa 18694898732 22040401045 24107264108 26256977719 30023173824 + Americas 324085389022 363314008350 439447790357 489899820623 582693307146 + Asia 159802590186 194429049919 241784763369 307100497486 387597655323 + Europe 255367522034 279484077072 316507473546 342703247405 383606933833 + Oceania 154707711162 176177151380 209451563998 236319179826 289304255183 + year +continent 2002 2007 + Africa 35303511424 45778570846 + Americas 661248623419 776723426068 + Asia 458042336179 627513635079 + Europe 436448815097 493183311052 + Oceania 345236880176 403657044512 +``` + +Puedes usar estas funciones en lugar de ciclos `for` (y generalmente es mas rápido). +Para remplazar un ciclo ‘for', pon el código que estaba en el cuerpo del ciclo `for` dentro de la función anónima. + + +```r +d_ply( + .data=gapminder, + .variables = "continent", + .fun = function(x) { + meanGDPperCap <- mean(x$gdpPercap) + print(paste( + "La media GDP per cápita para", unique(x$continent), + "es", format(meanGDPperCap, big.mark=",") + )) + } +) +``` + +```{.output} +[1] "La media GDP per cápita para Africa es 2,193.755" +[1] "La media GDP per cápita para Americas es 7,136.11" +[1] "La media GDP per cápita para Asia es 7,902.15" +[1] "La media GDP per cápita para Europe es 14,469.48" +[1] "La media GDP per cápita para Oceania es 18,621.61" +``` + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Imprimiendo números + +La función `format` puede ser usada para imprimir los valores numéricos +"bonitos" en los mensajes. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +Calcula el promedio de vida esperado por `"continent"`. ¿Quién tiene el promedio mas alto? +¿Quién tiene el mas pequeño? + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +Calcula el promedio de vida esperado por `"continent"` y `"year"`. ¿Quién tiene el promedio mas +grande y mas corto en 2007? ¿Quién tiene el cambio mas grande entre 1952 +y 2007? + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío Avanzado + +Calcula la diferencia en la media de vida esperada entre los +años 1952 y 2007 a partir de la salida del desafío 2 +usando una de las funciones `plyr`. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío alterno si la clase parece perdida + +Sin ejecutarlos, cuál de los siguientes calculará el promedio +de la esperanza de vida por continente: + +1. + +```r +ddply( + .data = gapminder, + .variables = gapminder$continent, + .fun = function(dataGroup) { + mean(dataGroup$lifeExp) + } +) +``` + +2. + +```r +ddply( + .data = gapminder, + .variables = "continent", + .fun = mean(dataGroup$lifeExp) +) +``` + +3. + +```r +ddply( + .data = gapminder, + .variables = "continent", + .fun = function(dataGroup) { + mean(dataGroup$lifeExp) + } +) +``` + +4. + +```r +adply( + .data = gapminder, + .variables = "continent", + .fun = function(dataGroup) { + mean(dataGroup$lifeExp) + } +) +``` + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Uso del paquete `plyr` para dividir datos, aplicar funciones sobre subconjuntos, y combinar los resultados + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/13-dplyr.md b/13-dplyr.md new file mode 100644 index 00000000..f93f2a7a --- /dev/null +++ b/13-dplyr.md @@ -0,0 +1,559 @@ +--- +title: Manipulación de data frames con dplyr +teaching: 40 +exercises: 15 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Ser capaces de usar las seis principales acciones de manipulación de data frames con pipes en `dplyr`. +- Comprender cómo combinar `group_by()` y `summarize()` para obtener resúmenes de datasets. +- Ser capaces de analizar un subconjunto de datos usando un filtrado lógico. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo manipular data frames sin repetir lo mismo una y otra vez? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +::::::::::::::::::::::::::::::::::::::: checklist + +## Palabras clave + +Comando : Traducción + +`filter` : filtrar + +`select` : seleccionar + +`group_by` : agrupar + +`summarize` : resumir + +`count` : contar + +`mean` : media + +`mutate` : mutar + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +La manipulación de **data frames** significa distintas cosas para distintos investigadores. A veces queremos seleccionar +ciertas observaciones (filas) o variables (columnas), otras veces deseamos agrupar los datos en función de una o más variables, +o queremos calcular valores estadísticos de un conjunto. Podemos hacer todo ello usando las habituales operaciones básicas de R: + + +```r +mean(gapminder[gapminder$continent == "Africa", "gdpPercap"]) +``` + +```{.output} +[1] 2193.755 +``` + +```r +mean(gapminder[gapminder$continent == "Americas", "gdpPercap"]) +``` + +```{.output} +[1] 7136.11 +``` + +```r +mean(gapminder[gapminder$continent == "Asia", "gdpPercap"]) +``` + +```{.output} +[1] 7902.15 +``` + +Pero esto no es muy *elegante* porque hay demasiada repetición. Repetir cosas cuesta tiempo, tanto en el momento de hacerlo como +en el futuro, y aumenta la probabilidad de que se produzcan desagradables *bugs* (errores). + +## El paquete `dplyr` + +Afortunadamente, el paquete [`dplyr`](https://cran.r-project.org/package=dplyr) proporciona un conjunto de funciones +(consulta la [guía rápida](https://raw.githubusercontent.com/rstudio/cheatsheets/master/translations/spanish/data-transformation_es.pdf) ) +extremadamente útiles para manipular **data frames** y así reducir el número de repeticiones , la probabilidad de cometer errores y +el número de caracteres que hay que escribir. Como valor extra, puedes encontrar que la gramática de `dplyr` es más fácil de entender. + +Aquí vamos a revisar 6 de sus funciones más usadas, así como a usar los **pipes** (`%>%`) para combinarlas. + +1. `select()` +2. `filter()` +3. `group_by()` +4. `summarize()` +5. `mutate()` + +Si no has instalado antes este paquete, hazlo del siguiente modo: + + +```r +install.packages('dplyr') +``` + +Ahora vamos a cargar el paquete: + + +```r +library("dplyr") +``` + +## Usando select() + +Si por ejemplo queremos continuar el trabajo con sólo unas pocas de las variables de nuestro **data frame** podemos usar la función `select()`. Esto guardará sólo las variables que seleccionemos. + + +```r +year_country_gdp <- select(gapminder,year,country,gdpPercap) +``` + +![](fig/13-dplyr-fig1.png) + +Si ahora investigamos `year_country_gdp` veremos que sólo contiene el año, el país y la renta per cápita. Arriba hemos usado la gramática 'normal', pero la fortaleza de `dplyr` consiste en combinar funciones usando **pipes**. Como la gramática de las **pipes** es distinta a todo lo que hemos visto antes en R, repitamos lo que hemos hecho arriba, pero esta vez usando **pipes**. + + +```r +year_country_gdp <- gapminder %>% select(year,country,gdpPercap) +``` + +Para ayudarte a entender por qué lo hemos escrito así, vamos a revisarlo por partes. Primero hemos llamado al **data frame** "gapminder" y se lo hemos pasado al siguiente paso, que es la función `select()`, usando el símbolo del **pipe** `%>%`. En este caso no especificamos qué objeto de datos vamos a usar en la función `select()` porque esto se obtiene del resultado de la instrucción previa a el **pipe**. **Dato curioso:** es muy posible que te hayas encontrado con **pipes** antes en la terminal de unix. En R el símbolo del **pipe** es `%>%`, mientras que en la terminal es `|`, pero el concepto es el mismo. + +## Usando filter() + +Si ahora queremos continuar con lo de arriba, pero sólo con los países europeos, podemos combinar `select` y `filter`. + + +```r +year_country_gdp_euro <- gapminder %>% + filter(continent=="Europe") %>% + select(year,country,gdpPercap) +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Reto 1 + +Escribe un único comando (que puede ocupar varias líneas e incluir **pipes**) +que produzca un **data frame** y que tenga los valores africanos correspondientes +a `lifeExp`, `country` y `year`, pero no de los otros continentes. +¿Cuántas filas tiene dicho **data frame** y por qué? + +::::::::::::::: solution + +## Solución al Reto 1 + + +```r +year_country_lifeExp_Africa <- gapminder %>% + filter(continent=="Africa") %>% + select(year,country,lifeExp) +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Al igual que la vez anterior, primero le pasamos el **data frame** "gapminder" a la función `filter()` y luego le pasamos la versión filtrada del **data frame** a la función `select()`. **Nota:** El orden de las operaciones es muy importante en este caso. Si usamos primero `select()`, la función `filter()` no habría podido encontrar la variable "continent" porque la habríamos eliminado en el paso previo. + +## Usando group\_by() y summarize() + +Se suponía que teníamos que reducir las repeticiones causantes de errores de lo que se puede hacer con el R básico, pero hasta ahora no lo hemos conseguido porque tendríamos que repetir lo escrito arriba para cada continente. En lugar de `filter()`, que solamente deja pasar las observaciones que se ajustan a tu criterio (`continent = Europe` en lo escrito arriba), podemos usar `group_by()`, que esencialmente usará cada uno de los criterios únicos que podrías haber usado con `filter()`. + + +```r +str(gapminder) +``` + +```{.output} +'data.frame': 1704 obs. of 6 variables: + $ country : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... + $ year : int 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ... + $ pop : num 8425333 9240934 10267083 11537966 13079460 ... + $ continent: chr "Asia" "Asia" "Asia" "Asia" ... + $ lifeExp : num 28.8 30.3 32 34 36.1 ... + $ gdpPercap: num 779 821 853 836 740 ... +``` + +```r +str(gapminder %>% group_by(continent)) +``` + +```{.output} +gropd_df [1,704 × 6] (S3: grouped_df/tbl_df/tbl/data.frame) + $ country : chr [1:1704] "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... + $ year : int [1:1704] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ... + $ pop : num [1:1704] 8425333 9240934 10267083 11537966 13079460 ... + $ continent: chr [1:1704] "Asia" "Asia" "Asia" "Asia" ... + $ lifeExp : num [1:1704] 28.8 30.3 32 34 36.1 ... + $ gdpPercap: num [1:1704] 779 821 853 836 740 ... + - attr(*, "groups")= tibble [5 × 2] (S3: tbl_df/tbl/data.frame) + ..$ continent: chr [1:5] "Africa" "Americas" "Asia" "Europe" ... + ..$ .rows : list [1:5] + .. ..$ : int [1:624] 25 26 27 28 29 30 31 32 33 34 ... + .. ..$ : int [1:300] 49 50 51 52 53 54 55 56 57 58 ... + .. ..$ : int [1:396] 1 2 3 4 5 6 7 8 9 10 ... + .. ..$ : int [1:360] 13 14 15 16 17 18 19 20 21 22 ... + .. ..$ : int [1:24] 61 62 63 64 65 66 67 68 69 70 ... + .. ..@ ptype: int(0) + ..- attr(*, ".drop")= logi TRUE +``` + +Se puede observar que la estructura del **data frame** obtenido por `group_by()` (`grouped_df`) no es la misma que la del **data frame** original `gapminder`(`data.fram`). Se puede pensar en un `grouped_df` como en una `list` donde cada item in la `list` es un `data.frame` que contiene únicamente las filas que corresponden a un valor particular de `continent` (en el ejemplo mostrado). + +![](fig/13-dplyr-fig2.png) + +## Usando summarize() + +Lo visto arriba no es muy sofisticado, pero `group_by()` es más interesante y útil si se usa en conjunto con `summarize()`. Esto nos permitirá crear nuevas variables usando funciones que se aplican a cada uno de los **data frames** específicos para cada continente. Es decir, usando la función `group_by()` dividimos nuestro **data frame** original en varias partes, a las que luego podemos aplicarles funciones (por ejemplo, `mean()` o `sd()`) independientemente con `summarize()`. + + +```r +gdp_bycontinents <- gapminder %>% + group_by(continent) %>% + summarize(mean_gdpPercap=mean(gdpPercap)) +``` + +![](fig/13-dplyr-fig3.png) + + +```r +continent mean_gdpPercap + +1 Africa 2193.755 +2 Americas 7136.110 +3 Asia 7902.150 +4 Europe 14469.476 +5 Oceania 18621.609 +``` + +Esto nos ha permitido calcular la renta per cápita media para cada continente, pero puede ser todavía mucho mejor. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Reto 2 + +Calcula la esperanza de vida media por país. ¿Qué país tiene la esperanza de vida media mayor +y cuál la menor? + +::::::::::::::: solution + +## Solución al Reto 2 + + +```r +lifeExp_bycountry <- gapminder %>% + group_by(country) %>% + summarize(mean_lifeExp=mean(lifeExp)) +lifeExp_bycountry %>% + filter(mean_lifeExp == min(mean_lifeExp) | mean_lifeExp == max(mean_lifeExp)) +``` + +```{.output} +# A tibble: 2 × 2 + country mean_lifeExp + +1 Iceland 76.5 +2 Sierra Leone 36.8 +``` + +Otro modo de hacer esto es usando la función `arrange()` del paquete `dplyr`, +que distribuye las filas de un **data frame** en función del orden de una +o más variables del **data frame**. Tiene una sintaxis similar a otras funciones +del paquete `dplyr`. Se puede usar `desc()` dentro de `arrange()` para +ordenar de modo descendente. + + +```r +lifeExp_bycountry %>% + arrange(mean_lifeExp) %>% + head(1) +``` + +```{.output} +# A tibble: 1 × 2 + country mean_lifeExp + +1 Sierra Leone 36.8 +``` + +```r +lifeExp_bycountry %>% + arrange(desc(mean_lifeExp)) %>% + head(1) +``` + +```{.output} +# A tibble: 1 × 2 + country mean_lifeExp + +1 Iceland 76.5 +``` + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +::::::::::::::::::::::::: + +La función `group_by()` nos permite agrupar en función de varias variables. Vamos a agrupar por `year` y `continent`. + + +```r +gdp_bycontinents_byyear <- gapminder %>% + group_by(continent,year) %>% + summarize(mean_gdpPercap=mean(gdpPercap)) +``` + +```{.output} +`summarise()` has grouped output by 'continent'. You can override using the +`.groups` argument. +``` + +Esto ya es bastante potente, pero puede ser incluso mejor. Puedes definir más de una variable en `summarize()`. + + +```r +gdp_pop_bycontinents_byyear <- gapminder %>% + group_by(continent,year) %>% + summarize(mean_gdpPercap=mean(gdpPercap), + sd_gdpPercap=sd(gdpPercap), + mean_pop=mean(pop), + sd_pop=sd(pop)) +``` + +```{.output} +`summarise()` has grouped output by 'continent'. You can override using the +`.groups` argument. +``` + +## count() y n() + +Una operación muy habitual es contar el número de observaciones que hay en cada grupo. El paquete `dplyr` tiene dos funciones relacionadas muy útiles para ello. + +Por ejemplo, si queremos comprobar el número de países que hay en el conjunto de datos para el año 2002 podemos usar la función `count()`. Dicha función toma el nombre de una o más columnas que contienen los grupos en los que estamos interesados y puede opcionalmente ordenar los resultados en modo descendente si añadimos `sort = TRUE`. + + +```r +gapminder %>% + filter(year == 2002) %>% + count(continent, sort = TRUE) +``` + +```{.output} + continent n +1 Africa 52 +2 Asia 33 +3 Europe 30 +4 Americas 25 +5 Oceania 2 +``` + +Si necesitamos usar en nuestros cálculos el número de observaciones obtenidas, la función `n()` es muy útil. Por ejemplo, si queremos obtener el error estándar de la esperanza de vida por continente: + + +```r +gapminder %>% + group_by(continent) %>% + summarize(se_pop = sd(lifeExp)/sqrt(n())) +``` + +```{.output} +# A tibble: 5 × 2 + continent se_pop + +1 Africa 0.366 +2 Americas 0.540 +3 Asia 0.596 +4 Europe 0.286 +5 Oceania 0.775 +``` + +También se pueden encadenar juntas varias operaciones de resumen, como en el caso siguiente, en el que calculamos el `minimum`, `maximum`, `mean` y `se` de la esperanza de vida por país para cada continente: + + +```r +gapminder %>% + group_by(continent) %>% + summarize( + mean_le = mean(lifeExp), + min_le = min(lifeExp), + max_le = max(lifeExp), + se_le = sd(lifeExp)/sqrt(n())) +``` + +```{.output} +# A tibble: 5 × 5 + continent mean_le min_le max_le se_le + +1 Africa 48.9 23.6 76.4 0.366 +2 Americas 64.7 37.6 80.7 0.540 +3 Asia 60.1 28.8 82.6 0.596 +4 Europe 71.9 43.6 81.8 0.286 +5 Oceania 74.3 69.1 81.2 0.775 +``` + +## Usando mutate() + +También se pueden crear nuevas variables antes (o incluso después) de resumir la información usando `mutate()`. + + +```r +gdp_pop_bycontinents_byyear <- gapminder %>% + mutate(gdp_billion=gdpPercap*pop/10^9) %>% + group_by(continent,year) %>% + summarize(mean_gdpPercap=mean(gdpPercap), + sd_gdpPercap=sd(gdpPercap), + mean_pop=mean(pop), + sd_pop=sd(pop), + mean_gdp_billion=mean(gdp_billion), + sd_gdp_billion=sd(gdp_billion)) +``` + +```{.output} +`summarise()` has grouped output by 'continent'. You can override using the +`.groups` argument. +``` + +## Conectando mutate con filtrado lógico: ifelse + +La creación de nuevas variables se puede conectar con una condición lógica. Una simple combinación de `mutate` y `ifelse` facilita el filtrado solo allí donde se necesita: en el momento de crear algo nuevo. Esta combinación es fácil de leer y es un modo rápido y potente de descartar ciertos datos (incluso sin cambiar la dimensión conjunta del **data frame**) o para actualizar valores dependiendo de la condición utilizada. + + +```r +## manteniendo todos los datos pero "filtrando" según una determinada condición +# calcular renta per cápita sólo para gente con una esperanza de vida por encima de 25 +gdp_pop_bycontinents_byyear_above25 <- gapminder %>% + mutate(gdp_billion = ifelse(lifeExp > 25, gdpPercap * pop / 10^9, NA)) %>% + group_by(continent, year) %>% + summarize(mean_gdpPercap = mean(gdpPercap), + sd_gdpPercap = sd(gdpPercap), + mean_pop = mean(pop), + sd_pop = sd(pop), + mean_gdp_billion = mean(gdp_billion), + sd_gdp_billion = sd(gdp_billion)) +``` + +```{.output} +`summarise()` has grouped output by 'continent'. You can override using the +`.groups` argument. +``` + +```r +## actualizando sólo si se cumple una determinada condición +# para esperanzas de vida por encima de 40 años, el GDP que se espera en el futuro es escalado +gdp_future_bycontinents_byyear_high_lifeExp <- gapminder %>% + mutate(gdp_futureExpectation = ifelse(lifeExp > 40, gdpPercap * 1.5, gdpPercap)) %>% + group_by(continent, year) %>% + summarize(mean_gdpPercap = mean(gdpPercap), + mean_gdpPercap_expected = mean(gdp_futureExpectation)) +``` + +```{.output} +`summarise()` has grouped output by 'continent'. You can override using the +`.groups` argument. +``` + +## Combinando `dplyr` y `ggplot2` + +En la función de creación de gráficas vimos cómo hacer una figura con múltiples paneles añadiendo una capa de paneles separados (**facet panels**). Aquí está el código que usamos (con algunos comentarios extra): + + +```r +# Obtener la primera letra de cada país +starts.with <- substr(gapminder$country, start = 1, stop = 1) +# Filtrar países que empiezan con "A" o "Z" +az.countries <- gapminder[starts.with %in% c("A", "Z"), ] +# Construir el gráfico +ggplot(data = az.countries, aes(x = year, y = lifeExp, color = continent)) + + geom_line() + facet_wrap( ~ country) +``` + +```{.error} +Error in ggplot(data = az.countries, aes(x = year, y = lifeExp, color = continent)): could not find function "ggplot" +``` + +Este código construye la gráfica correcta, pero también crea algunas variables `starts.with` y `az.countries`) que podemos no querer usar para nada más. Del mismo modo que usamos `%>%` para pasar datos con **pipes** a lo largo de una cadena de funciones `dplyr`, podemos usarlo para pasarle datos a `ggplot()`. Como `%>%` sustituye al primer argumento de una función, no necesitamos especificar el argumento `data=` de la función `ggplot()`. Combinando funciones de los paquetes `dplyr` y `ggplot` podemos hacer la misma figura sin crear ninguna nueva variable y sin modificar los datos. + + +```r +gapminder %>% + # Get the start letter of each country + mutate(startsWith = substr(country, start = 1, stop = 1)) %>% + # Filter countries that start with "A" or "Z" + filter(startsWith %in% c("A", "Z")) %>% + # Make the plot + ggplot(aes(x = year, y = lifeExp, color = continent)) + + geom_line() + + facet_wrap( ~ country) +``` + +```{.error} +Error in ggplot(., aes(x = year, y = lifeExp, color = continent)): could not find function "ggplot" +``` + +Las funciones del paquete `dplyr` también nos ayudan a simplificar las cosas, por ejemplo, combinando los primeros dos pasos: + + +```r +gapminder %>% + # Filter countries that start with "A" or "Z" + filter(substr(country, start = 1, stop = 1) %in% c("A", "Z")) %>% + # Make the plot + ggplot(aes(x = year, y = lifeExp, color = continent)) + + geom_line() + + facet_wrap( ~ country) +``` + +```{.error} +Error in ggplot(., aes(x = year, y = lifeExp, color = continent)): could not find function "ggplot" +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Reto Avanzado + +Calcula la esperanza de vida media en 2002 de dos países seleccionados al azar +para cada continente. Luego distribuye los nombres de los continentes en orden inverso. +**Pista**: Usa las funciones `arrange()` y `sample_n()` del paquete `dplyr`, tienen +una sintaxis similar a las demás funciones del paquete `dplyr`. + +::::::::::::::: solution + +## Solución al Reto Avanzado + + +```r +lifeExp_2countries_bycontinents <- gapminder %>% + filter(year==2002) %>% + group_by(continent) %>% + sample_n(2) %>% + summarize(mean_lifeExp=mean(lifeExp)) %>% + arrange(desc(mean_lifeExp)) +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Más información + +- [R for Data Science](https://r4ds.had.co.nz/) +- [Data Wrangling Cheat sheet](https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf) +- [Introduction to dplyr](https://cran.rstudio.com/web/packages/dplyr/vignettes/dplyr.html) +- [Data wrangling with R and RStudio](https://www.rstudio.com/resources/webinars/data-wrangling-with-r-and-rstudio/) + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Usar el paquete `dplyr` para manipular data frames. +- Usar `select()` para seleccionar variables de un data frame. +- Usar `filter()` para seleccionar datos basándose en los valores. +- Usar `group_by()` y `summarize()` para trabajar con subconjuntos de datos. +- Usar `mutate()` para crear nuevas variables. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/14-tidyr.md b/14-tidyr.md new file mode 100644 index 00000000..1ce98b66 --- /dev/null +++ b/14-tidyr.md @@ -0,0 +1,554 @@ +--- +title: Manipulación de data frames usando tidyr +teaching: 30 +exercises: 15 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Entender los conceptos de formatos de datos largo y ancho y poder convertirlos al otro formato usando `tidyr`. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo cambiar el formato de los data frames? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +Las investigadoras a menudo quieren manipular sus datos del formato "ancho" al "largo", o viceversa. El formato "largo" es donde: + +- cada columna es una variable +- cada fila es una observación + +En el formato "largo", generalmente tienes una columna para la variable observada y las otras columnas son variables de ID. + +Para el formato "ancho", cada fila es un tema, por ejemplo un lugar o un paciente. Tendrás múltiples variables de observación, que contienen el mismo tipo de datos, para cada tema. Estas observaciones pueden ser +repetidas a lo largo del tiempo, o puede ser la observación de múltiples variables (o +una mezcla de ambos). Para algunas aplicaciones, es preferible el formato "ancho". Sin embargo, muchas de las funciones de `R` han +sido diseñadas para datos de formato "largo". Este tutorial te ayudará a transformar tus datos de manera eficiente, independientemente del formato original. + +![](fig/14-tidyr-fig1.png) + +Estos formatos de datos afectan principalmente a la legibilidad. Para los humanos, el formato "ancho" es +a menudo más intuitivo ya que podemos ver más de los datos en la pantalla debido a su forma. Sin embargo, el formato "largo" es más legible para las máquinas y está más cerca +al formateo de las bases de datos. Las variables de ID en nuestros marcos de datos son similares a +los campos en una base de datos y las variables observadas son como los valores de la base de datos. + +## Empecemos + +Primero instala los paquetes necesarios, `tidyr` y `dplyr`. Si aún no lo has hecho, puedes también instalar el grupo de paquetes `tidyverse` que contiene varios paquetes incluyendo `tidyr` y `dplyr`. + + +```r +#install.packages("tidyr") +#install.packages("dplyr") +``` + +Ahora carga los paquetes usando **library**. + + +```r +library("tidyr") +library("dplyr") +``` + +Primero, veamos la estructura **structure** del **data frame** gapminder: + + +```r +str(gapminder) +``` + +```{.output} +'data.frame': 1704 obs. of 6 variables: + $ country : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... + $ year : int 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ... + $ pop : num 8425333 9240934 10267083 11537966 13079460 ... + $ continent: chr "Asia" "Asia" "Asia" "Asia" ... + $ lifeExp : num 28.8 30.3 32 34 36.1 ... + $ gdpPercap: num 779 821 853 836 740 ... +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 1 + +¿Crees que el data frame gapminder tiene un formato largo, ancho o algo intermedio? + +::::::::::::::: solution + +## Solución del Desafío 1 + +El data frame gapminder tiene un formato intermedio. No es completamente +largo porque tiene múltiples observaciones por cada variable +(`pop`,`lifeExp`,`gdpPercap`). + + + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +A veces tenemos múltiples tipos de observaciones, como con el **data frame** gapminder. Entonces tendremos formatos de datos mixtos entre "largo" y "ancho". Nosotros tenemos 3 "variables de identificación" (`continente`,` país`, `año`) y 3 "variables de observación" (` pop`, `lifeExp`,`gdpPercap`). Generalmente, es preferible que los datos estén en este formato intermedio en la mayoría de los casos, a pesar de no tener TODAS las observaciones en una sola +columna. Esto es por que las 3 variables de observación tienen unidades diferentes (y cada una corresponde a una columna con su propio tipo de datos). + +A menudo queremos hacer operaciones matemáticas con valores que usen las mismas +unidades, esto facilita el uso de funciones en R, que a menudo se basan en vectores. Por ejemplo, si utilizamos el formato largo y calculamos un promedio de todos los +los valores de población `pop`, esperanza de vida `lifeExp` y el PIB ` gdpPercap` este resultado no tendría sentido, ya que +devolvería una incongruencia de valores con 3 unidades incompatibles. La solución es que primero manipulamos los datos agrupando (ver la lección sobre `dplyr`), o +cambiamos la estructura del marco de datos. **Nota:** Algunas funciones de gráficos en R (por ejemplo con `ggplot2`) realmente funcionan mejor con los datos de formato ancho. + +## Del formato ancho al largo con gather() + +Hasta ahora, hemos estado utilizando el conjunto de datos gapminder original muy bien formateado, pero +los datos "reales" (es decir, nuestros propios datos de investigación) nunca estarán tan bien organizados. Veamos un ejemplo con la versión de formato ancho del conjunto de datos gapminder. + +::::::::::::::::::::::::::::::::::::::::: callout + +Descarga la versión ancha de los datos de gapminder desde [aquí] ([https://raw.githubusercontent.com/swcarpentry/r-novice-gapminder/gh-pages/\_episodes\_rmd/data/gapminder\_wide.csv](https://raw.githubusercontent.com/swcarpentry/r-novice-gapminder/gh-pages/_episodes_rmd/data/gapminder_wide.csv)) +y guarda el archivo csv en tu carpeta de datos. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Cargaremos el archivo de datos para verlo. Nota: no queremos que las columnas de caracteres sean convertidas a factores, por lo que usamos el argumento `stringsAsFactors = FALSE` para para deshabilitar eso, más información en la ayuda `?read.csv ()`. + + +```r +gap_wide <- read.csv("data/gapminder_wide.csv", stringsAsFactors = FALSE) +str(gap_wide) +``` + +```{.output} +'data.frame': 142 obs. of 38 variables: + $ continent : chr "Africa" "Africa" "Africa" "Africa" ... + $ country : chr "Algeria" "Angola" "Benin" "Botswana" ... + $ gdpPercap_1952: num 2449 3521 1063 851 543 ... + $ gdpPercap_1957: num 3014 3828 960 918 617 ... + $ gdpPercap_1962: num 2551 4269 949 984 723 ... + $ gdpPercap_1967: num 3247 5523 1036 1215 795 ... + $ gdpPercap_1972: num 4183 5473 1086 2264 855 ... + $ gdpPercap_1977: num 4910 3009 1029 3215 743 ... + $ gdpPercap_1982: num 5745 2757 1278 4551 807 ... + $ gdpPercap_1987: num 5681 2430 1226 6206 912 ... + $ gdpPercap_1992: num 5023 2628 1191 7954 932 ... + $ gdpPercap_1997: num 4797 2277 1233 8647 946 ... + $ gdpPercap_2002: num 5288 2773 1373 11004 1038 ... + $ gdpPercap_2007: num 6223 4797 1441 12570 1217 ... + $ lifeExp_1952 : num 43.1 30 38.2 47.6 32 ... + $ lifeExp_1957 : num 45.7 32 40.4 49.6 34.9 ... + $ lifeExp_1962 : num 48.3 34 42.6 51.5 37.8 ... + $ lifeExp_1967 : num 51.4 36 44.9 53.3 40.7 ... + $ lifeExp_1972 : num 54.5 37.9 47 56 43.6 ... + $ lifeExp_1977 : num 58 39.5 49.2 59.3 46.1 ... + $ lifeExp_1982 : num 61.4 39.9 50.9 61.5 48.1 ... + $ lifeExp_1987 : num 65.8 39.9 52.3 63.6 49.6 ... + $ lifeExp_1992 : num 67.7 40.6 53.9 62.7 50.3 ... + $ lifeExp_1997 : num 69.2 41 54.8 52.6 50.3 ... + $ lifeExp_2002 : num 71 41 54.4 46.6 50.6 ... + $ lifeExp_2007 : num 72.3 42.7 56.7 50.7 52.3 ... + $ pop_1952 : num 9279525 4232095 1738315 442308 4469979 ... + $ pop_1957 : num 10270856 4561361 1925173 474639 4713416 ... + $ pop_1962 : num 11000948 4826015 2151895 512764 4919632 ... + $ pop_1967 : num 12760499 5247469 2427334 553541 5127935 ... + $ pop_1972 : num 14760787 5894858 2761407 619351 5433886 ... + $ pop_1977 : num 17152804 6162675 3168267 781472 5889574 ... + $ pop_1982 : num 20033753 7016384 3641603 970347 6634596 ... + $ pop_1987 : num 23254956 7874230 4243788 1151184 7586551 ... + $ pop_1992 : num 26298373 8735988 4981671 1342614 8878303 ... + $ pop_1997 : num 29072015 9875024 6066080 1536536 10352843 ... + $ pop_2002 : int 31287142 10866106 7026113 1630347 12251209 7021078 15929988 4048013 8835739 614382 ... + $ pop_2007 : int 33333216 12420476 8078314 1639131 14326203 8390505 17696293 4369038 10238807 710960 ... +``` + +![](fig/14-tidyr-fig2.png) + +El primer paso es formatear los datos de ancho a largo. Usando el paquete `tidyr` y la función `gather()` podemos juntar las variables de observación en una sola variable. + +![](fig/14-tidyr-fig3.png) + + +```r +gap_long <- gap_wide %>% + gather(obstype_year, obs_values, starts_with("pop"), + starts_with("lifeExp"), starts_with("gdpPercap")) +str(gap_long) +``` + +```{.output} +'data.frame': 5112 obs. of 4 variables: + $ continent : chr "Africa" "Africa" "Africa" "Africa" ... + $ country : chr "Algeria" "Angola" "Benin" "Botswana" ... + $ obstype_year: chr "pop_1952" "pop_1952" "pop_1952" "pop_1952" ... + $ obs_values : num 9279525 4232095 1738315 442308 4469979 ... +``` + +Aquí hemos utilizado la sintaxis con **pipes** (%>%) igual a como lo que estábamos usando en el lección anterior con `dplyr`. De hecho, estos son compatibles y puedes usar una mezcla de las funciones `tidyr` y `dplyr`. + +Dentro de `gather()`, primero nombramos la nueva columna para la nueva variable de ID +(`obstype_year`), el nombre de la nueva variable de observación conjunta +(`obs_value`), luego los nombres de la antigua variable de observación. Nosotros podríamos tener escritas todas las variables de observación, pero como lo hacíamos en la función `select()` (ver la lección de `dplyr`), podemos usar el argumento `starts_with()` para seleccionar todas las variables que comiencen con la cadena de caracteres deseada. Reunir o **gather** también permite la +sintaxis alternativa del uso del símbolo `-` para identificar qué variables queremos excluir (por ejemplo, las variables de identificación o **ID**) + +![](fig/14-tidyr-fig4.png) + + +```r +gap_long <- gap_wide %>% gather(obstype_year, obs_values, -continent, -country) +str(gap_long) +``` + +```{.output} +'data.frame': 5112 obs. of 4 variables: + $ continent : chr "Africa" "Africa" "Africa" "Africa" ... + $ country : chr "Algeria" "Angola" "Benin" "Botswana" ... + $ obstype_year: chr "gdpPercap_1952" "gdpPercap_1952" "gdpPercap_1952" "gdpPercap_1952" ... + $ obs_values : num 2449 3521 1063 851 543 ... +``` + +Eso puede parecer trivial con este **data frame** en particular, pero a veces tienes una variable de identificación **ID** y 40 variables de observación, con varios nombres de variables irregulares. La flexibilidad que nos da `tidyr` ¡es un gran ahorro de tiempo! + +Ahora, `obstype_year` en realidad contiene información en dos partes, la observación +tipo (`pop`,` lifeExp`, o `gdpPercap`) y el año `year`. Podemos usar la función `separate()` para dividir las cadenas de caracteres en múltiples variables. + + +```r +gap_long <- gap_long %>% separate(obstype_year, into = c("obs_type", "year"), sep = "_") +gap_long$year <- as.integer(gap_long$year) +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 2 + +Usando el **data frame** `gap_long`, calcula el promedio de esperanza de vida, población, y PIB por cada continente. +**Ayuda:** usa `group_by()` y `summarize()` que son las funciones de `dplyr` que aprendiste en el episodio anterior. + +::::::::::::::: solution + +## Solución al Desafío 2 + + +```r +gap_long %>% + group_by(continent, obs_type) %>% + summarize(means = mean(obs_values)) +``` + +```{.output} +`summarise()` has grouped output by 'continent'. You can override using the +`.groups` argument. +``` + +```{.output} +# A tibble: 15 × 3 +# Groups: continent [5] + continent obs_type means + + 1 Africa gdpPercap 2194. + 2 Africa lifeExp 48.9 + 3 Africa pop 9916003. + 4 Americas gdpPercap 7136. + 5 Americas lifeExp 64.7 + 6 Americas pop 24504795. + 7 Asia gdpPercap 7902. + 8 Asia lifeExp 60.1 + 9 Asia pop 77038722. +10 Europe gdpPercap 14469. +11 Europe lifeExp 71.9 +12 Europe pop 17169765. +13 Oceania gdpPercap 18622. +14 Oceania lifeExp 74.3 +15 Oceania pop 8874672. +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Del formato largo a intermedio usando spread() + +Siempre es bueno detenerse y verificar el trabajo. Entonces, usemos el opuesto de `gather()` para separar nuestras variables de observación con la función `spread()`. Para expandir nuestro objeto `gap_long()` al formato intermedio original o al formato ancho usaremos esta nueva función. Comencemos con el formato intermedio. + + +```r +gap_normal <- gap_long %>% spread(obs_type,obs_values) +dim(gap_normal) +``` + +```{.output} +[1] 1704 6 +``` + +```r +dim(gapminder) +``` + +```{.output} +[1] 1704 6 +``` + +```r +names(gap_normal) +``` + +```{.output} +[1] "continent" "country" "year" "gdpPercap" "lifeExp" "pop" +``` + +```r +names(gapminder) +``` + +```{.output} +[1] "country" "year" "pop" "continent" "lifeExp" "gdpPercap" +``` + +Ahora tenemos un marco de datos intermedio `gap_normal` con las mismas dimensiones que el `gapminder` original, pero el orden de las variables es diferente. Arreglemos +eso antes de comprobar si son iguales con la función `all.equal()`. + + +```r +gap_normal <- gap_normal[,names(gapminder)] +all.equal(gap_normal,gapminder) +``` + +```{.output} +[1] "Component \"country\": 1704 string mismatches" +[2] "Component \"pop\": Mean relative difference: 1.634504" +[3] "Component \"continent\": 1212 string mismatches" +[4] "Component \"lifeExp\": Mean relative difference: 0.203822" +[5] "Component \"gdpPercap\": Mean relative difference: 1.162302" +``` + +```r +head(gap_normal) +``` + +```{.output} + country year pop continent lifeExp gdpPercap +1 Algeria 1952 9279525 Africa 43.077 2449.008 +2 Algeria 1957 10270856 Africa 45.685 3013.976 +3 Algeria 1962 11000948 Africa 48.303 2550.817 +4 Algeria 1967 12760499 Africa 51.407 3246.992 +5 Algeria 1972 14760787 Africa 54.518 4182.664 +6 Algeria 1977 17152804 Africa 58.014 4910.417 +``` + +```r +head(gapminder) +``` + +```{.output} + country year pop continent lifeExp gdpPercap +1 Afghanistan 1952 8425333 Asia 28.801 779.4453 +2 Afghanistan 1957 9240934 Asia 30.332 820.8530 +3 Afghanistan 1962 10267083 Asia 31.997 853.1007 +4 Afghanistan 1967 11537966 Asia 34.020 836.1971 +5 Afghanistan 1972 13079460 Asia 36.088 739.9811 +6 Afghanistan 1977 14880372 Asia 38.438 786.1134 +``` + +Ya casi, el **data frame** original está ordenado por `country`, `continent`, y +`year`. Entonces probemos con la función `arrange()`. + + +```r +gap_normal <- gap_normal %>% arrange(country, continent, year) +all.equal(gap_normal, gapminder) +``` + +```{.output} +[1] TRUE +``` + +¡Muy bien! Pasamos del formato largo al intermedio y no hemos +tenido ningún error en nuestro código. + +Ahora pasemos a convertir del formato largo al ancho. En el formato ancho, nosotros +mantendremos el país y el continente como variables de ID y esto va expandir las observaciones +en las tres métricas (`pop`,` lifeExp`, `gdpPercap`) y año (` year`). Primero nosotros +necesitamos crear etiquetas apropiadas para todas nuestras nuevas variables (combinaciones de métricas\*año) y también necesitamos unificar nuestras variables de **ID** para simplificar el proceso de definir el nuevo objeto `gap_wide`. + + +```r +gap_temp <- gap_long %>% unite(var_ID, continent, country, sep = "_") +str(gap_temp) +``` + +```{.output} +'data.frame': 5112 obs. of 4 variables: + $ var_ID : chr "Africa_Algeria" "Africa_Angola" "Africa_Benin" "Africa_Botswana" ... + $ obs_type : chr "gdpPercap" "gdpPercap" "gdpPercap" "gdpPercap" ... + $ year : int 1952 1952 1952 1952 1952 1952 1952 1952 1952 1952 ... + $ obs_values: num 2449 3521 1063 851 543 ... +``` + +```r +gap_temp <- gap_long %>% + unite(ID_var, continent, country, sep = "_") %>% + unite(var_names, obs_type, year, sep = "_") +str(gap_temp) +``` + +```{.output} +'data.frame': 5112 obs. of 3 variables: + $ ID_var : chr "Africa_Algeria" "Africa_Angola" "Africa_Benin" "Africa_Botswana" ... + $ var_names : chr "gdpPercap_1952" "gdpPercap_1952" "gdpPercap_1952" "gdpPercap_1952" ... + $ obs_values: num 2449 3521 1063 851 543 ... +``` + +Usando la función `unite()` tenemos ahora un único **ID** que es la combinación de +`continent`, `country`, y así definimos nuestras nuevas variables. Ahora podemos usar ese resultado con la función `spread()`. + + +```r +gap_wide_new <- gap_long %>% + unite(ID_var, continent, country, sep = "_") %>% + unite(var_names, obs_type, year,sep = "_") %>% + spread(var_names, obs_values) +str(gap_wide_new) +``` + +```{.output} +'data.frame': 142 obs. of 37 variables: + $ ID_var : chr "Africa_Algeria" "Africa_Angola" "Africa_Benin" "Africa_Botswana" ... + $ gdpPercap_1952: num 2449 3521 1063 851 543 ... + $ gdpPercap_1957: num 3014 3828 960 918 617 ... + $ gdpPercap_1962: num 2551 4269 949 984 723 ... + $ gdpPercap_1967: num 3247 5523 1036 1215 795 ... + $ gdpPercap_1972: num 4183 5473 1086 2264 855 ... + $ gdpPercap_1977: num 4910 3009 1029 3215 743 ... + $ gdpPercap_1982: num 5745 2757 1278 4551 807 ... + $ gdpPercap_1987: num 5681 2430 1226 6206 912 ... + $ gdpPercap_1992: num 5023 2628 1191 7954 932 ... + $ gdpPercap_1997: num 4797 2277 1233 8647 946 ... + $ gdpPercap_2002: num 5288 2773 1373 11004 1038 ... + $ gdpPercap_2007: num 6223 4797 1441 12570 1217 ... + $ lifeExp_1952 : num 43.1 30 38.2 47.6 32 ... + $ lifeExp_1957 : num 45.7 32 40.4 49.6 34.9 ... + $ lifeExp_1962 : num 48.3 34 42.6 51.5 37.8 ... + $ lifeExp_1967 : num 51.4 36 44.9 53.3 40.7 ... + $ lifeExp_1972 : num 54.5 37.9 47 56 43.6 ... + $ lifeExp_1977 : num 58 39.5 49.2 59.3 46.1 ... + $ lifeExp_1982 : num 61.4 39.9 50.9 61.5 48.1 ... + $ lifeExp_1987 : num 65.8 39.9 52.3 63.6 49.6 ... + $ lifeExp_1992 : num 67.7 40.6 53.9 62.7 50.3 ... + $ lifeExp_1997 : num 69.2 41 54.8 52.6 50.3 ... + $ lifeExp_2002 : num 71 41 54.4 46.6 50.6 ... + $ lifeExp_2007 : num 72.3 42.7 56.7 50.7 52.3 ... + $ pop_1952 : num 9279525 4232095 1738315 442308 4469979 ... + $ pop_1957 : num 10270856 4561361 1925173 474639 4713416 ... + $ pop_1962 : num 11000948 4826015 2151895 512764 4919632 ... + $ pop_1967 : num 12760499 5247469 2427334 553541 5127935 ... + $ pop_1972 : num 14760787 5894858 2761407 619351 5433886 ... + $ pop_1977 : num 17152804 6162675 3168267 781472 5889574 ... + $ pop_1982 : num 20033753 7016384 3641603 970347 6634596 ... + $ pop_1987 : num 23254956 7874230 4243788 1151184 7586551 ... + $ pop_1992 : num 26298373 8735988 4981671 1342614 8878303 ... + $ pop_1997 : num 29072015 9875024 6066080 1536536 10352843 ... + $ pop_2002 : num 31287142 10866106 7026113 1630347 12251209 ... + $ pop_2007 : num 33333216 12420476 8078314 1639131 14326203 ... +``` + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío 3 + +Crea un formato de datos `gap_super_wide` mediante la distribución por países, año y las tres métricas. +**Ayuda** este nuevo **data frame** sólo debe tener cinco filas. + +::::::::::::::: solution + +## Solución para el desafío 3 + + +```r +gap_super_wide <- gap_long %>% + unite(var_names, obs_type, year, country, sep = "_") %>% + spread(var_names, obs_values) +``` + +::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +Ahora tenemos un gran **data frame** con formato 'ancho', pero el `ID_var` podría ser más mejor, hay que separarlos en dos variables con `separate()` + + +```r +gap_wide_betterID <- separate(gap_wide_new, ID_var, c("continent", "country"), sep = "_") +gap_wide_betterID <- gap_long %>% + unite(ID_var, continent, country, sep = "_") %>% + unite(var_names, obs_type, year, sep = "_") %>% + spread(var_names, obs_values) %>% + separate(ID_var, c("continent", "country"), sep = "_") +str(gap_wide_betterID) +``` + +```{.output} +'data.frame': 142 obs. of 38 variables: + $ continent : chr "Africa" "Africa" "Africa" "Africa" ... + $ country : chr "Algeria" "Angola" "Benin" "Botswana" ... + $ gdpPercap_1952: num 2449 3521 1063 851 543 ... + $ gdpPercap_1957: num 3014 3828 960 918 617 ... + $ gdpPercap_1962: num 2551 4269 949 984 723 ... + $ gdpPercap_1967: num 3247 5523 1036 1215 795 ... + $ gdpPercap_1972: num 4183 5473 1086 2264 855 ... + $ gdpPercap_1977: num 4910 3009 1029 3215 743 ... + $ gdpPercap_1982: num 5745 2757 1278 4551 807 ... + $ gdpPercap_1987: num 5681 2430 1226 6206 912 ... + $ gdpPercap_1992: num 5023 2628 1191 7954 932 ... + $ gdpPercap_1997: num 4797 2277 1233 8647 946 ... + $ gdpPercap_2002: num 5288 2773 1373 11004 1038 ... + $ gdpPercap_2007: num 6223 4797 1441 12570 1217 ... + $ lifeExp_1952 : num 43.1 30 38.2 47.6 32 ... + $ lifeExp_1957 : num 45.7 32 40.4 49.6 34.9 ... + $ lifeExp_1962 : num 48.3 34 42.6 51.5 37.8 ... + $ lifeExp_1967 : num 51.4 36 44.9 53.3 40.7 ... + $ lifeExp_1972 : num 54.5 37.9 47 56 43.6 ... + $ lifeExp_1977 : num 58 39.5 49.2 59.3 46.1 ... + $ lifeExp_1982 : num 61.4 39.9 50.9 61.5 48.1 ... + $ lifeExp_1987 : num 65.8 39.9 52.3 63.6 49.6 ... + $ lifeExp_1992 : num 67.7 40.6 53.9 62.7 50.3 ... + $ lifeExp_1997 : num 69.2 41 54.8 52.6 50.3 ... + $ lifeExp_2002 : num 71 41 54.4 46.6 50.6 ... + $ lifeExp_2007 : num 72.3 42.7 56.7 50.7 52.3 ... + $ pop_1952 : num 9279525 4232095 1738315 442308 4469979 ... + $ pop_1957 : num 10270856 4561361 1925173 474639 4713416 ... + $ pop_1962 : num 11000948 4826015 2151895 512764 4919632 ... + $ pop_1967 : num 12760499 5247469 2427334 553541 5127935 ... + $ pop_1972 : num 14760787 5894858 2761407 619351 5433886 ... + $ pop_1977 : num 17152804 6162675 3168267 781472 5889574 ... + $ pop_1982 : num 20033753 7016384 3641603 970347 6634596 ... + $ pop_1987 : num 23254956 7874230 4243788 1151184 7586551 ... + $ pop_1992 : num 26298373 8735988 4981671 1342614 8878303 ... + $ pop_1997 : num 29072015 9875024 6066080 1536536 10352843 ... + $ pop_2002 : num 31287142 10866106 7026113 1630347 12251209 ... + $ pop_2007 : num 33333216 12420476 8078314 1639131 14326203 ... +``` + +¡Muy bien hiciste el cambio de formato de ida y vuelta! + +## Otros recursos geniales + +- [R para Ciencia de datos] (r4ds.had.co.nz) +- [Hoja de trucos para la conversión de datos] ([https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf](https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf)) +- [Introducción a tidyr] ([https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html](https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html)) +- [Manipulación de datos con R y RStudio] ([https://www.rstudio.com/resources/webinars/data-wrangling-with-r-and-rstudio/](https://www.rstudio.com/resources/webinars/data-wrangling-with-r-and-rstudio/)) + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Usar el paquete `tidyr` para cambiar el diseño de los data frames. +- Usar `gather()` para invertir del formato ancho al formato largo. +- Usar `spread()` para invertir del formato largo al formato ancho. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/15-knitr-markdown.md b/15-knitr-markdown.md new file mode 100644 index 00000000..fd77b69e --- /dev/null +++ b/15-knitr-markdown.md @@ -0,0 +1,381 @@ +--- +title: Produciendo informes con knitr +teaching: 60 +exercises: 15 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Valor de informes reproducibles +- Conceptos básicos de **Markdown** +- Fragmentos de código en **R** +- Opciones de fragmentos +- Código **R** en línea +- Otros formatos de salida + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo integrar programas e informes? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + + +## Informes de análisis de datos + +Los analistas de datos tienden a escribir muchos informes, describiendo sus +análisis y resultados, para sus colaboradores o para documentar su +trabajo para referencia futura. + +Es común que muchos nuevos usuarios comiencen escribiendo una rutina **R** con todos sus +trabajos. Luego simplemente envien el análisis por un correo electrónico a su colaborador, describiendo los resultados y adjuntando el **script** y varios gráficos. Éste método puede ser problemático, ya que al discutir los resultados, +a menudo hay confusión sobre qué gráfico corresponde a cuál resultado. + +Escribir informes formales, con **Word** o **LaTeX**, puede simplificar esto, al incorporar el análisis y los resultados a un documento único. Pero arreglando el formato del documento para hacer que las figuras se vean bien y corregir saltos de página rebeldes puede ser tedioso y llevar mucho tiempo. + +Crear una página **web** (como un +archivo **html**) usando **R markdown** hace que el todo sea mas sencillo. El reporte puede ser muy largo, así que figuras altas que +no cabrían normalmente en una página, pueden incluirse en tamaño original, ya que el lector las puede ver simplemente desplazando la página. Dar formato es simple y fácil de modificar, por lo que podemos dedicar más tiempo a nuestros análisis y no a la redacción de informes. + +## Programación literaria + +Idealmente, dichos informes de análisis son documentos *reproducibles*: Si +se descubre un error, o si se agregan algunos temas adicionales a los +datos, puedes volver a compilar el informe y obtener los resultados, nuevo o corregido +(en lugar de tener que reconstruir figuras, pegarlas en +un documento de **Word** y luego editar manualmente varios resultados detallados). + +La herramienta clave para *R* es [knitr](https://yihui.name/knitr/), que te permite +crear un documento que es una mezcla de texto y algunos fragmentos de +código. Cuando el documento es procesado por **knitr**, los fragmentos del código **R** +serán ejecutados, y los gráficos u otros resultados serán insertados. + +Este tipo de idea ha sido llamado "programación literaria". + +**knitr** te permite mezclar básicamente cualquier tipo de texto con cualquier tipo de +código, pero te recomendamos que uses **R Markdown**, que mezcla **Markdown** +con **R**. **Markdown** es un ligero lenguaje de marcado para crear +páginas **web** y también otros formatos. + +## Creando un archivo **R Markdown** + +Dentro de **R Studio**, haz clic en Archivo; Nuevo archivo; **R Markdown** y +obtendrás un cuadro de diálogo parecido a éste: + +![](fig/New_R_Markdown.png) + +Puedes mantener el valor predeterminado (salida **HTML**), pero dale un título. + +## Componentes básicos de **R Markdown** + +El fragmento inicial de texto contiene instrucciones para **R**: le das +un título, autor y fecha, y díle que va a querer +producir una salida **html** (en otras palabras, una página **web**). + +``` +--- +title: "Documento inicial **R Markdown**" +author: "Karl Broman" +date: "23 de Abril de 2015" +output: html_document +--- +``` + +Puedes eliminar cualquiera de esos campos si no los quieres +incluidos. Las comillas dobles no son estrictamente *necesarias* en este caso. +Pero en su mayoría son necesarias si deseas incluir dos puntos en el título. + +**RStudio** crea el documento con un texto de ejemplo para ayudarte +a empezar. Observa a continuación que hay fragmentos como + +
+```{r}
+summary(cars)
+```
+
+ +Estos son fragmentos de código **R** que serán ejecutados por **knitr** y reemplazados +por sus resultados. Más sobre esto más tarde. + +También fíjate en la dirección **web** que se coloca entre corchetes angulares (`<>`) así +como los asteriscos dobles en `**Knit**`. Esto es +[Markdown](https://daringfireball.net/projects/markdown/syntax). + +## **Markdown** + +**Markdown** es un sistema para escribir páginas **web** marcando el texto tanto +como lo haría en un correo electrónico en lugar de escribir código **html**. El texto marcado +es *convertido* a **html**, reemplazando las marcas con el +código **HTML**. + +Por ahora, borremos todas las cosas que están ahí y escribamos un poco de +**markdown**. + +Haces las cosas en **negrita** usando dos asteriscos, como esto: `** negrita **`, +y haces cosas *italicas* usando guiones bajos, como esto: +`_italics_`. + +Puedes hacer una lista con viñetas escribiendo una lista con guiones o +asteriscos, como esta: + +``` +* negrita con doble asterisco +* itálica con guiones bajos +* tipografía estilo código fuente con acento inverso/grave +``` + +o así: + +``` +- negrita con doble asterisco +- itálica con guiones bajos +- tipografía estilo código fuente con acento inverso/grave +``` + +Cada uno aparecerá como: + +- negrita con doble asterisco +- itálica con guiones bajos +- tipografía estilo código fuente con acento inverso/grave + +Puedes usar el método que prefieras (guiones o asteriscos), pero *se consistente*. Esto mantiene la +legibilidad del código. + +Puedes hacer una lista numerada simplemente usando números. Puedes incluso usar el +mismo número una y otra vez si lo deseas: + +``` +1. negrita con doble asterisco +1. itálica con guiones bajos +1. tipografía estilo código fuente con acento inverso/grave +``` + +Esto aparecerá como: + +1. negrita con doble asterisco +2. itálica con guiones bajos +3. tipografía estilo código fuente con acento inverso/grave + +Puedes crear encabezados de sección de diferentes tamaños iniciando una línea +con un cierto número de símbolos `#`: + +``` +# Título +## Sección principal +### Subsección +#### Sub-subsección +``` + +Tú *compilas* el documento **R Markdown** a una página **web** **html** haciendo clic +en el **"Knit HTML"** en la esquina superior izquierda. Y ten en cuenta el pequeño signo de interrogación +junto a él; haz clic en el signo de interrogación y obtendrá un **"Markdown Quick +Reference"** (con la sintaxis **Markdown**) así como para la +documentación de **RStudio** en **R Markdown**. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío + +Crea un nuevo documento **R Markdown**. Elimina todos los fragmentos de código **R** +y escribe un poco de **Markdown** (algunas secciones, algunos +textos en itálica, y una lista de ítemes). + +Convierte el documento a una página **web**. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Un poco más de **Markdown** + +Puedes hacer un hipervínculo como éste: +`[text to show](http://the-web-page.com)`. + +Puedes incluir un archivo de imagen como éste: `![caption](http://url/for/file)` + +Puedes hacer subíndices (por ejemplo, F~~2~~) con `F~2` y superíndices (p. +F^2^) con `F^2^`. + +Si sabes cómo escribir ecuaciones en +[LaTeX] ([http://www.latex-project.org/](https://www.latex-project.org/)), te alegrará saber que +puedes usar `$ $` y `$$ $$` para insertar ecuaciones matemáticas, como +`$E = mc^2$` y + +``` +$$y = \mu + \sum_{i=1}^p \beta_i x_i + \epsilon$$ +``` + +## Fragmentos de código **R** + +**Markdown** es interesante y útil, pero el poder real proviene de +la mezcla entre **markdown** y fragmentos de código **R**. Esto es **R Markdown**. Cuando +procesado, el código **R** se ejecutará; si producen figuras, +las figuras se insertarán en el documento final. + +Los fragmentos del código principal se ven así: + +
+```{r load_data}
+gapminder <- read.csv("~/Desktop/gapminder.csv")
+```
+
+ +Es decir, coloca un fragmento de código **R** entre \`\`\`{r chunk\_name} +y \`\`\`. Es una buena idea darle a cada fragmento +un nombre, ya que te ayudarán a corregir los errores y, si alugnos gráficos son +producidos, los nombres de archivo estarán basados en el nombre del fragmento de código que +los produjo. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío + +Agrega fragmentos de código para + +- Cargar el paquete **ggplot2** +- Leer los datos del **gapminder** +- Crear un gráfico + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Cómo se compilan las cosas + +Cuando presionas el botón **"Knit HTML"**, el documento **R Markdown** es +procesado por [knitr](https://yihui.name/knitr) y un documento **Markdown** simple +es producido (así como, potencialmente, un conjunto de archivos de figuras): el código **R** es ejecutado +y reemplazado por ambas la entrada y la salida; si las figuras son +producidas, se incluyen enlaces a esas figuras. + +Los documentos **Markdown** y figura son entones procesados por la herramienta +[pandoc](https://pandoc.org/), que convierte el archivo **Markdown** en un +archivo **html**, con las figuras embebidas. + + + +## Opciones de fragmento + +Hay una variedad de opciones quen afectan la forma en que los fragmentos de código son +tratado + +- Usa `echo=FALSE` para evitar que se muestre el código en sí. +- Usa `results="hide"` para evitar que se impriman los resultados. +- Usa `eval=FALSE` para tener el código mostrado pero no evaluado. +- Usa `warning=FALSE` y `message=FALSE` para ocultar cualquier advertencia o +    mensajes producidos +- Usa `fig.height` y `fig.width` para controlar el tamaño de las figuras +    producidas (en pulgadas). + +Entonces podrías escribir: + +
+```{r load_libraries, echo=FALSE, message=FALSE}
+library("dplyr")
+library("ggplot2")
+```
+
+ +A menudo habrá opciones particulares que querrás usar +repetidamente; para esto, puede establecer las opciones de fragnento *global*, de esta forma: + +
+```{r global_options, echo=FALSE}
+knitr::opts_chunk$set(fig.path="Figs/", message=FALSE, warning=FALSE,
+                      echo=FALSE, results="hide", fig.width=11)
+```
+
+ +La opción `fig.path` define dónde se guardarán las figuras. El `/` +aquí es realmente importante; sin él, las figuras se guardarían en +el lugar estándar, pero solo con los nombres que están con `Figs`. + +Si tienes varios archivos **R Markdown** en un directorio común, es posible que +quieras usar `fig.path` para definir prefijos separados para los nombres de archivo de figura +, como `fig.path="Figs/cleaning-"` y `fig.path="Figs/analysis-"`. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío + +Usa las opciones de fragmentos para controlar el tamaño de una figura y ocultar el +código. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Código **R** en línea + +Puedes hacer cada número de tu informe reproducible. Usa +\`r y \` para un fragmento de código en línea, +al igual que: ``` `r round(some_value, 2)` ```. El código será +ejecutado y reemplazado con el *valor* del resultado. + +No dejes que estos fragmentos en línea se dividan en líneas. + +Tal vez anteceda el párrafo con un fragmento de código más grande que hace +cálculos y define cosas, con `include=FALSE` para ese largo +fragmento (que es lo mismo que `echo=FALSE` y `results="hide"`). + +Redondear puede generar diferencias en el resultado en tales situaciones. Es posible que desees +`2.0`, pero`round (2.03, 1)`resultará solo` 2`. + +La función +[`myround`](https://github.com/kbroman/broman/blob/master/R/myround.R) +en el paquete [R/broman](https://github.com/kbroman) maneja +esi. + +::::::::::::::::::::::::::::::::::::::: challenge + +## Desafío + +Prueba un poco de código **R** en línea. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Otras opciones de salida + +También puedes convertir **R Markdown** en un documento **PDF** o **Word**. Haz clic en el +pequeño triángulo junto al botón **"Knit HTML"** para obtener un menú desplegable. +O podrías poner **`pdf_document`** o **` word_document`** en el encabezado +del archivo. + +::::::::::::::::::::::::::::::::::::::::: callout + +## Sugerencia: Creación de documentos **PDF** + +La creación de documentos **.pdf** puede requerir la instalación de algún programa adicional. Si +eso es requerido, se detalla en un mensaje de error. + +**Tex** para **Windows** está disponible [aquí](https://miktex.org/2.9/setup). + +**Tex** for **mac** está disponible [aquí](https://tug.org/mactex). + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Recursos + +- [Knitr in a knutshell tutorial](https://kbroman.org/knitr_knutshell) +- [Dynamic Documents with R and knitr](https://www.amazon.com/exec/obidos/ASIN/1482203537/7210-20) (book) +- [R Markdown documentation](https://rmarkdown.rstudio.com) +- [R Markdown cheat sheet](https://www.rstudio.com/wp-content/uploads/2015/02/rmarkdown-cheatsheet.pdf) + +- [Getting started with R Markdown](https://www.rstudio.com/resources/webinars/getting-started-with-r-markdown/) +- [Reproducible Reporting](https://www.rstudio.com/resources/webinars/reproducible-reporting/) +- [The Ecosystem of R Markdown](https://www.rstudio.com/resources/webinars/the-ecosystem-of-r-markdown/) +- [Introducing Bookdown](https://www.rstudio.com/resources/webinars/introducing-bookdown/) + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Informes mixtos escritos en **R Markdown** usando un programa escrito en **R**. +- Especificar opciones de fragmento para controlar el formateo. +- Usar `knitr` para convertir estos documentos en PDF y en otros formatos. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/16-wrap-up.md b/16-wrap-up.md new file mode 100644 index 00000000..8978f6aa --- /dev/null +++ b/16-wrap-up.md @@ -0,0 +1,74 @@ +--- +title: Escribiendo buen software +teaching: 15 +exercises: 0 +source: Rmd +--- + +::::::::::::::::::::::::::::::::::::::: objectives + +- Describir las mejores prácticas para escribir software en R y explicar la justificación de cada una. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +:::::::::::::::::::::::::::::::::::::::: questions + +- ¿Cómo puedo escribir software que otras personas puedan usar? + +:::::::::::::::::::::::::::::::::::::::::::::::::: + +## Escribir código legible + +La parte más importante de escribir código es hacer que sea legible y comprensible. +Quieres que otra persona pueda tener tu código y comprenda lo que hace: la mayoría de las veces, esta persona +serás tú 6 meses después y si no es comprensible, te estarás culpando por no haber hecho las cosas bien. + +## Documentación: dinos qué y por qué, no cómo + +Cuando empiezas a programar, tus comentarios a menudo describen lo que hace un comando, ya que aún te +encuentras en aprendizaje y pueden ayudarte a aclarar conceptos y recordártelos más tarde. Sin embargo, estos +comentarios no son particularmente útiles, sobre todo cuando no recuerdes qué problema estabas tratando de +resolver con tu código. Intenta incluir comentarios que te digan *por qué* estás resolviendo un problema +y *qué* problema es. El *cómo* puede venir después de eso: es un detalle de implementación del que +idealmente no deberías preocuparte. + +## Mantén tu código modular + +Nuestra recomendación es que debes separar tus funciones de tus **scripts** y +almacenarlos en un archivo separado 'source' que llamarás cuando abras la sesión R en tu proyecto. Este enfoque es bueno porque te deja un **script** ordenado y un repositorio de funciones útiles que se pueden cargar en +cualquier script en tu proyecto. También te permite agrupar funciones relacionadas fácilmente. + +## Divide el problema en bocados pequeños + +Al principio la resolución de problemas y la escritura de funciones pueden ser tareas que te resulten +desalentadoras debido a la falta de experiencia en programación. Trata de dividir tu problema en bloques digeribles y preocúpate por los detalles de la implementación más adelante. Es recomendable seguir dividiendo el problema en +funciones cortas de un solo propósito. + +## Chequea que tu código está haciendo lo correcto + +¡Asegúrate de probar tus funciones! + +## No repitas tu código + +Las funciones permiten una fácil reutilización dentro de en proyecto. Si identificas bloques de código similares en tu proyecto son en general candidatos a ser convertidos en funciones. + +Si tus cálculos se realizan a través de una serie de funciones, entonces +el proyecto se vuelve más modular y más fácil de cambiar. Este es, especialmente el caso para el cual una entrada particular siempre da una salida particular. + +## Recuerda ser elegante + +Manten un mismo estilo en todo tu código. + + + +:::::::::::::::::::::::::::::::::::::::: keypoints + +- Documenta qué y por qué, no cómo. +- Divide los programas en funciones cortas de un solo propósito. +- Escribe pruebas re-ejecutables. +- No repitas tu código. +- Se coherente en la nomenclatura, indentación y otros aspectos del estilo. + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..f19b8049 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,13 @@ +--- +title: "Contributor Code of Conduct" +--- + +As contributors and maintainers of this project, +we pledge to follow the [The Carpentries Code of Conduct][coc]. + +Instances of abusive, harassing, or otherwise unacceptable behavior +may be reported by following our [reporting guidelines][coc-reporting]. + + +[coc-reporting]: https://docs.carpentries.org/topic_folders/policies/incident-reporting.html +[coc]: https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..7632871f --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,79 @@ +--- +title: "Licenses" +--- + +## Instructional Material + +All Carpentries (Software Carpentry, Data Carpentry, and Library Carpentry) +instructional material is made available under the [Creative Commons +Attribution license][cc-by-human]. The following is a human-readable summary of +(and not a substitute for) the [full legal text of the CC BY 4.0 +license][cc-by-legal]. + +You are free: + +- to **Share**---copy and redistribute the material in any medium or format +- to **Adapt**---remix, transform, and build upon the material + +for any purpose, even commercially. + +The licensor cannot revoke these freedoms as long as you follow the license +terms. + +Under the following terms: + +- **Attribution**---You must give appropriate credit (mentioning that your work + is derived from work that is Copyright (c) The Carpentries and, where + practical, linking to ), provide a [link to the + license][cc-by-human], and indicate if changes were made. You may do so in + any reasonable manner, but not in any way that suggests the licensor endorses + you or your use. + +- **No additional restrictions**---You may not apply legal terms or + technological measures that legally restrict others from doing anything the + license permits. With the understanding that: + +Notices: + +* You do not have to comply with the license for elements of the material in + the public domain or where your use is permitted by an applicable exception + or limitation. +* No warranties are given. The license may not give you all of the permissions + necessary for your intended use. For example, other rights such as publicity, + privacy, or moral rights may limit how you use the material. + +## Software + +Except where otherwise noted, the example programs and other software provided +by The Carpentries are made available under the [OSI][osi]-approved [MIT +license][mit-license]. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +## Trademark + +"The Carpentries", "Software Carpentry", "Data Carpentry", and "Library +Carpentry" and their respective logos are registered trademarks of [Community +Initiatives][ci]. + +[cc-by-human]: https://creativecommons.org/licenses/by/4.0/ +[cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode +[mit-license]: https://opensource.org/licenses/mit-license.html +[ci]: https://communityin.org/ +[osi]: https://opensource.org diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 00000000..4d1ecd80 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,17 @@ +# Notas de lanzamiento + +## Versión inicial + +- [May 2018] https://github.com/swcarpentry/r-novice-gapminder-es + +## Archivo de prelanzamiento + +- [March 2018](https://github.com/Carpentries-ES/r-novice-gapminder) + +## Lanzamientos de lecciones de inglés anteriores + +R for Reproducible Scientific Analysis +- [Corriente](https://github.com/swcarpentry/r-novice-gapminder) +- [August 2017](https://zenodo.org/record/838770) +- [February 2017](https://zenodo.org/record/278224) +- [June 2016](https://zenodo.org/record/57520) diff --git a/config.yaml b/config.yaml new file mode 100644 index 00000000..a14156dd --- /dev/null +++ b/config.yaml @@ -0,0 +1,96 @@ +#------------------------------------------------------------ +# Values for this lesson. +#------------------------------------------------------------ + +# Which carpentry is this (swc, dc, lc, or cp)? +# swc: Software Carpentry +# dc: Data Carpentry +# lc: Library Carpentry +# cp: Carpentries (to use for instructor training for instance) +# incubator: The Carpentries Incubator +carpentry: 'swc' + +# Overall title for pages. +title: 'R para Análisis Científicos Reproducibles' + +# Date the lesson was created (YYYY-MM-DD, this is empty by default) +created: '2018-03-20' + +# Comma-separated list of keywords for the lesson +keywords: 'software, data, lesson, The Carpentries' + +# Life cycle stage of the lesson +# possible values: pre-alpha, alpha, beta, stable +life_cycle: 'stable' + +# License of the lesson materials (recommended CC-BY 4.0) +license: 'CC-BY 4.0' + +# Link to the source repository for this lesson +source: 'https://github.com/swcarpentry/r-novice-gapminder-es' + +# Default branch of your lesson +branch: 'main' + +# Who to contact if there are any issues +contact: 'team@carpentries.org' + +# Navigation ------------------------------------------------ +# +# Use the following menu items to specify the order of +# individual pages in each dropdown section. Leave blank to +# include all pages in the folder. +# +# Example ------------- +# +# episodes: +# - introduction.md +# - first-steps.md +# +# learners: +# - setup.md +# +# instructors: +# - instructor-notes.md +# +# profiles: +# - one-learner.md +# - another-learner.md + +# Order of episodes in your lesson +episodes: +- 01-rstudio-intro.Rmd +- 02-project-intro.Rmd +- 03-seeking-help.Rmd +- 04-data-structures-part1.Rmd +- 05-data-structures-part2.Rmd +- 06-data-subsetting.Rmd +- 07-control-flow.Rmd +- 08-plot-ggplot2.Rmd +- 09-vectorization.Rmd +- 10-functions.Rmd +- 11-writing-data.Rmd +- 12-plyr.Rmd +- 13-dplyr.Rmd +- 14-tidyr.Rmd +- 15-knitr-markdown.Rmd +- 16-wrap-up.Rmd + +# Information for Learners +learners: + +# Information for Instructors +instructors: + +# Learner Profiles +profiles: + +# Customisation --------------------------------------------- +# +# This space below is where custom yaml items (e.g. pinning +# sandpaper and varnish versions) should live + + +url: 'https://swcarpentry.github.io/r-novice-gapminder-es' +analytics: carpentries +lang: 'es' diff --git a/data/Owls.txt b/data/Owls.txt new file mode 100644 index 00000000..490a16ee --- /dev/null +++ b/data/Owls.txt @@ -0,0 +1,600 @@ +Nest FoodTreatment SexParent ArrivalTime SiblingNegotiation BroodSize NegPerChick +AutavauxTV Deprived Male 22.25 4 5 0.8 +AutavauxTV Satiated Male 22.38 0 5 0 +AutavauxTV Deprived Male 22.53 2 5 0.4 +AutavauxTV Deprived Male 22.56 2 5 0.4 +AutavauxTV Deprived Male 22.61 2 5 0.4 +AutavauxTV Deprived Male 22.65 2 5 0.4 +AutavauxTV Deprived Male 22.76 18 5 3.6 +AutavauxTV Satiated Female 22.9 4 5 0.8 +AutavauxTV Deprived Male 22.98 18 5 3.6 +AutavauxTV Satiated Female 23.07 0 5 0 +AutavauxTV Satiated Female 23.18 0 5 0 +AutavauxTV Deprived Female 23.28 3 5 0.6 +AutavauxTV Satiated Male 23.38 0 5 0 +AutavauxTV Deprived Male 23.43 3 5 0.6 +AutavauxTV Deprived Female 23.45 3 5 0.6 +AutavauxTV Deprived Male 23.68 6 5 1.2 +AutavauxTV Deprived Female 24 0 5 0 +AutavauxTV Satiated Male 24.21 4 5 0.8 +AutavauxTV Deprived Male 24.25 0 5 0 +AutavauxTV Deprived Male 24.58 7 5 1.4 +AutavauxTV Deprived Male 24.65 7 5 1.4 +AutavauxTV Satiated Male 24.95 0 5 0 +AutavauxTV Satiated Female 25.25 16 5 3.2 +AutavauxTV Satiated Male 25.75 7 5 1.4 +AutavauxTV Deprived Male 27.71 0 5 0 +AutavauxTV Deprived Female 27.85 7 5 1.4 +AutavauxTV Deprived Female 28.02 16 5 3.2 +AutavauxTV Deprived Male 28.82 5 5 1 +Bochet Satiated Female 22.81 3 4 0.75 +Bochet Satiated Male 23.2 2 4 0.5 +Bochet Deprived Male 23.22 13 4 3.25 +Bochet Deprived Female 23.23 13 4 3.25 +Bochet Deprived Male 23.33 22 4 5.5 +Bochet Satiated Male 23.36 2 4 0.5 +Bochet Satiated Female 23.4 2 4 0.5 +Bochet Satiated Male 23.45 2 4 0.5 +Bochet Deprived Male 23.46 22 4 5.5 +Bochet Deprived Female 23.5 12 4 3 +Bochet Satiated Female 23.51 0 4 0 +Bochet Deprived Female 23.53 12 4 3 +Bochet Deprived Male 23.78 12 4 3 +Bochet Satiated Male 23.88 0 4 0 +Bochet Satiated Female 23.95 0 4 0 +Bochet Satiated Female 24.35 0 4 0 +Bochet Satiated Female 24.45 0 4 0 +Bochet Deprived Male 26.3 0 4 0 +Bochet Deprived Male 26.43 0 4 0 +Bochet Satiated Male 27.1 0 4 0 +Bochet Satiated Male 27.33 0 4 0 +Bochet Deprived Male 27.55 0 4 0 +Bochet Satiated Male 27.98 0 4 0 +Champmartin Deprived Female 22.08 3 3 1 +Champmartin Deprived Female 22.36 0 3 0 +Champmartin Satiated Female 22.46 0 3 0 +Champmartin Deprived Female 22.62 10 3 3.33333333 +Champmartin Deprived Female 22.83 18 3 6 +Champmartin Deprived Female 22.98 18 3 6 +Champmartin Deprived Female 23.1 0 3 0 +Champmartin Deprived Female 23.15 0 3 0 +Champmartin Deprived Female 23.56 2 3 0.66666667 +Champmartin Deprived Female 23.73 2 3 0.66666667 +Champmartin Deprived Female 23.95 4 3 1.33333333 +Champmartin Satiated Female 24.1 0 3 0 +Champmartin Satiated Female 24.21 0 3 0 +Champmartin Deprived Female 24.53 3 3 1 +Champmartin Deprived Female 24.78 7 3 2.33333333 +Champmartin Deprived Female 24.93 7 3 2.33333333 +Champmartin Deprived Female 25.03 13 3 4.33333333 +Champmartin Deprived Female 25.28 16 3 5.33333333 +Champmartin Deprived Female 25.63 14 3 4.66666667 +Champmartin Satiated Female 25.71 0 3 0 +Champmartin Deprived Female 25.82 0 3 0 +Champmartin Deprived Female 26.6 0 3 0 +Champmartin Satiated Female 27.28 0 3 0 +Champmartin Satiated Female 27.4 0 3 0 +Champmartin Satiated Female 27.5 0 3 0 +Champmartin Deprived Female 27.66 0 3 0 +Champmartin Satiated Female 27.66 0 3 0 +Champmartin Satiated Female 27.91 0 3 0 +Champmartin Deprived Female 28.58 1 3 0.33333333 +Champmartin Deprived Female 29.23 3 3 1 +ChEsard Deprived Male 22.36 23 4 5.75 +ChEsard Deprived Male 22.55 19 4 4.75 +ChEsard Deprived Male 22.66 19 4 4.75 +ChEsard Deprived Male 23.13 14 4 3.5 +ChEsard Deprived Female 23.26 18 4 4.5 +ChEsard Deprived Male 23.33 18 4 4.5 +ChEsard Deprived Male 23.58 14 4 3.5 +ChEsard Deprived Male 23.68 14 4 3.5 +ChEsard Deprived Male 23.82 6 4 1.5 +ChEsard Deprived Male 23.93 6 4 1.5 +ChEsard Deprived Male 24.63 12 4 3 +ChEsard Deprived Female 24.66 12 4 3 +ChEsard Deprived Male 24.88 12 4 3 +ChEsard Satiated Female 25.38 19 4 4.75 +ChEsard Deprived Male 25.5 0 4 0 +ChEsard Deprived Male 25.95 17 4 4.25 +ChEsard Deprived Male 26.65 3 4 0.75 +ChEsard Deprived Male 26.85 11 4 2.75 +ChEsard Deprived Male 27.06 2 4 0.5 +ChEsard Satiated Male 27.66 6 4 1.5 +Chevroux Satiated Male 22.35 0 2 0 +Chevroux Satiated Male 23.2 0 2 0 +Chevroux Satiated Female 23.88 0 2 0 +Chevroux Satiated Male 24.01 0 2 0 +Chevroux Satiated Male 24.76 0 2 0 +Chevroux Deprived Male 25.31 17 2 8.5 +Chevroux Satiated Male 25.98 0 2 0 +Chevroux Deprived Male 26.05 5 2 2.5 +Chevroux Deprived Male 27.53 5 2 2.5 +Chevroux Deprived Male 28.31 7 2 3.5 +CorcellesFavres Satiated Male 22.76 2 3 0.66666667 +CorcellesFavres Satiated Male 24.11 9 3 3 +CorcellesFavres Deprived Female 25.15 7 3 2.33333333 +CorcellesFavres Satiated Female 25.38 2 3 0.66666667 +CorcellesFavres Satiated Male 25.63 4 3 1.33333333 +CorcellesFavres Satiated Male 26.03 9 3 3 +CorcellesFavres Satiated Male 26.3 5 3 1.66666667 +CorcellesFavres Satiated Male 26.73 6 3 2 +CorcellesFavres Satiated Male 28.43 3 3 1 +CorcellesFavres Satiated Male 28.86 7 3 2.33333333 +CorcellesFavres Deprived Female 28.98 5 3 1.66666667 +CorcellesFavres Satiated Male 29.11 20 3 6.66666667 +Etrabloz Deprived Male 22.01 4 5 0.8 +Etrabloz Deprived Female 22.15 4 5 0.8 +Etrabloz Deprived Male 22.26 14 5 2.8 +Etrabloz Satiated Female 22.46 0 5 0 +Etrabloz Satiated Female 22.51 0 5 0 +Etrabloz Deprived Female 22.7 9 5 1.8 +Etrabloz Deprived Male 22.85 14 5 2.8 +Etrabloz Deprived Male 23.13 6 5 1.2 +Etrabloz Satiated Male 23.3 2 5 0.4 +Etrabloz Deprived Male 23.31 8 5 1.6 +Etrabloz Deprived Female 23.7 2 5 0.4 +Etrabloz Satiated Male 23.73 0 5 0 +Etrabloz Deprived Male 23.76 5 5 1 +Etrabloz Deprived Female 23.81 5 5 1 +Etrabloz Satiated Male 24.05 0 5 0 +Etrabloz Satiated Female 24.38 0 5 0 +Etrabloz Satiated Female 24.43 0 5 0 +Etrabloz Satiated Female 24.58 0 5 0 +Etrabloz Deprived Female 24.65 0 5 0 +Etrabloz Satiated Female 25.05 0 5 0 +Etrabloz Satiated Female 25.61 0 5 0 +Etrabloz Deprived Female 25.61 1 5 0.2 +Etrabloz Satiated Male 26.28 0 5 0 +Etrabloz Deprived Female 26.33 5 5 1 +Etrabloz Deprived Female 26.48 5 5 1 +Etrabloz Deprived Female 26.85 1 5 0.2 +Etrabloz Deprived Female 27.5 10 5 2 +Etrabloz Deprived Male 27.55 8 5 1.6 +Etrabloz Satiated Female 28.26 2 5 0.4 +Etrabloz Deprived Male 28.35 10 5 2 +Etrabloz Deprived Male 28.7 2 5 0.4 +Etrabloz Deprived Male 28.81 13 5 2.6 +Etrabloz Deprived Male 28.9 13 5 2.6 +Etrabloz Deprived Male 29.25 13 5 2.6 +Forel Satiated Male 23.25 0 4 0 +Forel Deprived Male 23.92 1 4 0.25 +Forel Satiated Male 24.26 0 4 0 +Forel Satiated Male 24.3 0 4 0 +Franex Satiated Male 22.36 0 4 0 +Franex Satiated Male 22.45 0 4 0 +Franex Deprived Female 22.66 19 4 4.75 +Franex Deprived Male 22.68 19 4 4.75 +Franex Deprived Male 22.75 19 4 4.75 +Franex Deprived Female 22.76 8 4 2 +Franex Deprived Female 23.05 9 4 2.25 +Franex Deprived Male 23.48 1 4 0.25 +Franex Deprived Male 23.65 4 4 1 +Franex Deprived Male 23.8 3 4 0.75 +Franex Deprived Male 23.9 3 4 0.75 +Franex Deprived Male 24.05 6 4 1.5 +Franex Deprived Female 24.08 6 4 1.5 +Franex Deprived Male 24.25 6 4 1.5 +Franex Satiated Female 24.58 0 4 0 +Franex Satiated Female 24.68 0 4 0 +Franex Satiated Male 24.73 0 4 0 +Franex Satiated Male 25.11 3 4 0.75 +Franex Deprived Male 25.26 0 4 0 +Franex Deprived Male 26.36 4 4 1 +Franex Deprived Male 26.6 4 4 1 +Franex Deprived Male 26.71 4 4 1 +Franex Deprived Male 26.95 14 4 3.5 +Franex Satiated Male 27.1 5 4 1.25 +Franex Deprived Female 27.25 8 4 2 +Franex Deprived Male 27.38 16 4 4 +GDLV Deprived Male 22.46 6 5 1.2 +GDLV Deprived Female 22.83 9 5 1.8 +GDLV Satiated Male 22.91 1 5 0.2 +GDLV Deprived Male 23.08 11 5 2.2 +GDLV Deprived Male 23.75 11 5 2.2 +GDLV Deprived Male 23.91 12 5 2.4 +GDLV Deprived Male 25.26 12 5 2.4 +GDLV Satiated Male 25.56 2 5 0.4 +GDLV Deprived Female 26.85 9 5 1.8 +GDLV Satiated Male 28.78 0 5 0 +Gletterens Deprived Female 23.15 16 2 8 +Gletterens Deprived Female 23.25 16 2 8 +Gletterens Satiated Female 23.8 3 2 1.5 +Gletterens Deprived Female 24.05 0 2 0 +Gletterens Deprived Female 24.53 0 2 0 +Gletterens Deprived Male 24.55 0 2 0 +Gletterens Satiated Male 24.81 0 2 0 +Gletterens Deprived Female 24.85 5 2 2.5 +Gletterens Satiated Female 25.1 9 2 4.5 +Gletterens Deprived Female 25.8 10 2 5 +Gletterens Deprived Male 26.3 3 2 1.5 +Gletterens Deprived Male 27.23 0 2 0 +Gletterens Satiated Female 27.4 0 2 0 +Gletterens Deprived Male 27.61 0 2 0 +Gletterens Deprived Male 28.78 2 2 1 +Henniez Deprived Female 22.51 6 2 3 +Henniez Deprived Female 22.63 6 2 3 +Henniez Satiated Female 22.68 2 2 1 +Henniez Satiated Female 22.76 17 2 8.5 +Henniez Deprived Female 22.91 3 2 1.5 +Henniez Satiated Female 23.06 0 2 0 +Henniez Satiated Female 23.28 0 2 0 +Henniez Deprived Female 23.81 0 2 0 +Henniez Satiated Female 23.96 0 2 0 +Henniez Deprived Female 25.88 0 2 0 +Henniez Deprived Female 26.78 0 2 0 +Henniez Deprived Female 27.63 0 2 0 +Henniez Satiated Female 28.26 0 2 0 +Jeuss Satiated Male 22.66 3 5 0.6 +Jeuss Deprived Female 23.11 9 5 1.8 +Jeuss Satiated Male 23.16 0 5 0 +Jeuss Satiated Female 23.41 0 5 0 +Jeuss Deprived Male 25.58 12 5 2.4 +Jeuss Satiated Male 25.9 0 5 0 +Jeuss Deprived Male 25.93 2 5 0.4 +Jeuss Deprived Female 26.16 11 5 2.2 +Jeuss Deprived Male 26.33 5 5 1 +Jeuss Deprived Male 26.56 3 5 0.6 +Jeuss Satiated Female 26.6 0 5 0 +Jeuss Deprived Female 26.75 3 5 0.6 +Jeuss Deprived Male 26.83 3 5 0.6 +Jeuss Satiated Female 26.98 0 5 0 +Jeuss Satiated Male 27.48 0 5 0 +Jeuss Deprived Female 27.51 0 5 0 +Jeuss Satiated Female 28 0 5 0 +Jeuss Satiated Male 28.8 0 5 0 +Jeuss Deprived Male 28.98 2 5 0.4 +LesPlanches Satiated Male 21.78 0 3 0 +LesPlanches Satiated Male 21.81 0 3 0 +LesPlanches Deprived Male 22.3 3 3 1 +LesPlanches Satiated Male 22.31 0 3 0 +LesPlanches Satiated Male 22.51 10 3 3.33333333 +LesPlanches Deprived Male 22.63 10 3 3.33333333 +LesPlanches Deprived Male 23.06 10 3 3.33333333 +LesPlanches Satiated Male 23.38 0 3 0 +LesPlanches Satiated Male 23.41 0 3 0 +LesPlanches Satiated Male 23.68 11 3 3.66666667 +LesPlanches Deprived Male 24.03 0 3 0 +LesPlanches Satiated Male 24.43 0 3 0 +LesPlanches Deprived Male 26.55 0 3 0 +LesPlanches Deprived Female 26.76 0 3 0 +LesPlanches Deprived Male 27.45 0 3 0 +LesPlanches Deprived Male 27.6 11 3 3.66666667 +LesPlanches Deprived Male 28.26 6 3 2 +Lucens Satiated Male 22.36 9 4 2.25 +Lucens Deprived Female 22.38 23 4 5.75 +Lucens Deprived Male 22.68 15 4 3.75 +Lucens Satiated Male 22.76 2 4 0.5 +Lucens Deprived Male 22.81 12 4 3 +Lucens Deprived Male 22.9 12 4 3 +Lucens Deprived Male 22.98 12 4 3 +Lucens Satiated Female 23.03 0 4 0 +Lucens Deprived Female 23.38 0 4 0 +Lucens Deprived Female 23.45 0 4 0 +Lucens Deprived Female 23.51 14 4 3.5 +Lucens Deprived Male 23.56 14 4 3.5 +Lucens Deprived Female 23.6 14 4 3.5 +Lucens Deprived Male 24.25 2 4 0.5 +Lucens Satiated Male 25.05 13 4 3.25 +Lucens Deprived Female 25.1 0 4 0 +Lucens Deprived Female 25.36 1 4 0.25 +Lucens Satiated Male 26.2 0 4 0 +Lucens Deprived Male 26.5 4 4 1 +Lucens Deprived Female 26.61 8 4 2 +Lucens Deprived Male 26.81 1 4 0.25 +Lucens Satiated Male 26.85 0 4 0 +Lucens Deprived Male 27.08 4 4 1 +Lucens Satiated Female 27.16 0 4 0 +Lucens Deprived Female 27.53 5 4 1.25 +Lucens Deprived Female 28.03 8 4 2 +Lucens Satiated Female 28.13 9 4 2.25 +Lucens Satiated Male 28.26 7 4 1.75 +Lucens Deprived Male 28.4 7 4 1.75 +Lully Deprived Male 22.31 16 4 4 +Lully Deprived Female 22.51 13 4 3.25 +Lully Deprived Male 22.55 13 4 3.25 +Lully Deprived Male 22.98 15 4 3.75 +Lully Deprived Male 23.01 14 4 3.5 +Lully Deprived Male 23.15 14 4 3.5 +Lully Satiated Female 23.25 6 4 1.5 +Lully Deprived Female 23.63 15 4 3.75 +Lully Deprived Male 23.66 15 4 3.75 +Lully Satiated Male 23.7 6 4 1.5 +Lully Deprived Female 24.4 0 4 0 +Lully Satiated Male 24.85 1 4 0.25 +Lully Deprived Female 25.13 0 4 0 +Lully Satiated Male 26.78 9 4 2.25 +Lully Satiated Male 26.93 9 4 2.25 +Lully Satiated Male 27.31 3 4 0.75 +Lully Deprived Male 28.58 2 4 0.5 +Marnand Deprived Male 22.28 12 4 3 +Marnand Satiated Female 22.53 6 4 1.5 +Marnand Satiated Male 22.65 6 4 1.5 +Marnand Deprived Male 22.73 13 4 3.25 +Marnand Deprived Female 22.98 28 4 7 +Marnand Satiated Male 23.35 0 4 0 +Marnand Deprived Female 23.4 6 4 1.5 +Marnand Deprived Male 23.86 0 4 0 +Marnand Satiated Male 24.23 3 4 0.75 +Marnand Satiated Female 24.31 2 4 0.5 +Marnand Deprived Male 24.41 4 4 1 +Marnand Deprived Female 24.48 4 4 1 +Marnand Satiated Female 24.58 8 4 2 +Marnand Satiated Male 24.63 8 4 2 +Marnand Deprived Female 25.13 13 4 3.25 +Marnand Deprived Male 25.53 7 4 1.75 +Marnand Deprived Male 25.58 4 4 1 +Marnand Satiated Female 25.63 0 4 0 +Marnand Satiated Female 25.68 0 4 0 +Marnand Satiated Male 25.86 12 4 3 +Marnand Deprived Male 25.96 4 4 1 +Marnand Deprived Male 26.06 17 4 4.25 +Marnand Satiated Male 26.38 7 4 1.75 +Marnand Deprived Male 26.53 5 4 1.25 +Marnand Satiated Male 26.76 1 4 0.25 +Marnand Deprived Male 27.38 0 4 0 +Marnand Deprived Male 27.46 0 4 0 +Montet Satiated Male 22.7 6 5 1.2 +Montet Deprived Male 22.95 15 5 3 +Montet Deprived Male 23.11 17 5 3.4 +Montet Deprived Male 23.33 10 5 2 +Montet Satiated Female 23.55 2 5 0.4 +Montet Deprived Male 23.6 15 5 3 +Montet Satiated Male 23.63 2 5 0.4 +Montet Deprived Male 23.81 10 5 2 +Montet Satiated Male 24.05 0 5 0 +Montet Deprived Male 24.06 7 5 1.4 +Montet Deprived Male 24.08 7 5 1.4 +Montet Deprived Male 24.2 7 5 1.4 +Montet Deprived Male 24.3 15 5 3 +Montet Satiated Male 24.35 5 5 1 +Montet Satiated Male 24.43 5 5 1 +Montet Deprived Male 24.48 15 5 3 +Montet Deprived Male 24.61 19 5 3.8 +Montet Satiated Male 24.66 0 5 0 +Montet Deprived Male 24.7 19 5 3.8 +Montet Satiated Male 24.81 12 5 2.4 +Montet Deprived Male 24.85 10 5 2 +Montet Satiated Male 24.9 12 5 2.4 +Montet Deprived Male 24.96 10 5 2 +Montet Deprived Male 25.03 20 5 4 +Montet Deprived Male 25.1 20 5 4 +Montet Satiated Female 25.36 7 5 1.4 +Montet Satiated Male 25.38 7 5 1.4 +Montet Satiated Male 25.55 22 5 4.4 +Montet Satiated Male 25.73 22 5 4.4 +Montet Deprived Male 25.9 4 5 0.8 +Montet Deprived Female 26.55 14 5 2.8 +Montet Deprived Male 26.83 4 5 0.8 +Montet Satiated Female 26.91 0 5 0 +Montet Satiated Male 26.93 0 5 0 +Montet Deprived Male 27.23 2 5 0.4 +Montet Deprived Male 27.43 0 5 0 +Montet Deprived Male 27.56 12 5 2.4 +Montet Deprived Male 27.83 4 5 0.8 +Montet Satiated Female 28.3 2 5 0.4 +Montet Satiated Male 28.38 2 5 0.4 +Montet Satiated Female 28.86 1 5 0.2 +Murist Deprived Female 22.23 3 4 0.75 +Murist Satiated Female 22.26 24 4 6 +Murist Deprived Male 22.5 24 4 6 +Murist Deprived Male 22.51 14 4 3.5 +Murist Deprived Male 22.58 14 4 3.5 +Murist Satiated Male 22.6 14 4 3.5 +Murist Deprived Male 22.61 14 4 3.5 +Murist Deprived Female 22.63 14 4 3.5 +Murist Deprived Male 22.66 14 4 3.5 +Murist Satiated Male 22.78 14 4 3.5 +Murist Satiated Male 22.86 14 4 3.5 +Murist Satiated Female 22.93 14 4 3.5 +Murist Deprived Male 23.1 0 4 0 +Murist Satiated Male 23.4 0 4 0 +Murist Deprived Female 23.78 0 4 0 +Murist Deprived Female 23.8 0 4 0 +Murist Satiated Male 25.7 3 4 0.75 +Murist Satiated Male 25.83 0 4 0 +Murist Deprived Male 26.23 6 4 1.5 +Murist Satiated Male 26.41 17 4 4.25 +Murist Deprived Male 27.25 5 4 1.25 +Murist Satiated Male 27.53 0 4 0 +Murist Satiated Male 27.73 0 4 0 +Murist Deprived Male 27.96 3 4 0.75 +Oleyes Satiated Female 21.76 11 5 2.2 +Oleyes Satiated Female 22.13 17 5 3.4 +Oleyes Satiated Female 22.28 17 5 3.4 +Oleyes Deprived Female 22.38 2 5 0.4 +Oleyes Satiated Male 22.4 12 5 2.4 +Oleyes Satiated Female 22.61 12 5 2.4 +Oleyes Satiated Male 22.73 13 5 2.6 +Oleyes Satiated Female 22.85 10 5 2 +Oleyes Deprived Female 22.96 16 5 3.2 +Oleyes Satiated Male 23.08 15 5 3 +Oleyes Deprived Male 23.1 12 5 2.4 +Oleyes Deprived Male 23.43 11 5 2.2 +Oleyes Satiated Male 23.65 0 5 0 +Oleyes Satiated Female 23.65 0 5 0 +Oleyes Deprived Male 23.7 7 5 1.4 +Oleyes Deprived Female 23.83 6 5 1.2 +Oleyes Deprived Male 23.96 6 5 1.2 +Oleyes Satiated Male 24.11 0 5 0 +Oleyes Satiated Female 24.13 0 5 0 +Oleyes Deprived Male 24.2 5 5 1 +Oleyes Deprived Male 24.41 5 5 1 +Oleyes Deprived Male 24.56 7 5 1.4 +Oleyes Satiated Female 24.73 2 5 0.4 +Oleyes Satiated Male 24.9 32 5 6.4 +Oleyes Deprived Male 24.93 6 5 1.2 +Oleyes Satiated Male 25.08 32 5 6.4 +Oleyes Satiated Female 25.16 5 5 1 +Oleyes Deprived Female 25.2 7 5 1.4 +Oleyes Deprived Male 25.2 7 5 1.4 +Oleyes Satiated Male 25.45 5 5 1 +Oleyes Satiated Female 25.51 0 5 0 +Oleyes Deprived Male 25.68 3 5 0.6 +Oleyes Satiated Male 25.76 7 5 1.4 +Oleyes Deprived Female 25.8 14 5 2.8 +Oleyes Satiated Female 26 6 5 1.2 +Oleyes Satiated Male 26 6 5 1.2 +Oleyes Deprived Male 26 14 5 2.8 +Oleyes Deprived Male 26.03 0 5 0 +Oleyes Satiated Female 26.1 0 5 0 +Oleyes Satiated Male 26.28 13 5 2.6 +Oleyes Satiated Female 26.4 13 5 2.6 +Oleyes Satiated Male 26.55 0 5 0 +Oleyes Deprived Female 26.63 4 5 0.8 +Oleyes Deprived Male 26.75 4 5 0.8 +Oleyes Satiated Male 26.8 0 5 0 +Oleyes Satiated Male 26.98 0 5 0 +Oleyes Deprived Male 27.13 10 5 2 +Oleyes Deprived Female 27.31 10 5 2 +Oleyes Deprived Female 27.83 6 5 1.2 +Oleyes Deprived Male 28.03 2 5 0.4 +Oleyes Satiated Female 28.25 0 5 0 +Oleyes Deprived Female 28.86 0 5 0 +Payerne Satiated Male 22.08 6 5 1.2 +Payerne Satiated Female 22.15 6 5 1.2 +Payerne Satiated Female 22.61 8 5 1.6 +Payerne Satiated Male 22.63 8 5 1.6 +Payerne Satiated Female 22.71 8 5 1.6 +Payerne Deprived Male 22.78 8 5 1.6 +Payerne Satiated Male 22.88 7 5 1.4 +Payerne Deprived Female 23.01 15 5 3 +Payerne Satiated Male 23.03 8 5 1.6 +Payerne Satiated Female 23.1 8 5 1.6 +Payerne Satiated Female 23.35 0 5 0 +Payerne Satiated Male 23.43 0 5 0 +Payerne Satiated Male 23.68 1 5 0.2 +Payerne Satiated Male 24.1 8 5 1.6 +Payerne Satiated Male 24.35 5 5 1 +Payerne Satiated Male 24.48 5 5 1 +Payerne Satiated Male 25 7 5 1.4 +Payerne Deprived Male 25.05 10 5 2 +Payerne Deprived Male 25.26 14 5 2.8 +Payerne Satiated Female 25.35 0 5 0 +Payerne Deprived Female 25.36 14 5 2.8 +Payerne Satiated Male 25.51 0 5 0 +Payerne Satiated Male 25.85 0 5 0 +Payerne Satiated Male 26.31 0 5 0 +Payerne Satiated Male 27.53 0 5 0 +Rueyes Deprived Female 22.01 6 4 1.5 +Rueyes Satiated Female 22.06 0 4 0 +Rueyes Deprived Male 22.26 10 4 2.5 +Rueyes Satiated Male 22.35 18 4 4.5 +Rueyes Satiated Male 22.38 18 4 4.5 +Rueyes Satiated Male 22.48 18 4 4.5 +Rueyes Satiated Male 22.5 18 4 4.5 +Rueyes Satiated Male 22.58 11 4 2.75 +Rueyes Deprived Male 22.7 7 4 1.75 +Rueyes Satiated Male 22.95 11 4 2.75 +Rueyes Satiated Male 23.78 9 4 2.25 +Rueyes Deprived Male 24.05 6 4 1.5 +Rueyes Deprived Male 24.31 6 4 1.5 +Rueyes Satiated Female 25.06 0 4 0 +Rueyes Satiated Male 25.33 0 4 0 +Rueyes Deprived Male 25.35 1 4 0.25 +Rueyes Deprived Female 28.2 7 4 1.75 +Seiry Satiated Female 22.13 1 6 0.16666667 +Seiry Deprived Female 22.43 16 6 2.66666667 +Seiry Deprived Male 22.46 16 6 2.66666667 +Seiry Satiated Female 22.83 2 6 0.33333333 +Seiry Satiated Male 22.85 2 6 0.33333333 +Seiry Satiated Female 23.03 26 6 4.33333333 +Seiry Satiated Male 23.35 1 6 0.16666667 +Seiry Satiated Male 23.55 8 6 1.33333333 +Seiry Satiated Female 23.6 8 6 1.33333333 +Seiry Deprived Male 23.81 13 6 2.16666667 +Seiry Satiated Male 24.01 2 6 0.33333333 +Seiry Deprived Female 24.23 15 6 2.5 +Seiry Deprived Male 24.43 8 6 1.33333333 +Seiry Satiated Female 24.45 0 6 0 +Seiry Satiated Male 24.55 10 6 1.66666667 +Seiry Deprived Male 24.93 6 6 1 +Seiry Satiated Male 24.95 7 6 1.16666667 +Seiry Satiated Male 25.8 2 6 0.33333333 +Seiry Satiated Male 26 2 6 0.33333333 +Seiry Deprived Male 26.01 17 6 2.83333333 +Seiry Satiated Male 26.16 11 6 1.83333333 +Seiry Deprived Male 26.33 13 6 2.16666667 +Seiry Deprived Female 27.1 4 6 0.66666667 +Seiry Satiated Male 27.11 0 6 0 +Seiry Satiated Female 27.4 6 6 1 +Seiry Satiated Female 27.63 26 6 4.33333333 +Sevaz Deprived Male 22.86 6 1 6 +Sevaz Satiated Female 23.85 3 1 3 +Sevaz Satiated Male 26 6 1 6 +Sevaz Satiated Male 27.96 1 1 1 +StAubin Satiated Female 22.51 2 4 0.5 +StAubin Satiated Male 22.51 2 4 0.5 +StAubin Deprived Female 22.55 12 4 3 +StAubin Satiated Female 23.03 0 4 0 +StAubin Deprived Female 23.03 1 4 0.25 +StAubin Deprived Male 23.3 2 4 0.5 +StAubin Satiated Female 23.35 6 4 1.5 +StAubin Satiated Female 23.61 1 4 0.25 +StAubin Deprived Female 23.66 9 4 2.25 +StAubin Deprived Female 23.85 8 4 2 +StAubin Deprived Female 24.06 6 4 1.5 +StAubin Satiated Female 24.38 0 4 0 +StAubin Deprived Female 24.38 0 4 0 +StAubin Deprived Female 25.11 4 4 1 +StAubin Satiated Female 25.3 0 4 0 +StAubin Deprived Female 25.36 3 4 0.75 +StAubin Satiated Female 26.16 5 4 1.25 +StAubin Satiated Female 26.83 0 4 0 +StAubin Deprived Male 27.25 0 4 0 +StAubin Deprived Female 27.43 1 4 0.25 +StAubin Satiated Female 27.43 9 4 2.25 +StAubin Deprived Female 27.71 12 4 3 +StAubin Deprived Female 27.91 8 4 2 +Trey Deprived Female 22.05 16 5 3.2 +Trey Satiated Female 22.43 1 5 0.2 +Trey Satiated Male 22.73 12 5 2.4 +Trey Satiated Female 22.9 25 5 5 +Trey Satiated Male 23.2 16 5 3.2 +Trey Satiated Female 23.45 20 5 4 +Trey Satiated Male 23.73 23 5 4.6 +Trey Satiated Female 24.15 2 5 0.4 +Trey Satiated Female 24.36 11 5 2.2 +Trey Satiated Female 24.5 11 5 2.2 +Trey Satiated Male 24.6 3 5 0.6 +Trey Satiated Male 24.93 18 5 3.6 +Trey Satiated Female 25.28 5 5 1 +Trey Satiated Female 25.8 1 5 0.2 +Trey Satiated Male 25.86 1 5 0.2 +Trey Satiated Female 26.1 8 5 1.6 +Trey Satiated Male 27.66 0 5 0 +Trey Satiated Female 27.76 11 5 2.2 +Trey Satiated Female 27.93 11 5 2.2 +Yvonnand Satiated Female 21.71 10 7 1.42857143 +Yvonnand Satiated Female 21.73 10 7 1.42857143 +Yvonnand Satiated Female 21.91 17 7 2.42857143 +Yvonnand Satiated Male 21.93 17 7 2.42857143 +Yvonnand Satiated Female 21.95 17 7 2.42857143 +Yvonnand Deprived Male 21.96 6 7 0.85714286 +Yvonnand Deprived Female 22.18 19 7 2.71428571 +Yvonnand Satiated Male 22.28 4 7 0.57142857 +Yvonnand Deprived Male 22.3 31 7 4.42857143 +Yvonnand Deprived Male 22.5 31 7 4.42857143 +Yvonnand Satiated Male 22.56 10 7 1.42857143 +Yvonnand Deprived Female 22.6 23 7 3.28571429 +Yvonnand Deprived Male 22.6 23 7 3.28571429 +Yvonnand Deprived Male 22.9 15 7 2.14285714 +Yvonnand Satiated Male 23.25 0 7 0 +Yvonnand Satiated Female 23.46 6 7 0.85714286 +Yvonnand Satiated Female 23.53 1 7 0.14285714 +Yvonnand Satiated Female 23.63 1 7 0.14285714 +Yvonnand Deprived Male 24 9 7 1.28571429 +Yvonnand Deprived Male 24.31 6 7 0.85714286 +Yvonnand Deprived Male 24.56 8 7 1.14285714 +Yvonnand Deprived Male 24.73 10 7 1.42857143 +Yvonnand Satiated Male 25.25 4 7 0.57142857 +Yvonnand Satiated Female 25.41 11 7 1.57142857 +Yvonnand Satiated Female 25.56 9 7 1.28571429 +Yvonnand Satiated Female 25.76 14 7 2 +Yvonnand Deprived Male 26.15 13 7 1.85714286 +Yvonnand Deprived Male 26.76 22 7 3.14285714 +Yvonnand Deprived Male 27.23 7 7 1 +Yvonnand Deprived Female 27.25 7 7 1 +Yvonnand Deprived Male 28.45 5 7 0.71428571 +Yvonnand Deprived Female 28.86 15 7 2.14285714 +Yvonnand Deprived Male 29.21 10 7 1.42857143 +Yvonnand Satiated Female 29.23 0 7 0 diff --git a/data/feline-data.csv b/data/feline-data.csv new file mode 100644 index 00000000..df162080 --- /dev/null +++ b/data/feline-data.csv @@ -0,0 +1,4 @@ +"coat","weight","likes_string" +"calico",2.1,1 +"black",5,0 +"tabby",3.2,1 diff --git a/data/feline-data_v2.csv b/data/feline-data_v2.csv new file mode 100644 index 00000000..76d324eb --- /dev/null +++ b/data/feline-data_v2.csv @@ -0,0 +1,5 @@ +coat,weight,likes_string +calico,2.1,1 +black,5,0 +tabby,3.2,1 +tabby,2.3 or 2.4,1 diff --git a/data/gapminder-FiveYearData.csv b/data/gapminder-FiveYearData.csv new file mode 100644 index 00000000..661ddefc --- /dev/null +++ b/data/gapminder-FiveYearData.csv @@ -0,0 +1,1705 @@ +country,year,pop,continent,lifeExp,gdpPercap +Afghanistan,1952,8425333,Asia,28.801,779.4453145 +Afghanistan,1957,9240934,Asia,30.332,820.8530296 +Afghanistan,1962,10267083,Asia,31.997,853.10071 +Afghanistan,1967,11537966,Asia,34.02,836.1971382 +Afghanistan,1972,13079460,Asia,36.088,739.9811058 +Afghanistan,1977,14880372,Asia,38.438,786.11336 +Afghanistan,1982,12881816,Asia,39.854,978.0114388 +Afghanistan,1987,13867957,Asia,40.822,852.3959448 +Afghanistan,1992,16317921,Asia,41.674,649.3413952 +Afghanistan,1997,22227415,Asia,41.763,635.341351 +Afghanistan,2002,25268405,Asia,42.129,726.7340548 +Afghanistan,2007,31889923,Asia,43.828,974.5803384 +Albania,1952,1282697,Europe,55.23,1601.056136 +Albania,1957,1476505,Europe,59.28,1942.284244 +Albania,1962,1728137,Europe,64.82,2312.888958 +Albania,1967,1984060,Europe,66.22,2760.196931 +Albania,1972,2263554,Europe,67.69,3313.422188 +Albania,1977,2509048,Europe,68.93,3533.00391 +Albania,1982,2780097,Europe,70.42,3630.880722 +Albania,1987,3075321,Europe,72,3738.932735 +Albania,1992,3326498,Europe,71.581,2497.437901 +Albania,1997,3428038,Europe,72.95,3193.054604 +Albania,2002,3508512,Europe,75.651,4604.211737 +Albania,2007,3600523,Europe,76.423,5937.029526 +Algeria,1952,9279525,Africa,43.077,2449.008185 +Algeria,1957,10270856,Africa,45.685,3013.976023 +Algeria,1962,11000948,Africa,48.303,2550.81688 +Algeria,1967,12760499,Africa,51.407,3246.991771 +Algeria,1972,14760787,Africa,54.518,4182.663766 +Algeria,1977,17152804,Africa,58.014,4910.416756 +Algeria,1982,20033753,Africa,61.368,5745.160213 +Algeria,1987,23254956,Africa,65.799,5681.358539 +Algeria,1992,26298373,Africa,67.744,5023.216647 +Algeria,1997,29072015,Africa,69.152,4797.295051 +Algeria,2002,31287142,Africa,70.994,5288.040382 +Algeria,2007,33333216,Africa,72.301,6223.367465 +Angola,1952,4232095,Africa,30.015,3520.610273 +Angola,1957,4561361,Africa,31.999,3827.940465 +Angola,1962,4826015,Africa,34,4269.276742 +Angola,1967,5247469,Africa,35.985,5522.776375 +Angola,1972,5894858,Africa,37.928,5473.288005 +Angola,1977,6162675,Africa,39.483,3008.647355 +Angola,1982,7016384,Africa,39.942,2756.953672 +Angola,1987,7874230,Africa,39.906,2430.208311 +Angola,1992,8735988,Africa,40.647,2627.845685 +Angola,1997,9875024,Africa,40.963,2277.140884 +Angola,2002,10866106,Africa,41.003,2773.287312 +Angola,2007,12420476,Africa,42.731,4797.231267 +Argentina,1952,17876956,Americas,62.485,5911.315053 +Argentina,1957,19610538,Americas,64.399,6856.856212 +Argentina,1962,21283783,Americas,65.142,7133.166023 +Argentina,1967,22934225,Americas,65.634,8052.953021 +Argentina,1972,24779799,Americas,67.065,9443.038526 +Argentina,1977,26983828,Americas,68.481,10079.02674 +Argentina,1982,29341374,Americas,69.942,8997.897412 +Argentina,1987,31620918,Americas,70.774,9139.671389 +Argentina,1992,33958947,Americas,71.868,9308.41871 +Argentina,1997,36203463,Americas,73.275,10967.28195 +Argentina,2002,38331121,Americas,74.34,8797.640716 +Argentina,2007,40301927,Americas,75.32,12779.37964 +Australia,1952,8691212,Oceania,69.12,10039.59564 +Australia,1957,9712569,Oceania,70.33,10949.64959 +Australia,1962,10794968,Oceania,70.93,12217.22686 +Australia,1967,11872264,Oceania,71.1,14526.12465 +Australia,1972,13177000,Oceania,71.93,16788.62948 +Australia,1977,14074100,Oceania,73.49,18334.19751 +Australia,1982,15184200,Oceania,74.74,19477.00928 +Australia,1987,16257249,Oceania,76.32,21888.88903 +Australia,1992,17481977,Oceania,77.56,23424.76683 +Australia,1997,18565243,Oceania,78.83,26997.93657 +Australia,2002,19546792,Oceania,80.37,30687.75473 +Australia,2007,20434176,Oceania,81.235,34435.36744 +Austria,1952,6927772,Europe,66.8,6137.076492 +Austria,1957,6965860,Europe,67.48,8842.59803 +Austria,1962,7129864,Europe,69.54,10750.72111 +Austria,1967,7376998,Europe,70.14,12834.6024 +Austria,1972,7544201,Europe,70.63,16661.6256 +Austria,1977,7568430,Europe,72.17,19749.4223 +Austria,1982,7574613,Europe,73.18,21597.08362 +Austria,1987,7578903,Europe,74.94,23687.82607 +Austria,1992,7914969,Europe,76.04,27042.01868 +Austria,1997,8069876,Europe,77.51,29095.92066 +Austria,2002,8148312,Europe,78.98,32417.60769 +Austria,2007,8199783,Europe,79.829,36126.4927 +Bahrain,1952,120447,Asia,50.939,9867.084765 +Bahrain,1957,138655,Asia,53.832,11635.79945 +Bahrain,1962,171863,Asia,56.923,12753.27514 +Bahrain,1967,202182,Asia,59.923,14804.6727 +Bahrain,1972,230800,Asia,63.3,18268.65839 +Bahrain,1977,297410,Asia,65.593,19340.10196 +Bahrain,1982,377967,Asia,69.052,19211.14731 +Bahrain,1987,454612,Asia,70.75,18524.02406 +Bahrain,1992,529491,Asia,72.601,19035.57917 +Bahrain,1997,598561,Asia,73.925,20292.01679 +Bahrain,2002,656397,Asia,74.795,23403.55927 +Bahrain,2007,708573,Asia,75.635,29796.04834 +Bangladesh,1952,46886859,Asia,37.484,684.2441716 +Bangladesh,1957,51365468,Asia,39.348,661.6374577 +Bangladesh,1962,56839289,Asia,41.216,686.3415538 +Bangladesh,1967,62821884,Asia,43.453,721.1860862 +Bangladesh,1972,70759295,Asia,45.252,630.2336265 +Bangladesh,1977,80428306,Asia,46.923,659.8772322 +Bangladesh,1982,93074406,Asia,50.009,676.9818656 +Bangladesh,1987,103764241,Asia,52.819,751.9794035 +Bangladesh,1992,113704579,Asia,56.018,837.8101643 +Bangladesh,1997,123315288,Asia,59.412,972.7700352 +Bangladesh,2002,135656790,Asia,62.013,1136.39043 +Bangladesh,2007,150448339,Asia,64.062,1391.253792 +Belgium,1952,8730405,Europe,68,8343.105127 +Belgium,1957,8989111,Europe,69.24,9714.960623 +Belgium,1962,9218400,Europe,70.25,10991.20676 +Belgium,1967,9556500,Europe,70.94,13149.04119 +Belgium,1972,9709100,Europe,71.44,16672.14356 +Belgium,1977,9821800,Europe,72.8,19117.97448 +Belgium,1982,9856303,Europe,73.93,20979.84589 +Belgium,1987,9870200,Europe,75.35,22525.56308 +Belgium,1992,10045622,Europe,76.46,25575.57069 +Belgium,1997,10199787,Europe,77.53,27561.19663 +Belgium,2002,10311970,Europe,78.32,30485.88375 +Belgium,2007,10392226,Europe,79.441,33692.60508 +Benin,1952,1738315,Africa,38.223,1062.7522 +Benin,1957,1925173,Africa,40.358,959.6010805 +Benin,1962,2151895,Africa,42.618,949.4990641 +Benin,1967,2427334,Africa,44.885,1035.831411 +Benin,1972,2761407,Africa,47.014,1085.796879 +Benin,1977,3168267,Africa,49.19,1029.161251 +Benin,1982,3641603,Africa,50.904,1277.897616 +Benin,1987,4243788,Africa,52.337,1225.85601 +Benin,1992,4981671,Africa,53.919,1191.207681 +Benin,1997,6066080,Africa,54.777,1232.975292 +Benin,2002,7026113,Africa,54.406,1372.877931 +Benin,2007,8078314,Africa,56.728,1441.284873 +Bolivia,1952,2883315,Americas,40.414,2677.326347 +Bolivia,1957,3211738,Americas,41.89,2127.686326 +Bolivia,1962,3593918,Americas,43.428,2180.972546 +Bolivia,1967,4040665,Americas,45.032,2586.886053 +Bolivia,1972,4565872,Americas,46.714,2980.331339 +Bolivia,1977,5079716,Americas,50.023,3548.097832 +Bolivia,1982,5642224,Americas,53.859,3156.510452 +Bolivia,1987,6156369,Americas,57.251,2753.69149 +Bolivia,1992,6893451,Americas,59.957,2961.699694 +Bolivia,1997,7693188,Americas,62.05,3326.143191 +Bolivia,2002,8445134,Americas,63.883,3413.26269 +Bolivia,2007,9119152,Americas,65.554,3822.137084 +Bosnia and Herzegovina,1952,2791000,Europe,53.82,973.5331948 +Bosnia and Herzegovina,1957,3076000,Europe,58.45,1353.989176 +Bosnia and Herzegovina,1962,3349000,Europe,61.93,1709.683679 +Bosnia and Herzegovina,1967,3585000,Europe,64.79,2172.352423 +Bosnia and Herzegovina,1972,3819000,Europe,67.45,2860.16975 +Bosnia and Herzegovina,1977,4086000,Europe,69.86,3528.481305 +Bosnia and Herzegovina,1982,4172693,Europe,70.69,4126.613157 +Bosnia and Herzegovina,1987,4338977,Europe,71.14,4314.114757 +Bosnia and Herzegovina,1992,4256013,Europe,72.178,2546.781445 +Bosnia and Herzegovina,1997,3607000,Europe,73.244,4766.355904 +Bosnia and Herzegovina,2002,4165416,Europe,74.09,6018.975239 +Bosnia and Herzegovina,2007,4552198,Europe,74.852,7446.298803 +Botswana,1952,442308,Africa,47.622,851.2411407 +Botswana,1957,474639,Africa,49.618,918.2325349 +Botswana,1962,512764,Africa,51.52,983.6539764 +Botswana,1967,553541,Africa,53.298,1214.709294 +Botswana,1972,619351,Africa,56.024,2263.611114 +Botswana,1977,781472,Africa,59.319,3214.857818 +Botswana,1982,970347,Africa,61.484,4551.14215 +Botswana,1987,1151184,Africa,63.622,6205.88385 +Botswana,1992,1342614,Africa,62.745,7954.111645 +Botswana,1997,1536536,Africa,52.556,8647.142313 +Botswana,2002,1630347,Africa,46.634,11003.60508 +Botswana,2007,1639131,Africa,50.728,12569.85177 +Brazil,1952,56602560,Americas,50.917,2108.944355 +Brazil,1957,65551171,Americas,53.285,2487.365989 +Brazil,1962,76039390,Americas,55.665,3336.585802 +Brazil,1967,88049823,Americas,57.632,3429.864357 +Brazil,1972,100840058,Americas,59.504,4985.711467 +Brazil,1977,114313951,Americas,61.489,6660.118654 +Brazil,1982,128962939,Americas,63.336,7030.835878 +Brazil,1987,142938076,Americas,65.205,7807.095818 +Brazil,1992,155975974,Americas,67.057,6950.283021 +Brazil,1997,168546719,Americas,69.388,7957.980824 +Brazil,2002,179914212,Americas,71.006,8131.212843 +Brazil,2007,190010647,Americas,72.39,9065.800825 +Bulgaria,1952,7274900,Europe,59.6,2444.286648 +Bulgaria,1957,7651254,Europe,66.61,3008.670727 +Bulgaria,1962,8012946,Europe,69.51,4254.337839 +Bulgaria,1967,8310226,Europe,70.42,5577.0028 +Bulgaria,1972,8576200,Europe,70.9,6597.494398 +Bulgaria,1977,8797022,Europe,70.81,7612.240438 +Bulgaria,1982,8892098,Europe,71.08,8224.191647 +Bulgaria,1987,8971958,Europe,71.34,8239.854824 +Bulgaria,1992,8658506,Europe,71.19,6302.623438 +Bulgaria,1997,8066057,Europe,70.32,5970.38876 +Bulgaria,2002,7661799,Europe,72.14,7696.777725 +Bulgaria,2007,7322858,Europe,73.005,10680.79282 +Burkina Faso,1952,4469979,Africa,31.975,543.2552413 +Burkina Faso,1957,4713416,Africa,34.906,617.1834648 +Burkina Faso,1962,4919632,Africa,37.814,722.5120206 +Burkina Faso,1967,5127935,Africa,40.697,794.8265597 +Burkina Faso,1972,5433886,Africa,43.591,854.7359763 +Burkina Faso,1977,5889574,Africa,46.137,743.3870368 +Burkina Faso,1982,6634596,Africa,48.122,807.1985855 +Burkina Faso,1987,7586551,Africa,49.557,912.0631417 +Burkina Faso,1992,8878303,Africa,50.26,931.7527731 +Burkina Faso,1997,10352843,Africa,50.324,946.2949618 +Burkina Faso,2002,12251209,Africa,50.65,1037.645221 +Burkina Faso,2007,14326203,Africa,52.295,1217.032994 +Burundi,1952,2445618,Africa,39.031,339.2964587 +Burundi,1957,2667518,Africa,40.533,379.5646281 +Burundi,1962,2961915,Africa,42.045,355.2032273 +Burundi,1967,3330989,Africa,43.548,412.9775136 +Burundi,1972,3529983,Africa,44.057,464.0995039 +Burundi,1977,3834415,Africa,45.91,556.1032651 +Burundi,1982,4580410,Africa,47.471,559.603231 +Burundi,1987,5126023,Africa,48.211,621.8188189 +Burundi,1992,5809236,Africa,44.736,631.6998778 +Burundi,1997,6121610,Africa,45.326,463.1151478 +Burundi,2002,7021078,Africa,47.36,446.4035126 +Burundi,2007,8390505,Africa,49.58,430.0706916 +Cambodia,1952,4693836,Asia,39.417,368.4692856 +Cambodia,1957,5322536,Asia,41.366,434.0383364 +Cambodia,1962,6083619,Asia,43.415,496.9136476 +Cambodia,1967,6960067,Asia,45.415,523.4323142 +Cambodia,1972,7450606,Asia,40.317,421.6240257 +Cambodia,1977,6978607,Asia,31.22,524.9721832 +Cambodia,1982,7272485,Asia,50.957,624.4754784 +Cambodia,1987,8371791,Asia,53.914,683.8955732 +Cambodia,1992,10150094,Asia,55.803,682.3031755 +Cambodia,1997,11782962,Asia,56.534,734.28517 +Cambodia,2002,12926707,Asia,56.752,896.2260153 +Cambodia,2007,14131858,Asia,59.723,1713.778686 +Cameroon,1952,5009067,Africa,38.523,1172.667655 +Cameroon,1957,5359923,Africa,40.428,1313.048099 +Cameroon,1962,5793633,Africa,42.643,1399.607441 +Cameroon,1967,6335506,Africa,44.799,1508.453148 +Cameroon,1972,7021028,Africa,47.049,1684.146528 +Cameroon,1977,7959865,Africa,49.355,1783.432873 +Cameroon,1982,9250831,Africa,52.961,2367.983282 +Cameroon,1987,10780667,Africa,54.985,2602.664206 +Cameroon,1992,12467171,Africa,54.314,1793.163278 +Cameroon,1997,14195809,Africa,52.199,1694.337469 +Cameroon,2002,15929988,Africa,49.856,1934.011449 +Cameroon,2007,17696293,Africa,50.43,2042.09524 +Canada,1952,14785584,Americas,68.75,11367.16112 +Canada,1957,17010154,Americas,69.96,12489.95006 +Canada,1962,18985849,Americas,71.3,13462.48555 +Canada,1967,20819767,Americas,72.13,16076.58803 +Canada,1972,22284500,Americas,72.88,18970.57086 +Canada,1977,23796400,Americas,74.21,22090.88306 +Canada,1982,25201900,Americas,75.76,22898.79214 +Canada,1987,26549700,Americas,76.86,26626.51503 +Canada,1992,28523502,Americas,77.95,26342.88426 +Canada,1997,30305843,Americas,78.61,28954.92589 +Canada,2002,31902268,Americas,79.77,33328.96507 +Canada,2007,33390141,Americas,80.653,36319.23501 +Central African Republic,1952,1291695,Africa,35.463,1071.310713 +Central African Republic,1957,1392284,Africa,37.464,1190.844328 +Central African Republic,1962,1523478,Africa,39.475,1193.068753 +Central African Republic,1967,1733638,Africa,41.478,1136.056615 +Central African Republic,1972,1927260,Africa,43.457,1070.013275 +Central African Republic,1977,2167533,Africa,46.775,1109.374338 +Central African Republic,1982,2476971,Africa,48.295,956.7529907 +Central African Republic,1987,2840009,Africa,50.485,844.8763504 +Central African Republic,1992,3265124,Africa,49.396,747.9055252 +Central African Republic,1997,3696513,Africa,46.066,740.5063317 +Central African Republic,2002,4048013,Africa,43.308,738.6906068 +Central African Republic,2007,4369038,Africa,44.741,706.016537 +Chad,1952,2682462,Africa,38.092,1178.665927 +Chad,1957,2894855,Africa,39.881,1308.495577 +Chad,1962,3150417,Africa,41.716,1389.817618 +Chad,1967,3495967,Africa,43.601,1196.810565 +Chad,1972,3899068,Africa,45.569,1104.103987 +Chad,1977,4388260,Africa,47.383,1133.98495 +Chad,1982,4875118,Africa,49.517,797.9081006 +Chad,1987,5498955,Africa,51.051,952.386129 +Chad,1992,6429417,Africa,51.724,1058.0643 +Chad,1997,7562011,Africa,51.573,1004.961353 +Chad,2002,8835739,Africa,50.525,1156.18186 +Chad,2007,10238807,Africa,50.651,1704.063724 +Chile,1952,6377619,Americas,54.745,3939.978789 +Chile,1957,7048426,Americas,56.074,4315.622723 +Chile,1962,7961258,Americas,57.924,4519.094331 +Chile,1967,8858908,Americas,60.523,5106.654313 +Chile,1972,9717524,Americas,63.441,5494.024437 +Chile,1977,10599793,Americas,67.052,4756.763836 +Chile,1982,11487112,Americas,70.565,5095.665738 +Chile,1987,12463354,Americas,72.492,5547.063754 +Chile,1992,13572994,Americas,74.126,7596.125964 +Chile,1997,14599929,Americas,75.816,10118.05318 +Chile,2002,15497046,Americas,77.86,10778.78385 +Chile,2007,16284741,Americas,78.553,13171.63885 +China,1952,556263527.999989,Asia,44,400.448610699994 +China,1957,637408000,Asia,50.54896,575.9870009 +China,1962,665770000,Asia,44.50136,487.6740183 +China,1967,754550000,Asia,58.38112,612.7056934 +China,1972,862030000,Asia,63.11888,676.9000921 +China,1977,943455000,Asia,63.96736,741.2374699 +China,1982,1000281000,Asia,65.525,962.4213805 +China,1987,1084035000,Asia,67.274,1378.904018 +China,1992,1164970000,Asia,68.69,1655.784158 +China,1997,1230075000,Asia,70.426,2289.234136 +China,2002,1280400000,Asia,72.028,3119.280896 +China,2007,1318683096,Asia,72.961,4959.114854 +Colombia,1952,12350771,Americas,50.643,2144.115096 +Colombia,1957,14485993,Americas,55.118,2323.805581 +Colombia,1962,17009885,Americas,57.863,2492.351109 +Colombia,1967,19764027,Americas,59.963,2678.729839 +Colombia,1972,22542890,Americas,61.623,3264.660041 +Colombia,1977,25094412,Americas,63.837,3815.80787 +Colombia,1982,27764644,Americas,66.653,4397.575659 +Colombia,1987,30964245,Americas,67.768,4903.2191 +Colombia,1992,34202721,Americas,68.421,5444.648617 +Colombia,1997,37657830,Americas,70.313,6117.361746 +Colombia,2002,41008227,Americas,71.682,5755.259962 +Colombia,2007,44227550,Americas,72.889,7006.580419 +Comoros,1952,153936,Africa,40.715,1102.990936 +Comoros,1957,170928,Africa,42.46,1211.148548 +Comoros,1962,191689,Africa,44.467,1406.648278 +Comoros,1967,217378,Africa,46.472,1876.029643 +Comoros,1972,250027,Africa,48.944,1937.577675 +Comoros,1977,304739,Africa,50.939,1172.603047 +Comoros,1982,348643,Africa,52.933,1267.100083 +Comoros,1987,395114,Africa,54.926,1315.980812 +Comoros,1992,454429,Africa,57.939,1246.90737 +Comoros,1997,527982,Africa,60.66,1173.618235 +Comoros,2002,614382,Africa,62.974,1075.811558 +Comoros,2007,710960,Africa,65.152,986.1478792 +Congo Dem. Rep.,1952,14100005,Africa,39.143,780.5423257 +Congo Dem. Rep.,1957,15577932,Africa,40.652,905.8602303 +Congo Dem. Rep.,1962,17486434,Africa,42.122,896.3146335 +Congo Dem. Rep.,1967,19941073,Africa,44.056,861.5932424 +Congo Dem. Rep.,1972,23007669,Africa,45.989,904.8960685 +Congo Dem. Rep.,1977,26480870,Africa,47.804,795.757282 +Congo Dem. Rep.,1982,30646495,Africa,47.784,673.7478181 +Congo Dem. Rep.,1987,35481645,Africa,47.412,672.774812 +Congo Dem. Rep.,1992,41672143,Africa,45.548,457.7191807 +Congo Dem. Rep.,1997,47798986,Africa,42.587,312.188423 +Congo Dem. Rep.,2002,55379852,Africa,44.966,241.1658765 +Congo Dem. Rep.,2007,64606759,Africa,46.462,277.5518587 +Congo Rep.,1952,854885,Africa,42.111,2125.621418 +Congo Rep.,1957,940458,Africa,45.053,2315.056572 +Congo Rep.,1962,1047924,Africa,48.435,2464.783157 +Congo Rep.,1967,1179760,Africa,52.04,2677.939642 +Congo Rep.,1972,1340458,Africa,54.907,3213.152683 +Congo Rep.,1977,1536769,Africa,55.625,3259.178978 +Congo Rep.,1982,1774735,Africa,56.695,4879.507522 +Congo Rep.,1987,2064095,Africa,57.47,4201.194937 +Congo Rep.,1992,2409073,Africa,56.433,4016.239529 +Congo Rep.,1997,2800947,Africa,52.962,3484.164376 +Congo Rep.,2002,3328795,Africa,52.97,3484.06197 +Congo Rep.,2007,3800610,Africa,55.322,3632.557798 +Costa Rica,1952,926317,Americas,57.206,2627.009471 +Costa Rica,1957,1112300,Americas,60.026,2990.010802 +Costa Rica,1962,1345187,Americas,62.842,3460.937025 +Costa Rica,1967,1588717,Americas,65.424,4161.727834 +Costa Rica,1972,1834796,Americas,67.849,5118.146939 +Costa Rica,1977,2108457,Americas,70.75,5926.876967 +Costa Rica,1982,2424367,Americas,73.45,5262.734751 +Costa Rica,1987,2799811,Americas,74.752,5629.915318 +Costa Rica,1992,3173216,Americas,75.713,6160.416317 +Costa Rica,1997,3518107,Americas,77.26,6677.045314 +Costa Rica,2002,3834934,Americas,78.123,7723.447195 +Costa Rica,2007,4133884,Americas,78.782,9645.06142 +"Cote d'Ivoire",1952,2977019,Africa,40.477,1388.594732 +"Cote d'Ivoire",1957,3300000,Africa,42.469,1500.895925 +"Cote d'Ivoire",1962,3832408,Africa,44.93,1728.869428 +"Cote d'Ivoire",1967,4744870,Africa,47.35,2052.050473 +"Cote d'Ivoire",1972,6071696,Africa,49.801,2378.201111 +"Cote d'Ivoire",1977,7459574,Africa,52.374,2517.736547 +"Cote d'Ivoire",1982,9025951,Africa,53.983,2602.710169 +"Cote d'Ivoire",1987,10761098,Africa,54.655,2156.956069 +"Cote d'Ivoire",1992,12772596,Africa,52.044,1648.073791 +"Cote d'Ivoire",1997,14625967,Africa,47.991,1786.265407 +"Cote d'Ivoire",2002,16252726,Africa,46.832,1648.800823 +"Cote d'Ivoire",2007,18013409,Africa,48.328,1544.750112 +Croatia,1952,3882229,Europe,61.21,3119.23652 +Croatia,1957,3991242,Europe,64.77,4338.231617 +Croatia,1962,4076557,Europe,67.13,5477.890018 +Croatia,1967,4174366,Europe,68.5,6960.297861 +Croatia,1972,4225310,Europe,69.61,9164.090127 +Croatia,1977,4318673,Europe,70.64,11305.38517 +Croatia,1982,4413368,Europe,70.46,13221.82184 +Croatia,1987,4484310,Europe,71.52,13822.58394 +Croatia,1992,4494013,Europe,72.527,8447.794873 +Croatia,1997,4444595,Europe,73.68,9875.604515 +Croatia,2002,4481020,Europe,74.876,11628.38895 +Croatia,2007,4493312,Europe,75.748,14619.22272 +Cuba,1952,6007797,Americas,59.421,5586.53878 +Cuba,1957,6640752,Americas,62.325,6092.174359 +Cuba,1962,7254373,Americas,65.246,5180.75591 +Cuba,1967,8139332,Americas,68.29,5690.268015 +Cuba,1972,8831348,Americas,70.723,5305.445256 +Cuba,1977,9537988,Americas,72.649,6380.494966 +Cuba,1982,9789224,Americas,73.717,7316.918107 +Cuba,1987,10239839,Americas,74.174,7532.924763 +Cuba,1992,10723260,Americas,74.414,5592.843963 +Cuba,1997,10983007,Americas,76.151,5431.990415 +Cuba,2002,11226999,Americas,77.158,6340.646683 +Cuba,2007,11416987,Americas,78.273,8948.102923 +Czech Republic,1952,9125183,Europe,66.87,6876.14025 +Czech Republic,1957,9513758,Europe,69.03,8256.343918 +Czech Republic,1962,9620282,Europe,69.9,10136.86713 +Czech Republic,1967,9835109,Europe,70.38,11399.44489 +Czech Republic,1972,9862158,Europe,70.29,13108.4536 +Czech Republic,1977,10161915,Europe,70.71,14800.16062 +Czech Republic,1982,10303704,Europe,70.96,15377.22855 +Czech Republic,1987,10311597,Europe,71.58,16310.4434 +Czech Republic,1992,10315702,Europe,72.4,14297.02122 +Czech Republic,1997,10300707,Europe,74.01,16048.51424 +Czech Republic,2002,10256295,Europe,75.51,17596.21022 +Czech Republic,2007,10228744,Europe,76.486,22833.30851 +Denmark,1952,4334000,Europe,70.78,9692.385245 +Denmark,1957,4487831,Europe,71.81,11099.65935 +Denmark,1962,4646899,Europe,72.35,13583.31351 +Denmark,1967,4838800,Europe,72.96,15937.21123 +Denmark,1972,4991596,Europe,73.47,18866.20721 +Denmark,1977,5088419,Europe,74.69,20422.9015 +Denmark,1982,5117810,Europe,74.63,21688.04048 +Denmark,1987,5127024,Europe,74.8,25116.17581 +Denmark,1992,5171393,Europe,75.33,26406.73985 +Denmark,1997,5283663,Europe,76.11,29804.34567 +Denmark,2002,5374693,Europe,77.18,32166.50006 +Denmark,2007,5468120,Europe,78.332,35278.41874 +Djibouti,1952,63149,Africa,34.812,2669.529475 +Djibouti,1957,71851,Africa,37.328,2864.969076 +Djibouti,1962,89898,Africa,39.693,3020.989263 +Djibouti,1967,127617,Africa,42.074,3020.050513 +Djibouti,1972,178848,Africa,44.366,3694.212352 +Djibouti,1977,228694,Africa,46.519,3081.761022 +Djibouti,1982,305991,Africa,48.812,2879.468067 +Djibouti,1987,311025,Africa,50.04,2880.102568 +Djibouti,1992,384156,Africa,51.604,2377.156192 +Djibouti,1997,417908,Africa,53.157,1895.016984 +Djibouti,2002,447416,Africa,53.373,1908.260867 +Djibouti,2007,496374,Africa,54.791,2082.481567 +Dominican Republic,1952,2491346,Americas,45.928,1397.717137 +Dominican Republic,1957,2923186,Americas,49.828,1544.402995 +Dominican Republic,1962,3453434,Americas,53.459,1662.137359 +Dominican Republic,1967,4049146,Americas,56.751,1653.723003 +Dominican Republic,1972,4671329,Americas,59.631,2189.874499 +Dominican Republic,1977,5302800,Americas,61.788,2681.9889 +Dominican Republic,1982,5968349,Americas,63.727,2861.092386 +Dominican Republic,1987,6655297,Americas,66.046,2899.842175 +Dominican Republic,1992,7351181,Americas,68.457,3044.214214 +Dominican Republic,1997,7992357,Americas,69.957,3614.101285 +Dominican Republic,2002,8650322,Americas,70.847,4563.808154 +Dominican Republic,2007,9319622,Americas,72.235,6025.374752 +Ecuador,1952,3548753,Americas,48.357,3522.110717 +Ecuador,1957,4058385,Americas,51.356,3780.546651 +Ecuador,1962,4681707,Americas,54.64,4086.114078 +Ecuador,1967,5432424,Americas,56.678,4579.074215 +Ecuador,1972,6298651,Americas,58.796,5280.99471 +Ecuador,1977,7278866,Americas,61.31,6679.62326 +Ecuador,1982,8365850,Americas,64.342,7213.791267 +Ecuador,1987,9545158,Americas,67.231,6481.776993 +Ecuador,1992,10748394,Americas,69.613,7103.702595 +Ecuador,1997,11911819,Americas,72.312,7429.455877 +Ecuador,2002,12921234,Americas,74.173,5773.044512 +Ecuador,2007,13755680,Americas,74.994,6873.262326 +Egypt,1952,22223309,Africa,41.893,1418.822445 +Egypt,1957,25009741,Africa,44.444,1458.915272 +Egypt,1962,28173309,Africa,46.992,1693.335853 +Egypt,1967,31681188,Africa,49.293,1814.880728 +Egypt,1972,34807417,Africa,51.137,2024.008147 +Egypt,1977,38783863,Africa,53.319,2785.493582 +Egypt,1982,45681811,Africa,56.006,3503.729636 +Egypt,1987,52799062,Africa,59.797,3885.46071 +Egypt,1992,59402198,Africa,63.674,3794.755195 +Egypt,1997,66134291,Africa,67.217,4173.181797 +Egypt,2002,73312559,Africa,69.806,4754.604414 +Egypt,2007,80264543,Africa,71.338,5581.180998 +El Salvador,1952,2042865,Americas,45.262,3048.3029 +El Salvador,1957,2355805,Americas,48.57,3421.523218 +El Salvador,1962,2747687,Americas,52.307,3776.803627 +El Salvador,1967,3232927,Americas,55.855,4358.595393 +El Salvador,1972,3790903,Americas,58.207,4520.246008 +El Salvador,1977,4282586,Americas,56.696,5138.922374 +El Salvador,1982,4474873,Americas,56.604,4098.344175 +El Salvador,1987,4842194,Americas,63.154,4140.442097 +El Salvador,1992,5274649,Americas,66.798,4444.2317 +El Salvador,1997,5783439,Americas,69.535,5154.825496 +El Salvador,2002,6353681,Americas,70.734,5351.568666 +El Salvador,2007,6939688,Americas,71.878,5728.353514 +Equatorial Guinea,1952,216964,Africa,34.482,375.6431231 +Equatorial Guinea,1957,232922,Africa,35.983,426.0964081 +Equatorial Guinea,1962,249220,Africa,37.485,582.8419714 +Equatorial Guinea,1967,259864,Africa,38.987,915.5960025 +Equatorial Guinea,1972,277603,Africa,40.516,672.4122571 +Equatorial Guinea,1977,192675,Africa,42.024,958.5668124 +Equatorial Guinea,1982,285483,Africa,43.662,927.8253427 +Equatorial Guinea,1987,341244,Africa,45.664,966.8968149 +Equatorial Guinea,1992,387838,Africa,47.545,1132.055034 +Equatorial Guinea,1997,439971,Africa,48.245,2814.480755 +Equatorial Guinea,2002,495627,Africa,49.348,7703.4959 +Equatorial Guinea,2007,551201,Africa,51.579,12154.08975 +Eritrea,1952,1438760,Africa,35.928,328.9405571 +Eritrea,1957,1542611,Africa,38.047,344.1618859 +Eritrea,1962,1666618,Africa,40.158,380.9958433 +Eritrea,1967,1820319,Africa,42.189,468.7949699 +Eritrea,1972,2260187,Africa,44.142,514.3242082 +Eritrea,1977,2512642,Africa,44.535,505.7538077 +Eritrea,1982,2637297,Africa,43.89,524.8758493 +Eritrea,1987,2915959,Africa,46.453,521.1341333 +Eritrea,1992,3668440,Africa,49.991,582.8585102 +Eritrea,1997,4058319,Africa,53.378,913.47079 +Eritrea,2002,4414865,Africa,55.24,765.3500015 +Eritrea,2007,4906585,Africa,58.04,641.3695236 +Ethiopia,1952,20860941,Africa,34.078,362.1462796 +Ethiopia,1957,22815614,Africa,36.667,378.9041632 +Ethiopia,1962,25145372,Africa,40.059,419.4564161 +Ethiopia,1967,27860297,Africa,42.115,516.1186438 +Ethiopia,1972,30770372,Africa,43.515,566.2439442 +Ethiopia,1977,34617799,Africa,44.51,556.8083834 +Ethiopia,1982,38111756,Africa,44.916,577.8607471 +Ethiopia,1987,42999530,Africa,46.684,573.7413142 +Ethiopia,1992,52088559,Africa,48.091,421.3534653 +Ethiopia,1997,59861301,Africa,49.402,515.8894013 +Ethiopia,2002,67946797,Africa,50.725,530.0535319 +Ethiopia,2007,76511887,Africa,52.947,690.8055759 +Finland,1952,4090500,Europe,66.55,6424.519071 +Finland,1957,4324000,Europe,67.49,7545.415386 +Finland,1962,4491443,Europe,68.75,9371.842561 +Finland,1967,4605744,Europe,69.83,10921.63626 +Finland,1972,4639657,Europe,70.87,14358.8759 +Finland,1977,4738902,Europe,72.52,15605.42283 +Finland,1982,4826933,Europe,74.55,18533.15761 +Finland,1987,4931729,Europe,74.83,21141.01223 +Finland,1992,5041039,Europe,75.7,20647.16499 +Finland,1997,5134406,Europe,77.13,23723.9502 +Finland,2002,5193039,Europe,78.37,28204.59057 +Finland,2007,5238460,Europe,79.313,33207.0844 +France,1952,42459667,Europe,67.41,7029.809327 +France,1957,44310863,Europe,68.93,8662.834898 +France,1962,47124000,Europe,70.51,10560.48553 +France,1967,49569000,Europe,71.55,12999.91766 +France,1972,51732000,Europe,72.38,16107.19171 +France,1977,53165019,Europe,73.83,18292.63514 +France,1982,54433565,Europe,74.89,20293.89746 +France,1987,55630100,Europe,76.34,22066.44214 +France,1992,57374179,Europe,77.46,24703.79615 +France,1997,58623428,Europe,78.64,25889.78487 +France,2002,59925035,Europe,79.59,28926.03234 +France,2007,61083916,Europe,80.657,30470.0167 +Gabon,1952,420702,Africa,37.003,4293.476475 +Gabon,1957,434904,Africa,38.999,4976.198099 +Gabon,1962,455661,Africa,40.489,6631.459222 +Gabon,1967,489004,Africa,44.598,8358.761987 +Gabon,1972,537977,Africa,48.69,11401.94841 +Gabon,1977,706367,Africa,52.79,21745.57328 +Gabon,1982,753874,Africa,56.564,15113.36194 +Gabon,1987,880397,Africa,60.19,11864.40844 +Gabon,1992,985739,Africa,61.366,13522.15752 +Gabon,1997,1126189,Africa,60.461,14722.84188 +Gabon,2002,1299304,Africa,56.761,12521.71392 +Gabon,2007,1454867,Africa,56.735,13206.48452 +Gambia,1952,284320,Africa,30,485.2306591 +Gambia,1957,323150,Africa,32.065,520.9267111 +Gambia,1962,374020,Africa,33.896,599.650276 +Gambia,1967,439593,Africa,35.857,734.7829124 +Gambia,1972,517101,Africa,38.308,756.0868363 +Gambia,1977,608274,Africa,41.842,884.7552507 +Gambia,1982,715523,Africa,45.58,835.8096108 +Gambia,1987,848406,Africa,49.265,611.6588611 +Gambia,1992,1025384,Africa,52.644,665.6244126 +Gambia,1997,1235767,Africa,55.861,653.7301704 +Gambia,2002,1457766,Africa,58.041,660.5855997 +Gambia,2007,1688359,Africa,59.448,752.7497265 +Germany,1952,69145952,Europe,67.5,7144.114393 +Germany,1957,71019069,Europe,69.1,10187.82665 +Germany,1962,73739117,Europe,70.3,12902.46291 +Germany,1967,76368453,Europe,70.8,14745.62561 +Germany,1972,78717088,Europe,71,18016.18027 +Germany,1977,78160773,Europe,72.5,20512.92123 +Germany,1982,78335266,Europe,73.8,22031.53274 +Germany,1987,77718298,Europe,74.847,24639.18566 +Germany,1992,80597764,Europe,76.07,26505.30317 +Germany,1997,82011073,Europe,77.34,27788.88416 +Germany,2002,82350671,Europe,78.67,30035.80198 +Germany,2007,82400996,Europe,79.406,32170.37442 +Ghana,1952,5581001,Africa,43.149,911.2989371 +Ghana,1957,6391288,Africa,44.779,1043.561537 +Ghana,1962,7355248,Africa,46.452,1190.041118 +Ghana,1967,8490213,Africa,48.072,1125.69716 +Ghana,1972,9354120,Africa,49.875,1178.223708 +Ghana,1977,10538093,Africa,51.756,993.2239571 +Ghana,1982,11400338,Africa,53.744,876.032569 +Ghana,1987,14168101,Africa,55.729,847.0061135 +Ghana,1992,16278738,Africa,57.501,925.060154 +Ghana,1997,18418288,Africa,58.556,1005.245812 +Ghana,2002,20550751,Africa,58.453,1111.984578 +Ghana,2007,22873338,Africa,60.022,1327.60891 +Greece,1952,7733250,Europe,65.86,3530.690067 +Greece,1957,8096218,Europe,67.86,4916.299889 +Greece,1962,8448233,Europe,69.51,6017.190733 +Greece,1967,8716441,Europe,71,8513.097016 +Greece,1972,8888628,Europe,72.34,12724.82957 +Greece,1977,9308479,Europe,73.68,14195.52428 +Greece,1982,9786480,Europe,75.24,15268.42089 +Greece,1987,9974490,Europe,76.67,16120.52839 +Greece,1992,10325429,Europe,77.03,17541.49634 +Greece,1997,10502372,Europe,77.869,18747.69814 +Greece,2002,10603863,Europe,78.256,22514.2548 +Greece,2007,10706290,Europe,79.483,27538.41188 +Guatemala,1952,3146381,Americas,42.023,2428.237769 +Guatemala,1957,3640876,Americas,44.142,2617.155967 +Guatemala,1962,4208858,Americas,46.954,2750.364446 +Guatemala,1967,4690773,Americas,50.016,3242.531147 +Guatemala,1972,5149581,Americas,53.738,4031.408271 +Guatemala,1977,5703430,Americas,56.029,4879.992748 +Guatemala,1982,6395630,Americas,58.137,4820.49479 +Guatemala,1987,7326406,Americas,60.782,4246.485974 +Guatemala,1992,8486949,Americas,63.373,4439.45084 +Guatemala,1997,9803875,Americas,66.322,4684.313807 +Guatemala,2002,11178650,Americas,68.978,4858.347495 +Guatemala,2007,12572928,Americas,70.259,5186.050003 +Guinea,1952,2664249,Africa,33.609,510.1964923 +Guinea,1957,2876726,Africa,34.558,576.2670245 +Guinea,1962,3140003,Africa,35.753,686.3736739 +Guinea,1967,3451418,Africa,37.197,708.7595409 +Guinea,1972,3811387,Africa,38.842,741.6662307 +Guinea,1977,4227026,Africa,40.762,874.6858643 +Guinea,1982,4710497,Africa,42.891,857.2503577 +Guinea,1987,5650262,Africa,45.552,805.5724718 +Guinea,1992,6990574,Africa,48.576,794.3484384 +Guinea,1997,8048834,Africa,51.455,869.4497668 +Guinea,2002,8807818,Africa,53.676,945.5835837 +Guinea,2007,9947814,Africa,56.007,942.6542111 +Guinea-Bissau,1952,580653,Africa,32.5,299.850319 +Guinea-Bissau,1957,601095,Africa,33.489,431.7904566 +Guinea-Bissau,1962,627820,Africa,34.488,522.0343725 +Guinea-Bissau,1967,601287,Africa,35.492,715.5806402 +Guinea-Bissau,1972,625361,Africa,36.486,820.2245876 +Guinea-Bissau,1977,745228,Africa,37.465,764.7259628 +Guinea-Bissau,1982,825987,Africa,39.327,838.1239671 +Guinea-Bissau,1987,927524,Africa,41.245,736.4153921 +Guinea-Bissau,1992,1050938,Africa,43.266,745.5398706 +Guinea-Bissau,1997,1193708,Africa,44.873,796.6644681 +Guinea-Bissau,2002,1332459,Africa,45.504,575.7047176 +Guinea-Bissau,2007,1472041,Africa,46.388,579.231743 +Haiti,1952,3201488,Americas,37.579,1840.366939 +Haiti,1957,3507701,Americas,40.696,1726.887882 +Haiti,1962,3880130,Americas,43.59,1796.589032 +Haiti,1967,4318137,Americas,46.243,1452.057666 +Haiti,1972,4698301,Americas,48.042,1654.456946 +Haiti,1977,4908554,Americas,49.923,1874.298931 +Haiti,1982,5198399,Americas,51.461,2011.159549 +Haiti,1987,5756203,Americas,53.636,1823.015995 +Haiti,1992,6326682,Americas,55.089,1456.309517 +Haiti,1997,6913545,Americas,56.671,1341.726931 +Haiti,2002,7607651,Americas,58.137,1270.364932 +Haiti,2007,8502814,Americas,60.916,1201.637154 +Honduras,1952,1517453,Americas,41.912,2194.926204 +Honduras,1957,1770390,Americas,44.665,2220.487682 +Honduras,1962,2090162,Americas,48.041,2291.156835 +Honduras,1967,2500689,Americas,50.924,2538.269358 +Honduras,1972,2965146,Americas,53.884,2529.842345 +Honduras,1977,3055235,Americas,57.402,3203.208066 +Honduras,1982,3669448,Americas,60.909,3121.760794 +Honduras,1987,4372203,Americas,64.492,3023.096699 +Honduras,1992,5077347,Americas,66.399,3081.694603 +Honduras,1997,5867957,Americas,67.659,3160.454906 +Honduras,2002,6677328,Americas,68.565,3099.72866 +Honduras,2007,7483763,Americas,70.198,3548.330846 +Hong Kong China,1952,2125900,Asia,60.96,3054.421209 +Hong Kong China,1957,2736300,Asia,64.75,3629.076457 +Hong Kong China,1962,3305200,Asia,67.65,4692.648272 +Hong Kong China,1967,3722800,Asia,70,6197.962814 +Hong Kong China,1972,4115700,Asia,72,8315.928145 +Hong Kong China,1977,4583700,Asia,73.6,11186.14125 +Hong Kong China,1982,5264500,Asia,75.45,14560.53051 +Hong Kong China,1987,5584510,Asia,76.2,20038.47269 +Hong Kong China,1992,5829696,Asia,77.601,24757.60301 +Hong Kong China,1997,6495918,Asia,80,28377.63219 +Hong Kong China,2002,6762476,Asia,81.495,30209.01516 +Hong Kong China,2007,6980412,Asia,82.208,39724.97867 +Hungary,1952,9504000,Europe,64.03,5263.673816 +Hungary,1957,9839000,Europe,66.41,6040.180011 +Hungary,1962,10063000,Europe,67.96,7550.359877 +Hungary,1967,10223422,Europe,69.5,9326.64467 +Hungary,1972,10394091,Europe,69.76,10168.65611 +Hungary,1977,10637171,Europe,69.95,11674.83737 +Hungary,1982,10705535,Europe,69.39,12545.99066 +Hungary,1987,10612740,Europe,69.58,12986.47998 +Hungary,1992,10348684,Europe,69.17,10535.62855 +Hungary,1997,10244684,Europe,71.04,11712.7768 +Hungary,2002,10083313,Europe,72.59,14843.93556 +Hungary,2007,9956108,Europe,73.338,18008.94444 +Iceland,1952,147962,Europe,72.49,7267.688428 +Iceland,1957,165110,Europe,73.47,9244.001412 +Iceland,1962,182053,Europe,73.68,10350.15906 +Iceland,1967,198676,Europe,73.73,13319.89568 +Iceland,1972,209275,Europe,74.46,15798.06362 +Iceland,1977,221823,Europe,76.11,19654.96247 +Iceland,1982,233997,Europe,76.99,23269.6075 +Iceland,1987,244676,Europe,77.23,26923.20628 +Iceland,1992,259012,Europe,78.77,25144.39201 +Iceland,1997,271192,Europe,78.95,28061.09966 +Iceland,2002,288030,Europe,80.5,31163.20196 +Iceland,2007,301931,Europe,81.757,36180.78919 +India,1952,3.72e+08,Asia,37.373,546.5657493 +India,1957,4.09e+08,Asia,40.249,590.061996 +India,1962,4.54e+08,Asia,43.605,658.3471509 +India,1967,5.06e+08,Asia,47.193,700.7706107 +India,1972,5.67e+08,Asia,50.651,724.032527 +India,1977,6.34e+08,Asia,54.208,813.337323 +India,1982,7.08e+08,Asia,56.596,855.7235377 +India,1987,7.88e+08,Asia,58.553,976.5126756 +India,1992,8.72e+08,Asia,60.223,1164.406809 +India,1997,9.59e+08,Asia,61.765,1458.817442 +India,2002,1034172547,Asia,62.879,1746.769454 +India,2007,1110396331,Asia,64.698,2452.210407 +Indonesia,1952,82052000,Asia,37.468,749.6816546 +Indonesia,1957,90124000,Asia,39.918,858.9002707 +Indonesia,1962,99028000,Asia,42.518,849.2897701 +Indonesia,1967,109343000,Asia,45.964,762.4317721 +Indonesia,1972,121282000,Asia,49.203,1111.107907 +Indonesia,1977,136725000,Asia,52.702,1382.702056 +Indonesia,1982,153343000,Asia,56.159,1516.872988 +Indonesia,1987,169276000,Asia,60.137,1748.356961 +Indonesia,1992,184816000,Asia,62.681,2383.140898 +Indonesia,1997,199278000,Asia,66.041,3119.335603 +Indonesia,2002,211060000,Asia,68.588,2873.91287 +Indonesia,2007,223547000,Asia,70.65,3540.651564 +Iran,1952,17272000,Asia,44.869,3035.326002 +Iran,1957,19792000,Asia,47.181,3290.257643 +Iran,1962,22874000,Asia,49.325,4187.329802 +Iran,1967,26538000,Asia,52.469,5906.731805 +Iran,1972,30614000,Asia,55.234,9613.818607 +Iran,1977,35480679,Asia,57.702,11888.59508 +Iran,1982,43072751,Asia,59.62,7608.334602 +Iran,1987,51889696,Asia,63.04,6642.881371 +Iran,1992,60397973,Asia,65.742,7235.653188 +Iran,1997,63327987,Asia,68.042,8263.590301 +Iran,2002,66907826,Asia,69.451,9240.761975 +Iran,2007,69453570,Asia,70.964,11605.71449 +Iraq,1952,5441766,Asia,45.32,4129.766056 +Iraq,1957,6248643,Asia,48.437,6229.333562 +Iraq,1962,7240260,Asia,51.457,8341.737815 +Iraq,1967,8519282,Asia,54.459,8931.459811 +Iraq,1972,10061506,Asia,56.95,9576.037596 +Iraq,1977,11882916,Asia,60.413,14688.23507 +Iraq,1982,14173318,Asia,62.038,14517.90711 +Iraq,1987,16543189,Asia,65.044,11643.57268 +Iraq,1992,17861905,Asia,59.461,3745.640687 +Iraq,1997,20775703,Asia,58.811,3076.239795 +Iraq,2002,24001816,Asia,57.046,4390.717312 +Iraq,2007,27499638,Asia,59.545,4471.061906 +Ireland,1952,2952156,Europe,66.91,5210.280328 +Ireland,1957,2878220,Europe,68.9,5599.077872 +Ireland,1962,2830000,Europe,70.29,6631.597314 +Ireland,1967,2900100,Europe,71.08,7655.568963 +Ireland,1972,3024400,Europe,71.28,9530.772896 +Ireland,1977,3271900,Europe,72.03,11150.98113 +Ireland,1982,3480000,Europe,73.1,12618.32141 +Ireland,1987,3539900,Europe,74.36,13872.86652 +Ireland,1992,3557761,Europe,75.467,17558.81555 +Ireland,1997,3667233,Europe,76.122,24521.94713 +Ireland,2002,3879155,Europe,77.783,34077.04939 +Ireland,2007,4109086,Europe,78.885,40675.99635 +Israel,1952,1620914,Asia,65.39,4086.522128 +Israel,1957,1944401,Asia,67.84,5385.278451 +Israel,1962,2310904,Asia,69.39,7105.630706 +Israel,1967,2693585,Asia,70.75,8393.741404 +Israel,1972,3095893,Asia,71.63,12786.93223 +Israel,1977,3495918,Asia,73.06,13306.61921 +Israel,1982,3858421,Asia,74.45,15367.0292 +Israel,1987,4203148,Asia,75.6,17122.47986 +Israel,1992,4936550,Asia,76.93,18051.52254 +Israel,1997,5531387,Asia,78.269,20896.60924 +Israel,2002,6029529,Asia,79.696,21905.59514 +Israel,2007,6426679,Asia,80.745,25523.2771 +Italy,1952,47666000,Europe,65.94,4931.404155 +Italy,1957,49182000,Europe,67.81,6248.656232 +Italy,1962,50843200,Europe,69.24,8243.58234 +Italy,1967,52667100,Europe,71.06,10022.40131 +Italy,1972,54365564,Europe,72.19,12269.27378 +Italy,1977,56059245,Europe,73.48,14255.98475 +Italy,1982,56535636,Europe,74.98,16537.4835 +Italy,1987,56729703,Europe,76.42,19207.23482 +Italy,1992,56840847,Europe,77.44,22013.64486 +Italy,1997,57479469,Europe,78.82,24675.02446 +Italy,2002,57926999,Europe,80.24,27968.09817 +Italy,2007,58147733,Europe,80.546,28569.7197 +Jamaica,1952,1426095,Americas,58.53,2898.530881 +Jamaica,1957,1535090,Americas,62.61,4756.525781 +Jamaica,1962,1665128,Americas,65.61,5246.107524 +Jamaica,1967,1861096,Americas,67.51,6124.703451 +Jamaica,1972,1997616,Americas,69,7433.889293 +Jamaica,1977,2156814,Americas,70.11,6650.195573 +Jamaica,1982,2298309,Americas,71.21,6068.05135 +Jamaica,1987,2326606,Americas,71.77,6351.237495 +Jamaica,1992,2378618,Americas,71.766,7404.923685 +Jamaica,1997,2531311,Americas,72.262,7121.924704 +Jamaica,2002,2664659,Americas,72.047,6994.774861 +Jamaica,2007,2780132,Americas,72.567,7320.880262 +Japan,1952,86459025,Asia,63.03,3216.956347 +Japan,1957,91563009,Asia,65.5,4317.694365 +Japan,1962,95831757,Asia,68.73,6576.649461 +Japan,1967,100825279,Asia,71.43,9847.788607 +Japan,1972,107188273,Asia,73.42,14778.78636 +Japan,1977,113872473,Asia,75.38,16610.37701 +Japan,1982,118454974,Asia,77.11,19384.10571 +Japan,1987,122091325,Asia,78.67,22375.94189 +Japan,1992,124329269,Asia,79.36,26824.89511 +Japan,1997,125956499,Asia,80.69,28816.58499 +Japan,2002,127065841,Asia,82,28604.5919 +Japan,2007,127467972,Asia,82.603,31656.06806 +Jordan,1952,607914,Asia,43.158,1546.907807 +Jordan,1957,746559,Asia,45.669,1886.080591 +Jordan,1962,933559,Asia,48.126,2348.009158 +Jordan,1967,1255058,Asia,51.629,2741.796252 +Jordan,1972,1613551,Asia,56.528,2110.856309 +Jordan,1977,1937652,Asia,61.134,2852.351568 +Jordan,1982,2347031,Asia,63.739,4161.415959 +Jordan,1987,2820042,Asia,65.869,4448.679912 +Jordan,1992,3867409,Asia,68.015,3431.593647 +Jordan,1997,4526235,Asia,69.772,3645.379572 +Jordan,2002,5307470,Asia,71.263,3844.917194 +Jordan,2007,6053193,Asia,72.535,4519.461171 +Kenya,1952,6464046,Africa,42.27,853.540919 +Kenya,1957,7454779,Africa,44.686,944.4383152 +Kenya,1962,8678557,Africa,47.949,896.9663732 +Kenya,1967,10191512,Africa,50.654,1056.736457 +Kenya,1972,12044785,Africa,53.559,1222.359968 +Kenya,1977,14500404,Africa,56.155,1267.613204 +Kenya,1982,17661452,Africa,58.766,1348.225791 +Kenya,1987,21198082,Africa,59.339,1361.936856 +Kenya,1992,25020539,Africa,59.285,1341.921721 +Kenya,1997,28263827,Africa,54.407,1360.485021 +Kenya,2002,31386842,Africa,50.992,1287.514732 +Kenya,2007,35610177,Africa,54.11,1463.249282 +Korea Dem. Rep.,1952,8865488,Asia,50.056,1088.277758 +Korea Dem. Rep.,1957,9411381,Asia,54.081,1571.134655 +Korea Dem. Rep.,1962,10917494,Asia,56.656,1621.693598 +Korea Dem. Rep.,1967,12617009,Asia,59.942,2143.540609 +Korea Dem. Rep.,1972,14781241,Asia,63.983,3701.621503 +Korea Dem. Rep.,1977,16325320,Asia,67.159,4106.301249 +Korea Dem. Rep.,1982,17647518,Asia,69.1,4106.525293 +Korea Dem. Rep.,1987,19067554,Asia,70.647,4106.492315 +Korea Dem. Rep.,1992,20711375,Asia,69.978,3726.063507 +Korea Dem. Rep.,1997,21585105,Asia,67.727,1690.756814 +Korea Dem. Rep.,2002,22215365,Asia,66.662,1646.758151 +Korea Dem. Rep.,2007,23301725,Asia,67.297,1593.06548 +Korea Rep.,1952,20947571,Asia,47.453,1030.592226 +Korea Rep.,1957,22611552,Asia,52.681,1487.593537 +Korea Rep.,1962,26420307,Asia,55.292,1536.344387 +Korea Rep.,1967,30131000,Asia,57.716,2029.228142 +Korea Rep.,1972,33505000,Asia,62.612,3030.87665 +Korea Rep.,1977,36436000,Asia,64.766,4657.22102 +Korea Rep.,1982,39326000,Asia,67.123,5622.942464 +Korea Rep.,1987,41622000,Asia,69.81,8533.088805 +Korea Rep.,1992,43805450,Asia,72.244,12104.27872 +Korea Rep.,1997,46173816,Asia,74.647,15993.52796 +Korea Rep.,2002,47969150,Asia,77.045,19233.98818 +Korea Rep.,2007,49044790,Asia,78.623,23348.13973 +Kuwait,1952,160000,Asia,55.565,108382.3529 +Kuwait,1957,212846,Asia,58.033,113523.1329 +Kuwait,1962,358266,Asia,60.47,95458.11176 +Kuwait,1967,575003,Asia,64.624,80894.88326 +Kuwait,1972,841934,Asia,67.712,109347.867 +Kuwait,1977,1140357,Asia,69.343,59265.47714 +Kuwait,1982,1497494,Asia,71.309,31354.03573 +Kuwait,1987,1891487,Asia,74.174,28118.42998 +Kuwait,1992,1418095,Asia,75.19,34932.91959 +Kuwait,1997,1765345,Asia,76.156,40300.61996 +Kuwait,2002,2111561,Asia,76.904,35110.10566 +Kuwait,2007,2505559,Asia,77.588,47306.98978 +Lebanon,1952,1439529,Asia,55.928,4834.804067 +Lebanon,1957,1647412,Asia,59.489,6089.786934 +Lebanon,1962,1886848,Asia,62.094,5714.560611 +Lebanon,1967,2186894,Asia,63.87,6006.983042 +Lebanon,1972,2680018,Asia,65.421,7486.384341 +Lebanon,1977,3115787,Asia,66.099,8659.696836 +Lebanon,1982,3086876,Asia,66.983,7640.519521 +Lebanon,1987,3089353,Asia,67.926,5377.091329 +Lebanon,1992,3219994,Asia,69.292,6890.806854 +Lebanon,1997,3430388,Asia,70.265,8754.96385 +Lebanon,2002,3677780,Asia,71.028,9313.93883 +Lebanon,2007,3921278,Asia,71.993,10461.05868 +Lesotho,1952,748747,Africa,42.138,298.8462121 +Lesotho,1957,813338,Africa,45.047,335.9971151 +Lesotho,1962,893143,Africa,47.747,411.8006266 +Lesotho,1967,996380,Africa,48.492,498.6390265 +Lesotho,1972,1116779,Africa,49.767,496.5815922 +Lesotho,1977,1251524,Africa,52.208,745.3695408 +Lesotho,1982,1411807,Africa,55.078,797.2631074 +Lesotho,1987,1599200,Africa,57.18,773.9932141 +Lesotho,1992,1803195,Africa,59.685,977.4862725 +Lesotho,1997,1982823,Africa,55.558,1186.147994 +Lesotho,2002,2046772,Africa,44.593,1275.184575 +Lesotho,2007,2012649,Africa,42.592,1569.331442 +Liberia,1952,863308,Africa,38.48,575.5729961 +Liberia,1957,975950,Africa,39.486,620.9699901 +Liberia,1962,1112796,Africa,40.502,634.1951625 +Liberia,1967,1279406,Africa,41.536,713.6036483 +Liberia,1972,1482628,Africa,42.614,803.0054535 +Liberia,1977,1703617,Africa,43.764,640.3224383 +Liberia,1982,1956875,Africa,44.852,572.1995694 +Liberia,1987,2269414,Africa,46.027,506.1138573 +Liberia,1992,1912974,Africa,40.802,636.6229191 +Liberia,1997,2200725,Africa,42.221,609.1739508 +Liberia,2002,2814651,Africa,43.753,531.4823679 +Liberia,2007,3193942,Africa,45.678,414.5073415 +Libya,1952,1019729,Africa,42.723,2387.54806 +Libya,1957,1201578,Africa,45.289,3448.284395 +Libya,1962,1441863,Africa,47.808,6757.030816 +Libya,1967,1759224,Africa,50.227,18772.75169 +Libya,1972,2183877,Africa,52.773,21011.49721 +Libya,1977,2721783,Africa,57.442,21951.21176 +Libya,1982,3344074,Africa,62.155,17364.27538 +Libya,1987,3799845,Africa,66.234,11770.5898 +Libya,1992,4364501,Africa,68.755,9640.138501 +Libya,1997,4759670,Africa,71.555,9467.446056 +Libya,2002,5368585,Africa,72.737,9534.677467 +Libya,2007,6036914,Africa,73.952,12057.49928 +Madagascar,1952,4762912,Africa,36.681,1443.011715 +Madagascar,1957,5181679,Africa,38.865,1589.20275 +Madagascar,1962,5703324,Africa,40.848,1643.38711 +Madagascar,1967,6334556,Africa,42.881,1634.047282 +Madagascar,1972,7082430,Africa,44.851,1748.562982 +Madagascar,1977,8007166,Africa,46.881,1544.228586 +Madagascar,1982,9171477,Africa,48.969,1302.878658 +Madagascar,1987,10568642,Africa,49.35,1155.441948 +Madagascar,1992,12210395,Africa,52.214,1040.67619 +Madagascar,1997,14165114,Africa,54.978,986.2958956 +Madagascar,2002,16473477,Africa,57.286,894.6370822 +Madagascar,2007,19167654,Africa,59.443,1044.770126 +Malawi,1952,2917802,Africa,36.256,369.1650802 +Malawi,1957,3221238,Africa,37.207,416.3698064 +Malawi,1962,3628608,Africa,38.41,427.9010856 +Malawi,1967,4147252,Africa,39.487,495.5147806 +Malawi,1972,4730997,Africa,41.766,584.6219709 +Malawi,1977,5637246,Africa,43.767,663.2236766 +Malawi,1982,6502825,Africa,45.642,632.8039209 +Malawi,1987,7824747,Africa,47.457,635.5173634 +Malawi,1992,10014249,Africa,49.42,563.2000145 +Malawi,1997,10419991,Africa,47.495,692.2758103 +Malawi,2002,11824495,Africa,45.009,665.4231186 +Malawi,2007,13327079,Africa,48.303,759.3499101 +Malaysia,1952,6748378,Asia,48.463,1831.132894 +Malaysia,1957,7739235,Asia,52.102,1810.066992 +Malaysia,1962,8906385,Asia,55.737,2036.884944 +Malaysia,1967,10154878,Asia,59.371,2277.742396 +Malaysia,1972,11441462,Asia,63.01,2849.09478 +Malaysia,1977,12845381,Asia,65.256,3827.921571 +Malaysia,1982,14441916,Asia,68,4920.355951 +Malaysia,1987,16331785,Asia,69.5,5249.802653 +Malaysia,1992,18319502,Asia,70.693,7277.912802 +Malaysia,1997,20476091,Asia,71.938,10132.90964 +Malaysia,2002,22662365,Asia,73.044,10206.97794 +Malaysia,2007,24821286,Asia,74.241,12451.6558 +Mali,1952,3838168,Africa,33.685,452.3369807 +Mali,1957,4241884,Africa,35.307,490.3821867 +Mali,1962,4690372,Africa,36.936,496.1743428 +Mali,1967,5212416,Africa,38.487,545.0098873 +Mali,1972,5828158,Africa,39.977,581.3688761 +Mali,1977,6491649,Africa,41.714,686.3952693 +Mali,1982,6998256,Africa,43.916,618.0140641 +Mali,1987,7634008,Africa,46.364,684.1715576 +Mali,1992,8416215,Africa,48.388,739.014375 +Mali,1997,9384984,Africa,49.903,790.2579846 +Mali,2002,10580176,Africa,51.818,951.4097518 +Mali,2007,12031795,Africa,54.467,1042.581557 +Mauritania,1952,1022556,Africa,40.543,743.1159097 +Mauritania,1957,1076852,Africa,42.338,846.1202613 +Mauritania,1962,1146757,Africa,44.248,1055.896036 +Mauritania,1967,1230542,Africa,46.289,1421.145193 +Mauritania,1972,1332786,Africa,48.437,1586.851781 +Mauritania,1977,1456688,Africa,50.852,1497.492223 +Mauritania,1982,1622136,Africa,53.599,1481.150189 +Mauritania,1987,1841240,Africa,56.145,1421.603576 +Mauritania,1992,2119465,Africa,58.333,1361.369784 +Mauritania,1997,2444741,Africa,60.43,1483.136136 +Mauritania,2002,2828858,Africa,62.247,1579.019543 +Mauritania,2007,3270065,Africa,64.164,1803.151496 +Mauritius,1952,516556,Africa,50.986,1967.955707 +Mauritius,1957,609816,Africa,58.089,2034.037981 +Mauritius,1962,701016,Africa,60.246,2529.067487 +Mauritius,1967,789309,Africa,61.557,2475.387562 +Mauritius,1972,851334,Africa,62.944,2575.484158 +Mauritius,1977,913025,Africa,64.93,3710.982963 +Mauritius,1982,992040,Africa,66.711,3688.037739 +Mauritius,1987,1042663,Africa,68.74,4783.586903 +Mauritius,1992,1096202,Africa,69.745,6058.253846 +Mauritius,1997,1149818,Africa,70.736,7425.705295 +Mauritius,2002,1200206,Africa,71.954,9021.815894 +Mauritius,2007,1250882,Africa,72.801,10956.99112 +Mexico,1952,30144317,Americas,50.789,3478.125529 +Mexico,1957,35015548,Americas,55.19,4131.546641 +Mexico,1962,41121485,Americas,58.299,4581.609385 +Mexico,1967,47995559,Americas,60.11,5754.733883 +Mexico,1972,55984294,Americas,62.361,6809.40669 +Mexico,1977,63759976,Americas,65.032,7674.929108 +Mexico,1982,71640904,Americas,67.405,9611.147541 +Mexico,1987,80122492,Americas,69.498,8688.156003 +Mexico,1992,88111030,Americas,71.455,9472.384295 +Mexico,1997,95895146,Americas,73.67,9767.29753 +Mexico,2002,102479927,Americas,74.902,10742.44053 +Mexico,2007,108700891,Americas,76.195,11977.57496 +Mongolia,1952,800663,Asia,42.244,786.5668575 +Mongolia,1957,882134,Asia,45.248,912.6626085 +Mongolia,1962,1010280,Asia,48.251,1056.353958 +Mongolia,1967,1149500,Asia,51.253,1226.04113 +Mongolia,1972,1320500,Asia,53.754,1421.741975 +Mongolia,1977,1528000,Asia,55.491,1647.511665 +Mongolia,1982,1756032,Asia,57.489,2000.603139 +Mongolia,1987,2015133,Asia,60.222,2338.008304 +Mongolia,1992,2312802,Asia,61.271,1785.402016 +Mongolia,1997,2494803,Asia,63.625,1902.2521 +Mongolia,2002,2674234,Asia,65.033,2140.739323 +Mongolia,2007,2874127,Asia,66.803,3095.772271 +Montenegro,1952,413834,Europe,59.164,2647.585601 +Montenegro,1957,442829,Europe,61.448,3682.259903 +Montenegro,1962,474528,Europe,63.728,4649.593785 +Montenegro,1967,501035,Europe,67.178,5907.850937 +Montenegro,1972,527678,Europe,70.636,7778.414017 +Montenegro,1977,560073,Europe,73.066,9595.929905 +Montenegro,1982,562548,Europe,74.101,11222.58762 +Montenegro,1987,569473,Europe,74.865,11732.51017 +Montenegro,1992,621621,Europe,75.435,7003.339037 +Montenegro,1997,692651,Europe,75.445,6465.613349 +Montenegro,2002,720230,Europe,73.981,6557.194282 +Montenegro,2007,684736,Europe,74.543,9253.896111 +Morocco,1952,9939217,Africa,42.873,1688.20357 +Morocco,1957,11406350,Africa,45.423,1642.002314 +Morocco,1962,13056604,Africa,47.924,1566.353493 +Morocco,1967,14770296,Africa,50.335,1711.04477 +Morocco,1972,16660670,Africa,52.862,1930.194975 +Morocco,1977,18396941,Africa,55.73,2370.619976 +Morocco,1982,20198730,Africa,59.65,2702.620356 +Morocco,1987,22987397,Africa,62.677,2755.046991 +Morocco,1992,25798239,Africa,65.393,2948.047252 +Morocco,1997,28529501,Africa,67.66,2982.101858 +Morocco,2002,31167783,Africa,69.615,3258.495584 +Morocco,2007,33757175,Africa,71.164,3820.17523 +Mozambique,1952,6446316,Africa,31.286,468.5260381 +Mozambique,1957,7038035,Africa,33.779,495.5868333 +Mozambique,1962,7788944,Africa,36.161,556.6863539 +Mozambique,1967,8680909,Africa,38.113,566.6691539 +Mozambique,1972,9809596,Africa,40.328,724.9178037 +Mozambique,1977,11127868,Africa,42.495,502.3197334 +Mozambique,1982,12587223,Africa,42.795,462.2114149 +Mozambique,1987,12891952,Africa,42.861,389.8761846 +Mozambique,1992,13160731,Africa,44.284,410.8968239 +Mozambique,1997,16603334,Africa,46.344,472.3460771 +Mozambique,2002,18473780,Africa,44.026,633.6179466 +Mozambique,2007,19951656,Africa,42.082,823.6856205 +Myanmar,1952,20092996,Asia,36.319,331 +Myanmar,1957,21731844,Asia,41.905,350 +Myanmar,1962,23634436,Asia,45.108,388 +Myanmar,1967,25870271,Asia,49.379,349 +Myanmar,1972,28466390,Asia,53.07,357 +Myanmar,1977,31528087,Asia,56.059,371 +Myanmar,1982,34680442,Asia,58.056,424 +Myanmar,1987,38028578,Asia,58.339,385 +Myanmar,1992,40546538,Asia,59.32,347 +Myanmar,1997,43247867,Asia,60.328,415 +Myanmar,2002,45598081,Asia,59.908,611 +Myanmar,2007,47761980,Asia,62.069,944 +Namibia,1952,485831,Africa,41.725,2423.780443 +Namibia,1957,548080,Africa,45.226,2621.448058 +Namibia,1962,621392,Africa,48.386,3173.215595 +Namibia,1967,706640,Africa,51.159,3793.694753 +Namibia,1972,821782,Africa,53.867,3746.080948 +Namibia,1977,977026,Africa,56.437,3876.485958 +Namibia,1982,1099010,Africa,58.968,4191.100511 +Namibia,1987,1278184,Africa,60.835,3693.731337 +Namibia,1992,1554253,Africa,61.999,3804.537999 +Namibia,1997,1774766,Africa,58.909,3899.52426 +Namibia,2002,1972153,Africa,51.479,4072.324751 +Namibia,2007,2055080,Africa,52.906,4811.060429 +Nepal,1952,9182536,Asia,36.157,545.8657229 +Nepal,1957,9682338,Asia,37.686,597.9363558 +Nepal,1962,10332057,Asia,39.393,652.3968593 +Nepal,1967,11261690,Asia,41.472,676.4422254 +Nepal,1972,12412593,Asia,43.971,674.7881296 +Nepal,1977,13933198,Asia,46.748,694.1124398 +Nepal,1982,15796314,Asia,49.594,718.3730947 +Nepal,1987,17917180,Asia,52.537,775.6324501 +Nepal,1992,20326209,Asia,55.727,897.7403604 +Nepal,1997,23001113,Asia,59.426,1010.892138 +Nepal,2002,25873917,Asia,61.34,1057.206311 +Nepal,2007,28901790,Asia,63.785,1091.359778 +Netherlands,1952,10381988,Europe,72.13,8941.571858 +Netherlands,1957,11026383,Europe,72.99,11276.19344 +Netherlands,1962,11805689,Europe,73.23,12790.84956 +Netherlands,1967,12596822,Europe,73.82,15363.25136 +Netherlands,1972,13329874,Europe,73.75,18794.74567 +Netherlands,1977,13852989,Europe,75.24,21209.0592 +Netherlands,1982,14310401,Europe,76.05,21399.46046 +Netherlands,1987,14665278,Europe,76.83,23651.32361 +Netherlands,1992,15174244,Europe,77.42,26790.94961 +Netherlands,1997,15604464,Europe,78.03,30246.13063 +Netherlands,2002,16122830,Europe,78.53,33724.75778 +Netherlands,2007,16570613,Europe,79.762,36797.93332 +New Zealand,1952,1994794,Oceania,69.39,10556.57566 +New Zealand,1957,2229407,Oceania,70.26,12247.39532 +New Zealand,1962,2488550,Oceania,71.24,13175.678 +New Zealand,1967,2728150,Oceania,71.52,14463.91893 +New Zealand,1972,2929100,Oceania,71.89,16046.03728 +New Zealand,1977,3164900,Oceania,72.22,16233.7177 +New Zealand,1982,3210650,Oceania,73.84,17632.4104 +New Zealand,1987,3317166,Oceania,74.32,19007.19129 +New Zealand,1992,3437674,Oceania,76.33,18363.32494 +New Zealand,1997,3676187,Oceania,77.55,21050.41377 +New Zealand,2002,3908037,Oceania,79.11,23189.80135 +New Zealand,2007,4115771,Oceania,80.204,25185.00911 +Nicaragua,1952,1165790,Americas,42.314,3112.363948 +Nicaragua,1957,1358828,Americas,45.432,3457.415947 +Nicaragua,1962,1590597,Americas,48.632,3634.364406 +Nicaragua,1967,1865490,Americas,51.884,4643.393534 +Nicaragua,1972,2182908,Americas,55.151,4688.593267 +Nicaragua,1977,2554598,Americas,57.47,5486.371089 +Nicaragua,1982,2979423,Americas,59.298,3470.338156 +Nicaragua,1987,3344353,Americas,62.008,2955.984375 +Nicaragua,1992,4017939,Americas,65.843,2170.151724 +Nicaragua,1997,4609572,Americas,68.426,2253.023004 +Nicaragua,2002,5146848,Americas,70.836,2474.548819 +Nicaragua,2007,5675356,Americas,72.899,2749.320965 +Niger,1952,3379468,Africa,37.444,761.879376 +Niger,1957,3692184,Africa,38.598,835.5234025 +Niger,1962,4076008,Africa,39.487,997.7661127 +Niger,1967,4534062,Africa,40.118,1054.384891 +Niger,1972,5060262,Africa,40.546,954.2092363 +Niger,1977,5682086,Africa,41.291,808.8970728 +Niger,1982,6437188,Africa,42.598,909.7221354 +Niger,1987,7332638,Africa,44.555,668.3000228 +Niger,1992,8392818,Africa,47.391,581.182725 +Niger,1997,9666252,Africa,51.313,580.3052092 +Niger,2002,11140655,Africa,54.496,601.0745012 +Niger,2007,12894865,Africa,56.867,619.6768924 +Nigeria,1952,33119096,Africa,36.324,1077.281856 +Nigeria,1957,37173340,Africa,37.802,1100.592563 +Nigeria,1962,41871351,Africa,39.36,1150.927478 +Nigeria,1967,47287752,Africa,41.04,1014.514104 +Nigeria,1972,53740085,Africa,42.821,1698.388838 +Nigeria,1977,62209173,Africa,44.514,1981.951806 +Nigeria,1982,73039376,Africa,45.826,1576.97375 +Nigeria,1987,81551520,Africa,46.886,1385.029563 +Nigeria,1992,93364244,Africa,47.472,1619.848217 +Nigeria,1997,106207839,Africa,47.464,1624.941275 +Nigeria,2002,119901274,Africa,46.608,1615.286395 +Nigeria,2007,135031164,Africa,46.859,2013.977305 +Norway,1952,3327728,Europe,72.67,10095.42172 +Norway,1957,3491938,Europe,73.44,11653.97304 +Norway,1962,3638919,Europe,73.47,13450.40151 +Norway,1967,3786019,Europe,74.08,16361.87647 +Norway,1972,3933004,Europe,74.34,18965.05551 +Norway,1977,4043205,Europe,75.37,23311.34939 +Norway,1982,4114787,Europe,75.97,26298.63531 +Norway,1987,4186147,Europe,75.89,31540.9748 +Norway,1992,4286357,Europe,77.32,33965.66115 +Norway,1997,4405672,Europe,78.32,41283.16433 +Norway,2002,4535591,Europe,79.05,44683.97525 +Norway,2007,4627926,Europe,80.196,49357.19017 +Oman,1952,507833,Asia,37.578,1828.230307 +Oman,1957,561977,Asia,40.08,2242.746551 +Oman,1962,628164,Asia,43.165,2924.638113 +Oman,1967,714775,Asia,46.988,4720.942687 +Oman,1972,829050,Asia,52.143,10618.03855 +Oman,1977,1004533,Asia,57.367,11848.34392 +Oman,1982,1301048,Asia,62.728,12954.79101 +Oman,1987,1593882,Asia,67.734,18115.22313 +Oman,1992,1915208,Asia,71.197,18616.70691 +Oman,1997,2283635,Asia,72.499,19702.05581 +Oman,2002,2713462,Asia,74.193,19774.83687 +Oman,2007,3204897,Asia,75.64,22316.19287 +Pakistan,1952,41346560,Asia,43.436,684.5971438 +Pakistan,1957,46679944,Asia,45.557,747.0835292 +Pakistan,1962,53100671,Asia,47.67,803.3427418 +Pakistan,1967,60641899,Asia,49.8,942.4082588 +Pakistan,1972,69325921,Asia,51.929,1049.938981 +Pakistan,1977,78152686,Asia,54.043,1175.921193 +Pakistan,1982,91462088,Asia,56.158,1443.429832 +Pakistan,1987,105186881,Asia,58.245,1704.686583 +Pakistan,1992,120065004,Asia,60.838,1971.829464 +Pakistan,1997,135564834,Asia,61.818,2049.350521 +Pakistan,2002,153403524,Asia,63.61,2092.712441 +Pakistan,2007,169270617,Asia,65.483,2605.94758 +Panama,1952,940080,Americas,55.191,2480.380334 +Panama,1957,1063506,Americas,59.201,2961.800905 +Panama,1962,1215725,Americas,61.817,3536.540301 +Panama,1967,1405486,Americas,64.071,4421.009084 +Panama,1972,1616384,Americas,66.216,5364.249663 +Panama,1977,1839782,Americas,68.681,5351.912144 +Panama,1982,2036305,Americas,70.472,7009.601598 +Panama,1987,2253639,Americas,71.523,7034.779161 +Panama,1992,2484997,Americas,72.462,6618.74305 +Panama,1997,2734531,Americas,73.738,7113.692252 +Panama,2002,2990875,Americas,74.712,7356.031934 +Panama,2007,3242173,Americas,75.537,9809.185636 +Paraguay,1952,1555876,Americas,62.649,1952.308701 +Paraguay,1957,1770902,Americas,63.196,2046.154706 +Paraguay,1962,2009813,Americas,64.361,2148.027146 +Paraguay,1967,2287985,Americas,64.951,2299.376311 +Paraguay,1972,2614104,Americas,65.815,2523.337977 +Paraguay,1977,2984494,Americas,66.353,3248.373311 +Paraguay,1982,3366439,Americas,66.874,4258.503604 +Paraguay,1987,3886512,Americas,67.378,3998.875695 +Paraguay,1992,4483945,Americas,68.225,4196.411078 +Paraguay,1997,5154123,Americas,69.4,4247.400261 +Paraguay,2002,5884491,Americas,70.755,3783.674243 +Paraguay,2007,6667147,Americas,71.752,4172.838464 +Peru,1952,8025700,Americas,43.902,3758.523437 +Peru,1957,9146100,Americas,46.263,4245.256698 +Peru,1962,10516500,Americas,49.096,4957.037982 +Peru,1967,12132200,Americas,51.445,5788.09333 +Peru,1972,13954700,Americas,55.448,5937.827283 +Peru,1977,15990099,Americas,58.447,6281.290855 +Peru,1982,18125129,Americas,61.406,6434.501797 +Peru,1987,20195924,Americas,64.134,6360.943444 +Peru,1992,22430449,Americas,66.458,4446.380924 +Peru,1997,24748122,Americas,68.386,5838.347657 +Peru,2002,26769436,Americas,69.906,5909.020073 +Peru,2007,28674757,Americas,71.421,7408.905561 +Philippines,1952,22438691,Asia,47.752,1272.880995 +Philippines,1957,26072194,Asia,51.334,1547.944844 +Philippines,1962,30325264,Asia,54.757,1649.552153 +Philippines,1967,35356600,Asia,56.393,1814.12743 +Philippines,1972,40850141,Asia,58.065,1989.37407 +Philippines,1977,46850962,Asia,60.06,2373.204287 +Philippines,1982,53456774,Asia,62.082,2603.273765 +Philippines,1987,60017788,Asia,64.151,2189.634995 +Philippines,1992,67185766,Asia,66.458,2279.324017 +Philippines,1997,75012988,Asia,68.564,2536.534925 +Philippines,2002,82995088,Asia,70.303,2650.921068 +Philippines,2007,91077287,Asia,71.688,3190.481016 +Poland,1952,25730551,Europe,61.31,4029.329699 +Poland,1957,28235346,Europe,65.77,4734.253019 +Poland,1962,30329617,Europe,67.64,5338.752143 +Poland,1967,31785378,Europe,69.61,6557.152776 +Poland,1972,33039545,Europe,70.85,8006.506993 +Poland,1977,34621254,Europe,70.67,9508.141454 +Poland,1982,36227381,Europe,71.32,8451.531004 +Poland,1987,37740710,Europe,70.98,9082.351172 +Poland,1992,38370697,Europe,70.99,7738.881247 +Poland,1997,38654957,Europe,72.75,10159.58368 +Poland,2002,38625976,Europe,74.67,12002.23908 +Poland,2007,38518241,Europe,75.563,15389.92468 +Portugal,1952,8526050,Europe,59.82,3068.319867 +Portugal,1957,8817650,Europe,61.51,3774.571743 +Portugal,1962,9019800,Europe,64.39,4727.954889 +Portugal,1967,9103000,Europe,66.6,6361.517993 +Portugal,1972,8970450,Europe,69.26,9022.247417 +Portugal,1977,9662600,Europe,70.41,10172.48572 +Portugal,1982,9859650,Europe,72.77,11753.84291 +Portugal,1987,9915289,Europe,74.06,13039.30876 +Portugal,1992,9927680,Europe,74.86,16207.26663 +Portugal,1997,10156415,Europe,75.97,17641.03156 +Portugal,2002,10433867,Europe,77.29,19970.90787 +Portugal,2007,10642836,Europe,78.098,20509.64777 +Puerto Rico,1952,2227000,Americas,64.28,3081.959785 +Puerto Rico,1957,2260000,Americas,68.54,3907.156189 +Puerto Rico,1962,2448046,Americas,69.62,5108.34463 +Puerto Rico,1967,2648961,Americas,71.1,6929.277714 +Puerto Rico,1972,2847132,Americas,72.16,9123.041742 +Puerto Rico,1977,3080828,Americas,73.44,9770.524921 +Puerto Rico,1982,3279001,Americas,73.75,10330.98915 +Puerto Rico,1987,3444468,Americas,74.63,12281.34191 +Puerto Rico,1992,3585176,Americas,73.911,14641.58711 +Puerto Rico,1997,3759430,Americas,74.917,16999.4333 +Puerto Rico,2002,3859606,Americas,77.778,18855.60618 +Puerto Rico,2007,3942491,Americas,78.746,19328.70901 +Reunion,1952,257700,Africa,52.724,2718.885295 +Reunion,1957,308700,Africa,55.09,2769.451844 +Reunion,1962,358900,Africa,57.666,3173.72334 +Reunion,1967,414024,Africa,60.542,4021.175739 +Reunion,1972,461633,Africa,64.274,5047.658563 +Reunion,1977,492095,Africa,67.064,4319.804067 +Reunion,1982,517810,Africa,69.885,5267.219353 +Reunion,1987,562035,Africa,71.913,5303.377488 +Reunion,1992,622191,Africa,73.615,6101.255823 +Reunion,1997,684810,Africa,74.772,6071.941411 +Reunion,2002,743981,Africa,75.744,6316.1652 +Reunion,2007,798094,Africa,76.442,7670.122558 +Romania,1952,16630000,Europe,61.05,3144.613186 +Romania,1957,17829327,Europe,64.1,3943.370225 +Romania,1962,18680721,Europe,66.8,4734.997586 +Romania,1967,19284814,Europe,66.8,6470.866545 +Romania,1972,20662648,Europe,69.21,8011.414402 +Romania,1977,21658597,Europe,69.46,9356.39724 +Romania,1982,22356726,Europe,69.66,9605.314053 +Romania,1987,22686371,Europe,69.53,9696.273295 +Romania,1992,22797027,Europe,69.36,6598.409903 +Romania,1997,22562458,Europe,69.72,7346.547557 +Romania,2002,22404337,Europe,71.322,7885.360081 +Romania,2007,22276056,Europe,72.476,10808.47561 +Rwanda,1952,2534927,Africa,40,493.3238752 +Rwanda,1957,2822082,Africa,41.5,540.2893983 +Rwanda,1962,3051242,Africa,43,597.4730727 +Rwanda,1967,3451079,Africa,44.1,510.9637142 +Rwanda,1972,3992121,Africa,44.6,590.5806638 +Rwanda,1977,4657072,Africa,45,670.0806011 +Rwanda,1982,5507565,Africa,46.218,881.5706467 +Rwanda,1987,6349365,Africa,44.02,847.991217 +Rwanda,1992,7290203,Africa,23.599,737.0685949 +Rwanda,1997,7212583,Africa,36.087,589.9445051 +Rwanda,2002,7852401,Africa,43.413,785.6537648 +Rwanda,2007,8860588,Africa,46.242,863.0884639 +Sao Tome and Principe,1952,60011,Africa,46.471,879.5835855 +Sao Tome and Principe,1957,61325,Africa,48.945,860.7369026 +Sao Tome and Principe,1962,65345,Africa,51.893,1071.551119 +Sao Tome and Principe,1967,70787,Africa,54.425,1384.840593 +Sao Tome and Principe,1972,76595,Africa,56.48,1532.985254 +Sao Tome and Principe,1977,86796,Africa,58.55,1737.561657 +Sao Tome and Principe,1982,98593,Africa,60.351,1890.218117 +Sao Tome and Principe,1987,110812,Africa,61.728,1516.525457 +Sao Tome and Principe,1992,125911,Africa,62.742,1428.777814 +Sao Tome and Principe,1997,145608,Africa,63.306,1339.076036 +Sao Tome and Principe,2002,170372,Africa,64.337,1353.09239 +Sao Tome and Principe,2007,199579,Africa,65.528,1598.435089 +Saudi Arabia,1952,4005677,Asia,39.875,6459.554823 +Saudi Arabia,1957,4419650,Asia,42.868,8157.591248 +Saudi Arabia,1962,4943029,Asia,45.914,11626.41975 +Saudi Arabia,1967,5618198,Asia,49.901,16903.04886 +Saudi Arabia,1972,6472756,Asia,53.886,24837.42865 +Saudi Arabia,1977,8128505,Asia,58.69,34167.7626 +Saudi Arabia,1982,11254672,Asia,63.012,33693.17525 +Saudi Arabia,1987,14619745,Asia,66.295,21198.26136 +Saudi Arabia,1992,16945857,Asia,68.768,24841.61777 +Saudi Arabia,1997,21229759,Asia,70.533,20586.69019 +Saudi Arabia,2002,24501530,Asia,71.626,19014.54118 +Saudi Arabia,2007,27601038,Asia,72.777,21654.83194 +Senegal,1952,2755589,Africa,37.278,1450.356983 +Senegal,1957,3054547,Africa,39.329,1567.653006 +Senegal,1962,3430243,Africa,41.454,1654.988723 +Senegal,1967,3965841,Africa,43.563,1612.404632 +Senegal,1972,4588696,Africa,45.815,1597.712056 +Senegal,1977,5260855,Africa,48.879,1561.769116 +Senegal,1982,6147783,Africa,52.379,1518.479984 +Senegal,1987,7171347,Africa,55.769,1441.72072 +Senegal,1992,8307920,Africa,58.196,1367.899369 +Senegal,1997,9535314,Africa,60.187,1392.368347 +Senegal,2002,10870037,Africa,61.6,1519.635262 +Senegal,2007,12267493,Africa,63.062,1712.472136 +Serbia,1952,6860147,Europe,57.996,3581.459448 +Serbia,1957,7271135,Europe,61.685,4981.090891 +Serbia,1962,7616060,Europe,64.531,6289.629157 +Serbia,1967,7971222,Europe,66.914,7991.707066 +Serbia,1972,8313288,Europe,68.7,10522.06749 +Serbia,1977,8686367,Europe,70.3,12980.66956 +Serbia,1982,9032824,Europe,70.162,15181.0927 +Serbia,1987,9230783,Europe,71.218,15870.87851 +Serbia,1992,9826397,Europe,71.659,9325.068238 +Serbia,1997,10336594,Europe,72.232,7914.320304 +Serbia,2002,10111559,Europe,73.213,7236.075251 +Serbia,2007,10150265,Europe,74.002,9786.534714 +Sierra Leone,1952,2143249,Africa,30.331,879.7877358 +Sierra Leone,1957,2295678,Africa,31.57,1004.484437 +Sierra Leone,1962,2467895,Africa,32.767,1116.639877 +Sierra Leone,1967,2662190,Africa,34.113,1206.043465 +Sierra Leone,1972,2879013,Africa,35.4,1353.759762 +Sierra Leone,1977,3140897,Africa,36.788,1348.285159 +Sierra Leone,1982,3464522,Africa,38.445,1465.010784 +Sierra Leone,1987,3868905,Africa,40.006,1294.447788 +Sierra Leone,1992,4260884,Africa,38.333,1068.696278 +Sierra Leone,1997,4578212,Africa,39.897,574.6481576 +Sierra Leone,2002,5359092,Africa,41.012,699.489713 +Sierra Leone,2007,6144562,Africa,42.568,862.5407561 +Singapore,1952,1127000,Asia,60.396,2315.138227 +Singapore,1957,1445929,Asia,63.179,2843.104409 +Singapore,1962,1750200,Asia,65.798,3674.735572 +Singapore,1967,1977600,Asia,67.946,4977.41854 +Singapore,1972,2152400,Asia,69.521,8597.756202 +Singapore,1977,2325300,Asia,70.795,11210.08948 +Singapore,1982,2651869,Asia,71.76,15169.16112 +Singapore,1987,2794552,Asia,73.56,18861.53081 +Singapore,1992,3235865,Asia,75.788,24769.8912 +Singapore,1997,3802309,Asia,77.158,33519.4766 +Singapore,2002,4197776,Asia,78.77,36023.1054 +Singapore,2007,4553009,Asia,79.972,47143.17964 +Slovak Republic,1952,3558137,Europe,64.36,5074.659104 +Slovak Republic,1957,3844277,Europe,67.45,6093.26298 +Slovak Republic,1962,4237384,Europe,70.33,7481.107598 +Slovak Republic,1967,4442238,Europe,70.98,8412.902397 +Slovak Republic,1972,4593433,Europe,70.35,9674.167626 +Slovak Republic,1977,4827803,Europe,70.45,10922.66404 +Slovak Republic,1982,5048043,Europe,70.8,11348.54585 +Slovak Republic,1987,5199318,Europe,71.08,12037.26758 +Slovak Republic,1992,5302888,Europe,71.38,9498.467723 +Slovak Republic,1997,5383010,Europe,72.71,12126.23065 +Slovak Republic,2002,5410052,Europe,73.8,13638.77837 +Slovak Republic,2007,5447502,Europe,74.663,18678.31435 +Slovenia,1952,1489518,Europe,65.57,4215.041741 +Slovenia,1957,1533070,Europe,67.85,5862.276629 +Slovenia,1962,1582962,Europe,69.15,7402.303395 +Slovenia,1967,1646912,Europe,69.18,9405.489397 +Slovenia,1972,1694510,Europe,69.82,12383.4862 +Slovenia,1977,1746919,Europe,70.97,15277.03017 +Slovenia,1982,1861252,Europe,71.063,17866.72175 +Slovenia,1987,1945870,Europe,72.25,18678.53492 +Slovenia,1992,1999210,Europe,73.64,14214.71681 +Slovenia,1997,2011612,Europe,75.13,17161.10735 +Slovenia,2002,2011497,Europe,76.66,20660.01936 +Slovenia,2007,2009245,Europe,77.926,25768.25759 +Somalia,1952,2526994,Africa,32.978,1135.749842 +Somalia,1957,2780415,Africa,34.977,1258.147413 +Somalia,1962,3080153,Africa,36.981,1369.488336 +Somalia,1967,3428839,Africa,38.977,1284.73318 +Somalia,1972,3840161,Africa,40.973,1254.576127 +Somalia,1977,4353666,Africa,41.974,1450.992513 +Somalia,1982,5828892,Africa,42.955,1176.807031 +Somalia,1987,6921858,Africa,44.501,1093.244963 +Somalia,1992,6099799,Africa,39.658,926.9602964 +Somalia,1997,6633514,Africa,43.795,930.5964284 +Somalia,2002,7753310,Africa,45.936,882.0818218 +Somalia,2007,9118773,Africa,48.159,926.1410683 +South Africa,1952,14264935,Africa,45.009,4725.295531 +South Africa,1957,16151549,Africa,47.985,5487.104219 +South Africa,1962,18356657,Africa,49.951,5768.729717 +South Africa,1967,20997321,Africa,51.927,7114.477971 +South Africa,1972,23935810,Africa,53.696,7765.962636 +South Africa,1977,27129932,Africa,55.527,8028.651439 +South Africa,1982,31140029,Africa,58.161,8568.266228 +South Africa,1987,35933379,Africa,60.834,7825.823398 +South Africa,1992,39964159,Africa,61.888,7225.069258 +South Africa,1997,42835005,Africa,60.236,7479.188244 +South Africa,2002,44433622,Africa,53.365,7710.946444 +South Africa,2007,43997828,Africa,49.339,9269.657808 +Spain,1952,28549870,Europe,64.94,3834.034742 +Spain,1957,29841614,Europe,66.66,4564.80241 +Spain,1962,31158061,Europe,69.69,5693.843879 +Spain,1967,32850275,Europe,71.44,7993.512294 +Spain,1972,34513161,Europe,73.06,10638.75131 +Spain,1977,36439000,Europe,74.39,13236.92117 +Spain,1982,37983310,Europe,76.3,13926.16997 +Spain,1987,38880702,Europe,76.9,15764.98313 +Spain,1992,39549438,Europe,77.57,18603.06452 +Spain,1997,39855442,Europe,78.77,20445.29896 +Spain,2002,40152517,Europe,79.78,24835.47166 +Spain,2007,40448191,Europe,80.941,28821.0637 +Sri Lanka,1952,7982342,Asia,57.593,1083.53203 +Sri Lanka,1957,9128546,Asia,61.456,1072.546602 +Sri Lanka,1962,10421936,Asia,62.192,1074.47196 +Sri Lanka,1967,11737396,Asia,64.266,1135.514326 +Sri Lanka,1972,13016733,Asia,65.042,1213.39553 +Sri Lanka,1977,14116836,Asia,65.949,1348.775651 +Sri Lanka,1982,15410151,Asia,68.757,1648.079789 +Sri Lanka,1987,16495304,Asia,69.011,1876.766827 +Sri Lanka,1992,17587060,Asia,70.379,2153.739222 +Sri Lanka,1997,18698655,Asia,70.457,2664.477257 +Sri Lanka,2002,19576783,Asia,70.815,3015.378833 +Sri Lanka,2007,20378239,Asia,72.396,3970.095407 +Sudan,1952,8504667,Africa,38.635,1615.991129 +Sudan,1957,9753392,Africa,39.624,1770.337074 +Sudan,1962,11183227,Africa,40.87,1959.593767 +Sudan,1967,12716129,Africa,42.858,1687.997641 +Sudan,1972,14597019,Africa,45.083,1659.652775 +Sudan,1977,17104986,Africa,47.8,2202.988423 +Sudan,1982,20367053,Africa,50.338,1895.544073 +Sudan,1987,24725960,Africa,51.744,1507.819159 +Sudan,1992,28227588,Africa,53.556,1492.197043 +Sudan,1997,32160729,Africa,55.373,1632.210764 +Sudan,2002,37090298,Africa,56.369,1993.398314 +Sudan,2007,42292929,Africa,58.556,2602.394995 +Swaziland,1952,290243,Africa,41.407,1148.376626 +Swaziland,1957,326741,Africa,43.424,1244.708364 +Swaziland,1962,370006,Africa,44.992,1856.182125 +Swaziland,1967,420690,Africa,46.633,2613.101665 +Swaziland,1972,480105,Africa,49.552,3364.836625 +Swaziland,1977,551425,Africa,52.537,3781.410618 +Swaziland,1982,649901,Africa,55.561,3895.384018 +Swaziland,1987,779348,Africa,57.678,3984.839812 +Swaziland,1992,962344,Africa,58.474,3553.0224 +Swaziland,1997,1054486,Africa,54.289,3876.76846 +Swaziland,2002,1130269,Africa,43.869,4128.116943 +Swaziland,2007,1133066,Africa,39.613,4513.480643 +Sweden,1952,7124673,Europe,71.86,8527.844662 +Sweden,1957,7363802,Europe,72.49,9911.878226 +Sweden,1962,7561588,Europe,73.37,12329.44192 +Sweden,1967,7867931,Europe,74.16,15258.29697 +Sweden,1972,8122293,Europe,74.72,17832.02464 +Sweden,1977,8251648,Europe,75.44,18855.72521 +Sweden,1982,8325260,Europe,76.42,20667.38125 +Sweden,1987,8421403,Europe,77.19,23586.92927 +Sweden,1992,8718867,Europe,78.16,23880.01683 +Sweden,1997,8897619,Europe,79.39,25266.59499 +Sweden,2002,8954175,Europe,80.04,29341.63093 +Sweden,2007,9031088,Europe,80.884,33859.74835 +Switzerland,1952,4815000,Europe,69.62,14734.23275 +Switzerland,1957,5126000,Europe,70.56,17909.48973 +Switzerland,1962,5666000,Europe,71.32,20431.0927 +Switzerland,1967,6063000,Europe,72.77,22966.14432 +Switzerland,1972,6401400,Europe,73.78,27195.11304 +Switzerland,1977,6316424,Europe,75.39,26982.29052 +Switzerland,1982,6468126,Europe,76.21,28397.71512 +Switzerland,1987,6649942,Europe,77.41,30281.70459 +Switzerland,1992,6995447,Europe,78.03,31871.5303 +Switzerland,1997,7193761,Europe,79.37,32135.32301 +Switzerland,2002,7361757,Europe,80.62,34480.95771 +Switzerland,2007,7554661,Europe,81.701,37506.41907 +Syria,1952,3661549,Asia,45.883,1643.485354 +Syria,1957,4149908,Asia,48.284,2117.234893 +Syria,1962,4834621,Asia,50.305,2193.037133 +Syria,1967,5680812,Asia,53.655,1881.923632 +Syria,1972,6701172,Asia,57.296,2571.423014 +Syria,1977,7932503,Asia,61.195,3195.484582 +Syria,1982,9410494,Asia,64.59,3761.837715 +Syria,1987,11242847,Asia,66.974,3116.774285 +Syria,1992,13219062,Asia,69.249,3340.542768 +Syria,1997,15081016,Asia,71.527,4014.238972 +Syria,2002,17155814,Asia,73.053,4090.925331 +Syria,2007,19314747,Asia,74.143,4184.548089 +Taiwan,1952,8550362,Asia,58.5,1206.947913 +Taiwan,1957,10164215,Asia,62.4,1507.86129 +Taiwan,1962,11918938,Asia,65.2,1822.879028 +Taiwan,1967,13648692,Asia,67.5,2643.858681 +Taiwan,1972,15226039,Asia,69.39,4062.523897 +Taiwan,1977,16785196,Asia,70.59,5596.519826 +Taiwan,1982,18501390,Asia,72.16,7426.354774 +Taiwan,1987,19757799,Asia,73.4,11054.56175 +Taiwan,1992,20686918,Asia,74.26,15215.6579 +Taiwan,1997,21628605,Asia,75.25,20206.82098 +Taiwan,2002,22454239,Asia,76.99,23235.42329 +Taiwan,2007,23174294,Asia,78.4,28718.27684 +Tanzania,1952,8322925,Africa,41.215,716.6500721 +Tanzania,1957,9452826,Africa,42.974,698.5356073 +Tanzania,1962,10863958,Africa,44.246,722.0038073 +Tanzania,1967,12607312,Africa,45.757,848.2186575 +Tanzania,1972,14706593,Africa,47.62,915.9850592 +Tanzania,1977,17129565,Africa,49.919,962.4922932 +Tanzania,1982,19844382,Africa,50.608,874.2426069 +Tanzania,1987,23040630,Africa,51.535,831.8220794 +Tanzania,1992,26605473,Africa,50.44,825.682454 +Tanzania,1997,30686889,Africa,48.466,789.1862231 +Tanzania,2002,34593779,Africa,49.651,899.0742111 +Tanzania,2007,38139640,Africa,52.517,1107.482182 +Thailand,1952,21289402,Asia,50.848,757.7974177 +Thailand,1957,25041917,Asia,53.63,793.5774148 +Thailand,1962,29263397,Asia,56.061,1002.199172 +Thailand,1967,34024249,Asia,58.285,1295.46066 +Thailand,1972,39276153,Asia,60.405,1524.358936 +Thailand,1977,44148285,Asia,62.494,1961.224635 +Thailand,1982,48827160,Asia,64.597,2393.219781 +Thailand,1987,52910342,Asia,66.084,2982.653773 +Thailand,1992,56667095,Asia,67.298,4616.896545 +Thailand,1997,60216677,Asia,67.521,5852.625497 +Thailand,2002,62806748,Asia,68.564,5913.187529 +Thailand,2007,65068149,Asia,70.616,7458.396327 +Togo,1952,1219113,Africa,38.596,859.8086567 +Togo,1957,1357445,Africa,41.208,925.9083202 +Togo,1962,1528098,Africa,43.922,1067.53481 +Togo,1967,1735550,Africa,46.769,1477.59676 +Togo,1972,2056351,Africa,49.759,1649.660188 +Togo,1977,2308582,Africa,52.887,1532.776998 +Togo,1982,2644765,Africa,55.471,1344.577953 +Togo,1987,3154264,Africa,56.941,1202.201361 +Togo,1992,3747553,Africa,58.061,1034.298904 +Togo,1997,4320890,Africa,58.39,982.2869243 +Togo,2002,4977378,Africa,57.561,886.2205765 +Togo,2007,5701579,Africa,58.42,882.9699438 +Trinidad and Tobago,1952,662850,Americas,59.1,3023.271928 +Trinidad and Tobago,1957,764900,Americas,61.8,4100.3934 +Trinidad and Tobago,1962,887498,Americas,64.9,4997.523971 +Trinidad and Tobago,1967,960155,Americas,65.4,5621.368472 +Trinidad and Tobago,1972,975199,Americas,65.9,6619.551419 +Trinidad and Tobago,1977,1039009,Americas,68.3,7899.554209 +Trinidad and Tobago,1982,1116479,Americas,68.832,9119.528607 +Trinidad and Tobago,1987,1191336,Americas,69.582,7388.597823 +Trinidad and Tobago,1992,1183669,Americas,69.862,7370.990932 +Trinidad and Tobago,1997,1138101,Americas,69.465,8792.573126 +Trinidad and Tobago,2002,1101832,Americas,68.976,11460.60023 +Trinidad and Tobago,2007,1056608,Americas,69.819,18008.50924 +Tunisia,1952,3647735,Africa,44.6,1468.475631 +Tunisia,1957,3950849,Africa,47.1,1395.232468 +Tunisia,1962,4286552,Africa,49.579,1660.30321 +Tunisia,1967,4786986,Africa,52.053,1932.360167 +Tunisia,1972,5303507,Africa,55.602,2753.285994 +Tunisia,1977,6005061,Africa,59.837,3120.876811 +Tunisia,1982,6734098,Africa,64.048,3560.233174 +Tunisia,1987,7724976,Africa,66.894,3810.419296 +Tunisia,1992,8523077,Africa,70.001,4332.720164 +Tunisia,1997,9231669,Africa,71.973,4876.798614 +Tunisia,2002,9770575,Africa,73.042,5722.895655 +Tunisia,2007,10276158,Africa,73.923,7092.923025 +Turkey,1952,22235677,Europe,43.585,1969.10098 +Turkey,1957,25670939,Europe,48.079,2218.754257 +Turkey,1962,29788695,Europe,52.098,2322.869908 +Turkey,1967,33411317,Europe,54.336,2826.356387 +Turkey,1972,37492953,Europe,57.005,3450.69638 +Turkey,1977,42404033,Europe,59.507,4269.122326 +Turkey,1982,47328791,Europe,61.036,4241.356344 +Turkey,1987,52881328,Europe,63.108,5089.043686 +Turkey,1992,58179144,Europe,66.146,5678.348271 +Turkey,1997,63047647,Europe,68.835,6601.429915 +Turkey,2002,67308928,Europe,70.845,6508.085718 +Turkey,2007,71158647,Europe,71.777,8458.276384 +Uganda,1952,5824797,Africa,39.978,734.753484 +Uganda,1957,6675501,Africa,42.571,774.3710692 +Uganda,1962,7688797,Africa,45.344,767.2717398 +Uganda,1967,8900294,Africa,48.051,908.9185217 +Uganda,1972,10190285,Africa,51.016,950.735869 +Uganda,1977,11457758,Africa,50.35,843.7331372 +Uganda,1982,12939400,Africa,49.849,682.2662268 +Uganda,1987,15283050,Africa,51.509,617.7244065 +Uganda,1992,18252190,Africa,48.825,644.1707969 +Uganda,1997,21210254,Africa,44.578,816.559081 +Uganda,2002,24739869,Africa,47.813,927.7210018 +Uganda,2007,29170398,Africa,51.542,1056.380121 +United Kingdom,1952,50430000,Europe,69.18,9979.508487 +United Kingdom,1957,51430000,Europe,70.42,11283.17795 +United Kingdom,1962,53292000,Europe,70.76,12477.17707 +United Kingdom,1967,54959000,Europe,71.36,14142.85089 +United Kingdom,1972,56079000,Europe,72.01,15895.11641 +United Kingdom,1977,56179000,Europe,72.76,17428.74846 +United Kingdom,1982,56339704,Europe,74.04,18232.42452 +United Kingdom,1987,56981620,Europe,75.007,21664.78767 +United Kingdom,1992,57866349,Europe,76.42,22705.09254 +United Kingdom,1997,58808266,Europe,77.218,26074.53136 +United Kingdom,2002,59912431,Europe,78.471,29478.99919 +United Kingdom,2007,60776238,Europe,79.425,33203.26128 +United States,1952,157553000,Americas,68.44,13990.48208 +United States,1957,171984000,Americas,69.49,14847.12712 +United States,1962,186538000,Americas,70.21,16173.14586 +United States,1967,198712000,Americas,70.76,19530.36557 +United States,1972,209896000,Americas,71.34,21806.03594 +United States,1977,220239000,Americas,73.38,24072.63213 +United States,1982,232187835,Americas,74.65,25009.55914 +United States,1987,242803533,Americas,75.02,29884.35041 +United States,1992,256894189,Americas,76.09,32003.93224 +United States,1997,272911760,Americas,76.81,35767.43303 +United States,2002,287675526,Americas,77.31,39097.09955 +United States,2007,301139947,Americas,78.242,42951.65309 +Uruguay,1952,2252965,Americas,66.071,5716.766744 +Uruguay,1957,2424959,Americas,67.044,6150.772969 +Uruguay,1962,2598466,Americas,68.253,5603.357717 +Uruguay,1967,2748579,Americas,68.468,5444.61962 +Uruguay,1972,2829526,Americas,68.673,5703.408898 +Uruguay,1977,2873520,Americas,69.481,6504.339663 +Uruguay,1982,2953997,Americas,70.805,6920.223051 +Uruguay,1987,3045153,Americas,71.918,7452.398969 +Uruguay,1992,3149262,Americas,72.752,8137.004775 +Uruguay,1997,3262838,Americas,74.223,9230.240708 +Uruguay,2002,3363085,Americas,75.307,7727.002004 +Uruguay,2007,3447496,Americas,76.384,10611.46299 +Venezuela,1952,5439568,Americas,55.088,7689.799761 +Venezuela,1957,6702668,Americas,57.907,9802.466526 +Venezuela,1962,8143375,Americas,60.77,8422.974165 +Venezuela,1967,9709552,Americas,63.479,9541.474188 +Venezuela,1972,11515649,Americas,65.712,10505.25966 +Venezuela,1977,13503563,Americas,67.456,13143.95095 +Venezuela,1982,15620766,Americas,68.557,11152.41011 +Venezuela,1987,17910182,Americas,70.19,9883.584648 +Venezuela,1992,20265563,Americas,71.15,10733.92631 +Venezuela,1997,22374398,Americas,72.146,10165.49518 +Venezuela,2002,24287670,Americas,72.766,8605.047831 +Venezuela,2007,26084662,Americas,73.747,11415.80569 +Vietnam,1952,26246839,Asia,40.412,605.0664917 +Vietnam,1957,28998543,Asia,42.887,676.2854478 +Vietnam,1962,33796140,Asia,45.363,772.0491602 +Vietnam,1967,39463910,Asia,47.838,637.1232887 +Vietnam,1972,44655014,Asia,50.254,699.5016441 +Vietnam,1977,50533506,Asia,55.764,713.5371196 +Vietnam,1982,56142181,Asia,58.816,707.2357863 +Vietnam,1987,62826491,Asia,62.82,820.7994449 +Vietnam,1992,69940728,Asia,67.662,989.0231487 +Vietnam,1997,76048996,Asia,70.672,1385.896769 +Vietnam,2002,80908147,Asia,73.017,1764.456677 +Vietnam,2007,85262356,Asia,74.249,2441.576404 +West Bank and Gaza,1952,1030585,Asia,43.16,1515.592329 +West Bank and Gaza,1957,1070439,Asia,45.671,1827.067742 +West Bank and Gaza,1962,1133134,Asia,48.127,2198.956312 +West Bank and Gaza,1967,1142636,Asia,51.631,2649.715007 +West Bank and Gaza,1972,1089572,Asia,56.532,3133.409277 +West Bank and Gaza,1977,1261091,Asia,60.765,3682.831494 +West Bank and Gaza,1982,1425876,Asia,64.406,4336.032082 +West Bank and Gaza,1987,1691210,Asia,67.046,5107.197384 +West Bank and Gaza,1992,2104779,Asia,69.718,6017.654756 +West Bank and Gaza,1997,2826046,Asia,71.096,7110.667619 +West Bank and Gaza,2002,3389578,Asia,72.37,4515.487575 +West Bank and Gaza,2007,4018332,Asia,73.422,3025.349798 +Yemen Rep.,1952,4963829,Asia,32.548,781.7175761 +Yemen Rep.,1957,5498090,Asia,33.97,804.8304547 +Yemen Rep.,1962,6120081,Asia,35.18,825.6232006 +Yemen Rep.,1967,6740785,Asia,36.984,862.4421463 +Yemen Rep.,1972,7407075,Asia,39.848,1265.047031 +Yemen Rep.,1977,8403990,Asia,44.175,1829.765177 +Yemen Rep.,1982,9657618,Asia,49.113,1977.55701 +Yemen Rep.,1987,11219340,Asia,52.922,1971.741538 +Yemen Rep.,1992,13367997,Asia,55.599,1879.496673 +Yemen Rep.,1997,15826497,Asia,58.02,2117.484526 +Yemen Rep.,2002,18701257,Asia,60.308,2234.820827 +Yemen Rep.,2007,22211743,Asia,62.698,2280.769906 +Zambia,1952,2672000,Africa,42.038,1147.388831 +Zambia,1957,3016000,Africa,44.077,1311.956766 +Zambia,1962,3421000,Africa,46.023,1452.725766 +Zambia,1967,3900000,Africa,47.768,1777.077318 +Zambia,1972,4506497,Africa,50.107,1773.498265 +Zambia,1977,5216550,Africa,51.386,1588.688299 +Zambia,1982,6100407,Africa,51.821,1408.678565 +Zambia,1987,7272406,Africa,50.821,1213.315116 +Zambia,1992,8381163,Africa,46.1,1210.884633 +Zambia,1997,9417789,Africa,40.238,1071.353818 +Zambia,2002,10595811,Africa,39.193,1071.613938 +Zambia,2007,11746035,Africa,42.384,1271.211593 +Zimbabwe,1952,3080907,Africa,48.451,406.8841148 +Zimbabwe,1957,3646340,Africa,50.469,518.7642681 +Zimbabwe,1962,4277736,Africa,52.358,527.2721818 +Zimbabwe,1967,4995432,Africa,53.995,569.7950712 +Zimbabwe,1972,5861135,Africa,55.635,799.3621758 +Zimbabwe,1977,6642107,Africa,57.674,685.5876821 +Zimbabwe,1982,7636524,Africa,60.363,788.8550411 +Zimbabwe,1987,9216418,Africa,62.351,706.1573059 +Zimbabwe,1992,10704340,Africa,60.377,693.4207856 +Zimbabwe,1997,11404948,Africa,46.809,792.4499603 +Zimbabwe,2002,11926563,Africa,39.989,672.0386227 +Zimbabwe,2007,12311143,Africa,43.487,469.7092981 diff --git a/data/gapminder_wide.csv b/data/gapminder_wide.csv new file mode 100644 index 00000000..028508a5 --- /dev/null +++ b/data/gapminder_wide.csv @@ -0,0 +1,143 @@ +"continent","country","gdpPercap_1952","gdpPercap_1957","gdpPercap_1962","gdpPercap_1967","gdpPercap_1972","gdpPercap_1977","gdpPercap_1982","gdpPercap_1987","gdpPercap_1992","gdpPercap_1997","gdpPercap_2002","gdpPercap_2007","lifeExp_1952","lifeExp_1957","lifeExp_1962","lifeExp_1967","lifeExp_1972","lifeExp_1977","lifeExp_1982","lifeExp_1987","lifeExp_1992","lifeExp_1997","lifeExp_2002","lifeExp_2007","pop_1952","pop_1957","pop_1962","pop_1967","pop_1972","pop_1977","pop_1982","pop_1987","pop_1992","pop_1997","pop_2002","pop_2007" +"Africa","Algeria",2449.008185,3013.976023,2550.81688,3246.991771,4182.663766,4910.416756,5745.160213,5681.358539,5023.216647,4797.295051,5288.040382,6223.367465,43.077,45.685,48.303,51.407,54.518,58.014,61.368,65.799,67.744,69.152,70.994,72.301,9279525,10270856,11000948,12760499,14760787,17152804,20033753,23254956,26298373,29072015,31287142,33333216 +"Africa","Angola",3520.610273,3827.940465,4269.276742,5522.776375,5473.288005,3008.647355,2756.953672,2430.208311,2627.845685,2277.140884,2773.287312,4797.231267,30.015,31.999,34,35.985,37.928,39.483,39.942,39.906,40.647,40.963,41.003,42.731,4232095,4561361,4826015,5247469,5894858,6162675,7016384,7874230,8735988,9875024,10866106,12420476 +"Africa","Benin",1062.7522,959.6010805,949.4990641,1035.831411,1085.796879,1029.161251,1277.897616,1225.85601,1191.207681,1232.975292,1372.877931,1441.284873,38.223,40.358,42.618,44.885,47.014,49.19,50.904,52.337,53.919,54.777,54.406,56.728,1738315,1925173,2151895,2427334,2761407,3168267,3641603,4243788,4981671,6066080,7026113,8078314 +"Africa","Botswana",851.2411407,918.2325349,983.6539764,1214.709294,2263.611114,3214.857818,4551.14215,6205.88385,7954.111645,8647.142313,11003.60508,12569.85177,47.622,49.618,51.52,53.298,56.024,59.319,61.484,63.622,62.745,52.556,46.634,50.728,442308,474639,512764,553541,619351,781472,970347,1151184,1342614,1536536,1630347,1639131 +"Africa","Burkina Faso",543.2552413,617.1834648,722.5120206,794.8265597,854.7359763,743.3870368,807.1985855,912.0631417,931.7527731,946.2949618,1037.645221,1217.032994,31.975,34.906,37.814,40.697,43.591,46.137,48.122,49.557,50.26,50.324,50.65,52.295,4469979,4713416,4919632,5127935,5433886,5889574,6634596,7586551,8878303,10352843,12251209,14326203 +"Africa","Burundi",339.2964587,379.5646281,355.2032273,412.9775136,464.0995039,556.1032651,559.603231,621.8188189,631.6998778,463.1151478,446.4035126,430.0706916,39.031,40.533,42.045,43.548,44.057,45.91,47.471,48.211,44.736,45.326,47.36,49.58,2445618,2667518,2961915,3330989,3529983,3834415,4580410,5126023,5809236,6121610,7021078,8390505 +"Africa","Cameroon",1172.667655,1313.048099,1399.607441,1508.453148,1684.146528,1783.432873,2367.983282,2602.664206,1793.163278,1694.337469,1934.011449,2042.09524,38.523,40.428,42.643,44.799,47.049,49.355,52.961,54.985,54.314,52.199,49.856,50.43,5009067,5359923,5793633,6335506,7021028,7959865,9250831,10780667,12467171,14195809,15929988,17696293 +"Africa","Central African Republic",1071.310713,1190.844328,1193.068753,1136.056615,1070.013275,1109.374338,956.7529907,844.8763504,747.9055252,740.5063317,738.6906068,706.016537,35.463,37.464,39.475,41.478,43.457,46.775,48.295,50.485,49.396,46.066,43.308,44.741,1291695,1392284,1523478,1733638,1927260,2167533,2476971,2840009,3265124,3696513,4048013,4369038 +"Africa","Chad",1178.665927,1308.495577,1389.817618,1196.810565,1104.103987,1133.98495,797.9081006,952.386129,1058.0643,1004.961353,1156.18186,1704.063724,38.092,39.881,41.716,43.601,45.569,47.383,49.517,51.051,51.724,51.573,50.525,50.651,2682462,2894855,3150417,3495967,3899068,4388260,4875118,5498955,6429417,7562011,8835739,10238807 +"Africa","Comoros",1102.990936,1211.148548,1406.648278,1876.029643,1937.577675,1172.603047,1267.100083,1315.980812,1246.90737,1173.618235,1075.811558,986.1478792,40.715,42.46,44.467,46.472,48.944,50.939,52.933,54.926,57.939,60.66,62.974,65.152,153936,170928,191689,217378,250027,304739,348643,395114,454429,527982,614382,710960 +"Africa","Congo Dem. Rep.",780.5423257,905.8602303,896.3146335,861.5932424,904.8960685,795.757282,673.7478181,672.774812,457.7191807,312.188423,241.1658765,277.5518587,39.143,40.652,42.122,44.056,45.989,47.804,47.784,47.412,45.548,42.587,44.966,46.462,14100005,15577932,17486434,19941073,23007669,26480870,30646495,35481645,41672143,47798986,55379852,64606759 +"Africa","Congo Rep.",2125.621418,2315.056572,2464.783157,2677.939642,3213.152683,3259.178978,4879.507522,4201.194937,4016.239529,3484.164376,3484.06197,3632.557798,42.111,45.053,48.435,52.04,54.907,55.625,56.695,57.47,56.433,52.962,52.97,55.322,854885,940458,1047924,1179760,1340458,1536769,1774735,2064095,2409073,2800947,3328795,3800610 +"Africa","Cote d'Ivoire",1388.594732,1500.895925,1728.869428,2052.050473,2378.201111,2517.736547,2602.710169,2156.956069,1648.073791,1786.265407,1648.800823,1544.750112,40.477,42.469,44.93,47.35,49.801,52.374,53.983,54.655,52.044,47.991,46.832,48.328,2977019,3300000,3832408,4744870,6071696,7459574,9025951,10761098,12772596,14625967,16252726,18013409 +"Africa","Djibouti",2669.529475,2864.969076,3020.989263,3020.050513,3694.212352,3081.761022,2879.468067,2880.102568,2377.156192,1895.016984,1908.260867,2082.481567,34.812,37.328,39.693,42.074,44.366,46.519,48.812,50.04,51.604,53.157,53.373,54.791,63149,71851,89898,127617,178848,228694,305991,311025,384156,417908,447416,496374 +"Africa","Egypt",1418.822445,1458.915272,1693.335853,1814.880728,2024.008147,2785.493582,3503.729636,3885.46071,3794.755195,4173.181797,4754.604414,5581.180998,41.893,44.444,46.992,49.293,51.137,53.319,56.006,59.797,63.674,67.217,69.806,71.338,22223309,25009741,28173309,31681188,34807417,38783863,45681811,52799062,59402198,66134291,73312559,80264543 +"Africa","Equatorial Guinea",375.6431231,426.0964081,582.8419714,915.5960025,672.4122571,958.5668124,927.8253427,966.8968149,1132.055034,2814.480755,7703.4959,12154.08975,34.482,35.983,37.485,38.987,40.516,42.024,43.662,45.664,47.545,48.245,49.348,51.579,216964,232922,249220,259864,277603,192675,285483,341244,387838,439971,495627,551201 +"Africa","Eritrea",328.9405571,344.1618859,380.9958433,468.7949699,514.3242082,505.7538077,524.8758493,521.1341333,582.8585102,913.47079,765.3500015,641.3695236,35.928,38.047,40.158,42.189,44.142,44.535,43.89,46.453,49.991,53.378,55.24,58.04,1438760,1542611,1666618,1820319,2260187,2512642,2637297,2915959,3668440,4058319,4414865,4906585 +"Africa","Ethiopia",362.1462796,378.9041632,419.4564161,516.1186438,566.2439442,556.8083834,577.8607471,573.7413142,421.3534653,515.8894013,530.0535319,690.8055759,34.078,36.667,40.059,42.115,43.515,44.51,44.916,46.684,48.091,49.402,50.725,52.947,20860941,22815614,25145372,27860297,30770372,34617799,38111756,42999530,52088559,59861301,67946797,76511887 +"Africa","Gabon",4293.476475,4976.198099,6631.459222,8358.761987,11401.94841,21745.57328,15113.36194,11864.40844,13522.15752,14722.84188,12521.71392,13206.48452,37.003,38.999,40.489,44.598,48.69,52.79,56.564,60.19,61.366,60.461,56.761,56.735,420702,434904,455661,489004,537977,706367,753874,880397,985739,1126189,1299304,1454867 +"Africa","Gambia",485.2306591,520.9267111,599.650276,734.7829124,756.0868363,884.7552507,835.8096108,611.6588611,665.6244126,653.7301704,660.5855997,752.7497265,30,32.065,33.896,35.857,38.308,41.842,45.58,49.265,52.644,55.861,58.041,59.448,284320,323150,374020,439593,517101,608274,715523,848406,1025384,1235767,1457766,1688359 +"Africa","Ghana",911.2989371,1043.561537,1190.041118,1125.69716,1178.223708,993.2239571,876.032569,847.0061135,925.060154,1005.245812,1111.984578,1327.60891,43.149,44.779,46.452,48.072,49.875,51.756,53.744,55.729,57.501,58.556,58.453,60.022,5581001,6391288,7355248,8490213,9354120,10538093,11400338,14168101,16278738,18418288,20550751,22873338 +"Africa","Guinea",510.1964923,576.2670245,686.3736739,708.7595409,741.6662307,874.6858643,857.2503577,805.5724718,794.3484384,869.4497668,945.5835837,942.6542111,33.609,34.558,35.753,37.197,38.842,40.762,42.891,45.552,48.576,51.455,53.676,56.007,2664249,2876726,3140003,3451418,3811387,4227026,4710497,5650262,6990574,8048834,8807818,9947814 +"Africa","Guinea-Bissau",299.850319,431.7904566,522.0343725,715.5806402,820.2245876,764.7259628,838.1239671,736.4153921,745.5398706,796.6644681,575.7047176,579.231743,32.5,33.489,34.488,35.492,36.486,37.465,39.327,41.245,43.266,44.873,45.504,46.388,580653,601095,627820,601287,625361,745228,825987,927524,1050938,1193708,1332459,1472041 +"Africa","Kenya",853.540919,944.4383152,896.9663732,1056.736457,1222.359968,1267.613204,1348.225791,1361.936856,1341.921721,1360.485021,1287.514732,1463.249282,42.27,44.686,47.949,50.654,53.559,56.155,58.766,59.339,59.285,54.407,50.992,54.11,6464046,7454779,8678557,10191512,12044785,14500404,17661452,21198082,25020539,28263827,31386842,35610177 +"Africa","Lesotho",298.8462121,335.9971151,411.8006266,498.6390265,496.5815922,745.3695408,797.2631074,773.9932141,977.4862725,1186.147994,1275.184575,1569.331442,42.138,45.047,47.747,48.492,49.767,52.208,55.078,57.18,59.685,55.558,44.593,42.592,748747,813338,893143,996380,1116779,1251524,1411807,1599200,1803195,1982823,2046772,2012649 +"Africa","Liberia",575.5729961,620.9699901,634.1951625,713.6036483,803.0054535,640.3224383,572.1995694,506.1138573,636.6229191,609.1739508,531.4823679,414.5073415,38.48,39.486,40.502,41.536,42.614,43.764,44.852,46.027,40.802,42.221,43.753,45.678,863308,975950,1112796,1279406,1482628,1703617,1956875,2269414,1912974,2200725,2814651,3193942 +"Africa","Libya",2387.54806,3448.284395,6757.030816,18772.75169,21011.49721,21951.21176,17364.27538,11770.5898,9640.138501,9467.446056,9534.677467,12057.49928,42.723,45.289,47.808,50.227,52.773,57.442,62.155,66.234,68.755,71.555,72.737,73.952,1019729,1201578,1441863,1759224,2183877,2721783,3344074,3799845,4364501,4759670,5368585,6036914 +"Africa","Madagascar",1443.011715,1589.20275,1643.38711,1634.047282,1748.562982,1544.228586,1302.878658,1155.441948,1040.67619,986.2958956,894.6370822,1044.770126,36.681,38.865,40.848,42.881,44.851,46.881,48.969,49.35,52.214,54.978,57.286,59.443,4762912,5181679,5703324,6334556,7082430,8007166,9171477,10568642,12210395,14165114,16473477,19167654 +"Africa","Malawi",369.1650802,416.3698064,427.9010856,495.5147806,584.6219709,663.2236766,632.8039209,635.5173634,563.2000145,692.2758103,665.4231186,759.3499101,36.256,37.207,38.41,39.487,41.766,43.767,45.642,47.457,49.42,47.495,45.009,48.303,2917802,3221238,3628608,4147252,4730997,5637246,6502825,7824747,10014249,10419991,11824495,13327079 +"Africa","Mali",452.3369807,490.3821867,496.1743428,545.0098873,581.3688761,686.3952693,618.0140641,684.1715576,739.014375,790.2579846,951.4097518,1042.581557,33.685,35.307,36.936,38.487,39.977,41.714,43.916,46.364,48.388,49.903,51.818,54.467,3838168,4241884,4690372,5212416,5828158,6491649,6998256,7634008,8416215,9384984,10580176,12031795 +"Africa","Mauritania",743.1159097,846.1202613,1055.896036,1421.145193,1586.851781,1497.492223,1481.150189,1421.603576,1361.369784,1483.136136,1579.019543,1803.151496,40.543,42.338,44.248,46.289,48.437,50.852,53.599,56.145,58.333,60.43,62.247,64.164,1022556,1076852,1146757,1230542,1332786,1456688,1622136,1841240,2119465,2444741,2828858,3270065 +"Africa","Mauritius",1967.955707,2034.037981,2529.067487,2475.387562,2575.484158,3710.982963,3688.037739,4783.586903,6058.253846,7425.705295,9021.815894,10956.99112,50.986,58.089,60.246,61.557,62.944,64.93,66.711,68.74,69.745,70.736,71.954,72.801,516556,609816,701016,789309,851334,913025,992040,1042663,1096202,1149818,1200206,1250882 +"Africa","Morocco",1688.20357,1642.002314,1566.353493,1711.04477,1930.194975,2370.619976,2702.620356,2755.046991,2948.047252,2982.101858,3258.495584,3820.17523,42.873,45.423,47.924,50.335,52.862,55.73,59.65,62.677,65.393,67.66,69.615,71.164,9939217,11406350,13056604,14770296,16660670,18396941,20198730,22987397,25798239,28529501,31167783,33757175 +"Africa","Mozambique",468.5260381,495.5868333,556.6863539,566.6691539,724.9178037,502.3197334,462.2114149,389.8761846,410.8968239,472.3460771,633.6179466,823.6856205,31.286,33.779,36.161,38.113,40.328,42.495,42.795,42.861,44.284,46.344,44.026,42.082,6446316,7038035,7788944,8680909,9809596,11127868,12587223,12891952,13160731,16603334,18473780,19951656 +"Africa","Namibia",2423.780443,2621.448058,3173.215595,3793.694753,3746.080948,3876.485958,4191.100511,3693.731337,3804.537999,3899.52426,4072.324751,4811.060429,41.725,45.226,48.386,51.159,53.867,56.437,58.968,60.835,61.999,58.909,51.479,52.906,485831,548080,621392,706640,821782,977026,1099010,1278184,1554253,1774766,1972153,2055080 +"Africa","Niger",761.879376,835.5234025,997.7661127,1054.384891,954.2092363,808.8970728,909.7221354,668.3000228,581.182725,580.3052092,601.0745012,619.6768924,37.444,38.598,39.487,40.118,40.546,41.291,42.598,44.555,47.391,51.313,54.496,56.867,3379468,3692184,4076008,4534062,5060262,5682086,6437188,7332638,8392818,9666252,11140655,12894865 +"Africa","Nigeria",1077.281856,1100.592563,1150.927478,1014.514104,1698.388838,1981.951806,1576.97375,1385.029563,1619.848217,1624.941275,1615.286395,2013.977305,36.324,37.802,39.36,41.04,42.821,44.514,45.826,46.886,47.472,47.464,46.608,46.859,33119096,37173340,41871351,47287752,53740085,62209173,73039376,81551520,93364244,106207839,119901274,135031164 +"Africa","Reunion",2718.885295,2769.451844,3173.72334,4021.175739,5047.658563,4319.804067,5267.219353,5303.377488,6101.255823,6071.941411,6316.1652,7670.122558,52.724,55.09,57.666,60.542,64.274,67.064,69.885,71.913,73.615,74.772,75.744,76.442,257700,308700,358900,414024,461633,492095,517810,562035,622191,684810,743981,798094 +"Africa","Rwanda",493.3238752,540.2893983,597.4730727,510.9637142,590.5806638,670.0806011,881.5706467,847.991217,737.0685949,589.9445051,785.6537648,863.0884639,40,41.5,43,44.1,44.6,45,46.218,44.02,23.599,36.087,43.413,46.242,2534927,2822082,3051242,3451079,3992121,4657072,5507565,6349365,7290203,7212583,7852401,8860588 +"Africa","Sao Tome and Principe",879.5835855,860.7369026,1071.551119,1384.840593,1532.985254,1737.561657,1890.218117,1516.525457,1428.777814,1339.076036,1353.09239,1598.435089,46.471,48.945,51.893,54.425,56.48,58.55,60.351,61.728,62.742,63.306,64.337,65.528,60011,61325,65345,70787,76595,86796,98593,110812,125911,145608,170372,199579 +"Africa","Senegal",1450.356983,1567.653006,1654.988723,1612.404632,1597.712056,1561.769116,1518.479984,1441.72072,1367.899369,1392.368347,1519.635262,1712.472136,37.278,39.329,41.454,43.563,45.815,48.879,52.379,55.769,58.196,60.187,61.6,63.062,2755589,3054547,3430243,3965841,4588696,5260855,6147783,7171347,8307920,9535314,10870037,12267493 +"Africa","Sierra Leone",879.7877358,1004.484437,1116.639877,1206.043465,1353.759762,1348.285159,1465.010784,1294.447788,1068.696278,574.6481576,699.489713,862.5407561,30.331,31.57,32.767,34.113,35.4,36.788,38.445,40.006,38.333,39.897,41.012,42.568,2143249,2295678,2467895,2662190,2879013,3140897,3464522,3868905,4260884,4578212,5359092,6144562 +"Africa","Somalia",1135.749842,1258.147413,1369.488336,1284.73318,1254.576127,1450.992513,1176.807031,1093.244963,926.9602964,930.5964284,882.0818218,926.1410683,32.978,34.977,36.981,38.977,40.973,41.974,42.955,44.501,39.658,43.795,45.936,48.159,2526994,2780415,3080153,3428839,3840161,4353666,5828892,6921858,6099799,6633514,7753310,9118773 +"Africa","South Africa",4725.295531,5487.104219,5768.729717,7114.477971,7765.962636,8028.651439,8568.266228,7825.823398,7225.069258,7479.188244,7710.946444,9269.657808,45.009,47.985,49.951,51.927,53.696,55.527,58.161,60.834,61.888,60.236,53.365,49.339,14264935,16151549,18356657,20997321,23935810,27129932,31140029,35933379,39964159,42835005,44433622,43997828 +"Africa","Sudan",1615.991129,1770.337074,1959.593767,1687.997641,1659.652775,2202.988423,1895.544073,1507.819159,1492.197043,1632.210764,1993.398314,2602.394995,38.635,39.624,40.87,42.858,45.083,47.8,50.338,51.744,53.556,55.373,56.369,58.556,8504667,9753392,11183227,12716129,14597019,17104986,20367053,24725960,28227588,32160729,37090298,42292929 +"Africa","Swaziland",1148.376626,1244.708364,1856.182125,2613.101665,3364.836625,3781.410618,3895.384018,3984.839812,3553.0224,3876.76846,4128.116943,4513.480643,41.407,43.424,44.992,46.633,49.552,52.537,55.561,57.678,58.474,54.289,43.869,39.613,290243,326741,370006,420690,480105,551425,649901,779348,962344,1054486,1130269,1133066 +"Africa","Tanzania",716.6500721,698.5356073,722.0038073,848.2186575,915.9850592,962.4922932,874.2426069,831.8220794,825.682454,789.1862231,899.0742111,1107.482182,41.215,42.974,44.246,45.757,47.62,49.919,50.608,51.535,50.44,48.466,49.651,52.517,8322925,9452826,10863958,12607312,14706593,17129565,19844382,23040630,26605473,30686889,34593779,38139640 +"Africa","Togo",859.8086567,925.9083202,1067.53481,1477.59676,1649.660188,1532.776998,1344.577953,1202.201361,1034.298904,982.2869243,886.2205765,882.9699438,38.596,41.208,43.922,46.769,49.759,52.887,55.471,56.941,58.061,58.39,57.561,58.42,1219113,1357445,1528098,1735550,2056351,2308582,2644765,3154264,3747553,4320890,4977378,5701579 +"Africa","Tunisia",1468.475631,1395.232468,1660.30321,1932.360167,2753.285994,3120.876811,3560.233174,3810.419296,4332.720164,4876.798614,5722.895655,7092.923025,44.6,47.1,49.579,52.053,55.602,59.837,64.048,66.894,70.001,71.973,73.042,73.923,3647735,3950849,4286552,4786986,5303507,6005061,6734098,7724976,8523077,9231669,9770575,10276158 +"Africa","Uganda",734.753484,774.3710692,767.2717398,908.9185217,950.735869,843.7331372,682.2662268,617.7244065,644.1707969,816.559081,927.7210018,1056.380121,39.978,42.571,45.344,48.051,51.016,50.35,49.849,51.509,48.825,44.578,47.813,51.542,5824797,6675501,7688797,8900294,10190285,11457758,12939400,15283050,18252190,21210254,24739869,29170398 +"Africa","Zambia",1147.388831,1311.956766,1452.725766,1777.077318,1773.498265,1588.688299,1408.678565,1213.315116,1210.884633,1071.353818,1071.613938,1271.211593,42.038,44.077,46.023,47.768,50.107,51.386,51.821,50.821,46.1,40.238,39.193,42.384,2672000,3016000,3421000,3900000,4506497,5216550,6100407,7272406,8381163,9417789,10595811,11746035 +"Africa","Zimbabwe",406.8841148,518.7642681,527.2721818,569.7950712,799.3621758,685.5876821,788.8550411,706.1573059,693.4207856,792.4499603,672.0386227,469.7092981,48.451,50.469,52.358,53.995,55.635,57.674,60.363,62.351,60.377,46.809,39.989,43.487,3080907,3646340,4277736,4995432,5861135,6642107,7636524,9216418,10704340,11404948,11926563,12311143 +"Americas","Argentina",5911.315053,6856.856212,7133.166023,8052.953021,9443.038526,10079.02674,8997.897412,9139.671389,9308.41871,10967.28195,8797.640716,12779.37964,62.485,64.399,65.142,65.634,67.065,68.481,69.942,70.774,71.868,73.275,74.34,75.32,17876956,19610538,21283783,22934225,24779799,26983828,29341374,31620918,33958947,36203463,38331121,40301927 +"Americas","Bolivia",2677.326347,2127.686326,2180.972546,2586.886053,2980.331339,3548.097832,3156.510452,2753.69149,2961.699694,3326.143191,3413.26269,3822.137084,40.414,41.89,43.428,45.032,46.714,50.023,53.859,57.251,59.957,62.05,63.883,65.554,2883315,3211738,3593918,4040665,4565872,5079716,5642224,6156369,6893451,7693188,8445134,9119152 +"Americas","Brazil",2108.944355,2487.365989,3336.585802,3429.864357,4985.711467,6660.118654,7030.835878,7807.095818,6950.283021,7957.980824,8131.212843,9065.800825,50.917,53.285,55.665,57.632,59.504,61.489,63.336,65.205,67.057,69.388,71.006,72.39,56602560,65551171,76039390,88049823,100840058,114313951,128962939,142938076,155975974,168546719,179914212,190010647 +"Americas","Canada",11367.16112,12489.95006,13462.48555,16076.58803,18970.57086,22090.88306,22898.79214,26626.51503,26342.88426,28954.92589,33328.96507,36319.23501,68.75,69.96,71.3,72.13,72.88,74.21,75.76,76.86,77.95,78.61,79.77,80.653,14785584,17010154,18985849,20819767,22284500,23796400,25201900,26549700,28523502,30305843,31902268,33390141 +"Americas","Chile",3939.978789,4315.622723,4519.094331,5106.654313,5494.024437,4756.763836,5095.665738,5547.063754,7596.125964,10118.05318,10778.78385,13171.63885,54.745,56.074,57.924,60.523,63.441,67.052,70.565,72.492,74.126,75.816,77.86,78.553,6377619,7048426,7961258,8858908,9717524,10599793,11487112,12463354,13572994,14599929,15497046,16284741 +"Americas","Colombia",2144.115096,2323.805581,2492.351109,2678.729839,3264.660041,3815.80787,4397.575659,4903.2191,5444.648617,6117.361746,5755.259962,7006.580419,50.643,55.118,57.863,59.963,61.623,63.837,66.653,67.768,68.421,70.313,71.682,72.889,12350771,14485993,17009885,19764027,22542890,25094412,27764644,30964245,34202721,37657830,41008227,44227550 +"Americas","Costa Rica",2627.009471,2990.010802,3460.937025,4161.727834,5118.146939,5926.876967,5262.734751,5629.915318,6160.416317,6677.045314,7723.447195,9645.06142,57.206,60.026,62.842,65.424,67.849,70.75,73.45,74.752,75.713,77.26,78.123,78.782,926317,1112300,1345187,1588717,1834796,2108457,2424367,2799811,3173216,3518107,3834934,4133884 +"Americas","Cuba",5586.53878,6092.174359,5180.75591,5690.268015,5305.445256,6380.494966,7316.918107,7532.924763,5592.843963,5431.990415,6340.646683,8948.102923,59.421,62.325,65.246,68.29,70.723,72.649,73.717,74.174,74.414,76.151,77.158,78.273,6007797,6640752,7254373,8139332,8831348,9537988,9789224,10239839,10723260,10983007,11226999,11416987 +"Americas","Dominican Republic",1397.717137,1544.402995,1662.137359,1653.723003,2189.874499,2681.9889,2861.092386,2899.842175,3044.214214,3614.101285,4563.808154,6025.374752,45.928,49.828,53.459,56.751,59.631,61.788,63.727,66.046,68.457,69.957,70.847,72.235,2491346,2923186,3453434,4049146,4671329,5302800,5968349,6655297,7351181,7992357,8650322,9319622 +"Americas","Ecuador",3522.110717,3780.546651,4086.114078,4579.074215,5280.99471,6679.62326,7213.791267,6481.776993,7103.702595,7429.455877,5773.044512,6873.262326,48.357,51.356,54.64,56.678,58.796,61.31,64.342,67.231,69.613,72.312,74.173,74.994,3548753,4058385,4681707,5432424,6298651,7278866,8365850,9545158,10748394,11911819,12921234,13755680 +"Americas","El Salvador",3048.3029,3421.523218,3776.803627,4358.595393,4520.246008,5138.922374,4098.344175,4140.442097,4444.2317,5154.825496,5351.568666,5728.353514,45.262,48.57,52.307,55.855,58.207,56.696,56.604,63.154,66.798,69.535,70.734,71.878,2042865,2355805,2747687,3232927,3790903,4282586,4474873,4842194,5274649,5783439,6353681,6939688 +"Americas","Guatemala",2428.237769,2617.155967,2750.364446,3242.531147,4031.408271,4879.992748,4820.49479,4246.485974,4439.45084,4684.313807,4858.347495,5186.050003,42.023,44.142,46.954,50.016,53.738,56.029,58.137,60.782,63.373,66.322,68.978,70.259,3146381,3640876,4208858,4690773,5149581,5703430,6395630,7326406,8486949,9803875,11178650,12572928 +"Americas","Haiti",1840.366939,1726.887882,1796.589032,1452.057666,1654.456946,1874.298931,2011.159549,1823.015995,1456.309517,1341.726931,1270.364932,1201.637154,37.579,40.696,43.59,46.243,48.042,49.923,51.461,53.636,55.089,56.671,58.137,60.916,3201488,3507701,3880130,4318137,4698301,4908554,5198399,5756203,6326682,6913545,7607651,8502814 +"Americas","Honduras",2194.926204,2220.487682,2291.156835,2538.269358,2529.842345,3203.208066,3121.760794,3023.096699,3081.694603,3160.454906,3099.72866,3548.330846,41.912,44.665,48.041,50.924,53.884,57.402,60.909,64.492,66.399,67.659,68.565,70.198,1517453,1770390,2090162,2500689,2965146,3055235,3669448,4372203,5077347,5867957,6677328,7483763 +"Americas","Jamaica",2898.530881,4756.525781,5246.107524,6124.703451,7433.889293,6650.195573,6068.05135,6351.237495,7404.923685,7121.924704,6994.774861,7320.880262,58.53,62.61,65.61,67.51,69,70.11,71.21,71.77,71.766,72.262,72.047,72.567,1426095,1535090,1665128,1861096,1997616,2156814,2298309,2326606,2378618,2531311,2664659,2780132 +"Americas","Mexico",3478.125529,4131.546641,4581.609385,5754.733883,6809.40669,7674.929108,9611.147541,8688.156003,9472.384295,9767.29753,10742.44053,11977.57496,50.789,55.19,58.299,60.11,62.361,65.032,67.405,69.498,71.455,73.67,74.902,76.195,30144317,35015548,41121485,47995559,55984294,63759976,71640904,80122492,88111030,95895146,102479927,108700891 +"Americas","Nicaragua",3112.363948,3457.415947,3634.364406,4643.393534,4688.593267,5486.371089,3470.338156,2955.984375,2170.151724,2253.023004,2474.548819,2749.320965,42.314,45.432,48.632,51.884,55.151,57.47,59.298,62.008,65.843,68.426,70.836,72.899,1165790,1358828,1590597,1865490,2182908,2554598,2979423,3344353,4017939,4609572,5146848,5675356 +"Americas","Panama",2480.380334,2961.800905,3536.540301,4421.009084,5364.249663,5351.912144,7009.601598,7034.779161,6618.74305,7113.692252,7356.031934,9809.185636,55.191,59.201,61.817,64.071,66.216,68.681,70.472,71.523,72.462,73.738,74.712,75.537,940080,1063506,1215725,1405486,1616384,1839782,2036305,2253639,2484997,2734531,2990875,3242173 +"Americas","Paraguay",1952.308701,2046.154706,2148.027146,2299.376311,2523.337977,3248.373311,4258.503604,3998.875695,4196.411078,4247.400261,3783.674243,4172.838464,62.649,63.196,64.361,64.951,65.815,66.353,66.874,67.378,68.225,69.4,70.755,71.752,1555876,1770902,2009813,2287985,2614104,2984494,3366439,3886512,4483945,5154123,5884491,6667147 +"Americas","Peru",3758.523437,4245.256698,4957.037982,5788.09333,5937.827283,6281.290855,6434.501797,6360.943444,4446.380924,5838.347657,5909.020073,7408.905561,43.902,46.263,49.096,51.445,55.448,58.447,61.406,64.134,66.458,68.386,69.906,71.421,8025700,9146100,10516500,12132200,13954700,15990099,18125129,20195924,22430449,24748122,26769436,28674757 +"Americas","Puerto Rico",3081.959785,3907.156189,5108.34463,6929.277714,9123.041742,9770.524921,10330.98915,12281.34191,14641.58711,16999.4333,18855.60618,19328.70901,64.28,68.54,69.62,71.1,72.16,73.44,73.75,74.63,73.911,74.917,77.778,78.746,2227000,2260000,2448046,2648961,2847132,3080828,3279001,3444468,3585176,3759430,3859606,3942491 +"Americas","Trinidad and Tobago",3023.271928,4100.3934,4997.523971,5621.368472,6619.551419,7899.554209,9119.528607,7388.597823,7370.990932,8792.573126,11460.60023,18008.50924,59.1,61.8,64.9,65.4,65.9,68.3,68.832,69.582,69.862,69.465,68.976,69.819,662850,764900,887498,960155,975199,1039009,1116479,1191336,1183669,1138101,1101832,1056608 +"Americas","United States",13990.48208,14847.12712,16173.14586,19530.36557,21806.03594,24072.63213,25009.55914,29884.35041,32003.93224,35767.43303,39097.09955,42951.65309,68.44,69.49,70.21,70.76,71.34,73.38,74.65,75.02,76.09,76.81,77.31,78.242,157553000,171984000,186538000,198712000,209896000,220239000,232187835,242803533,256894189,272911760,287675526,301139947 +"Americas","Uruguay",5716.766744,6150.772969,5603.357717,5444.61962,5703.408898,6504.339663,6920.223051,7452.398969,8137.004775,9230.240708,7727.002004,10611.46299,66.071,67.044,68.253,68.468,68.673,69.481,70.805,71.918,72.752,74.223,75.307,76.384,2252965,2424959,2598466,2748579,2829526,2873520,2953997,3045153,3149262,3262838,3363085,3447496 +"Americas","Venezuela",7689.799761,9802.466526,8422.974165,9541.474188,10505.25966,13143.95095,11152.41011,9883.584648,10733.92631,10165.49518,8605.047831,11415.80569,55.088,57.907,60.77,63.479,65.712,67.456,68.557,70.19,71.15,72.146,72.766,73.747,5439568,6702668,8143375,9709552,11515649,13503563,15620766,17910182,20265563,22374398,24287670,26084662 +"Asia","Afghanistan",779.4453145,820.8530296,853.10071,836.1971382,739.9811058,786.11336,978.0114388,852.3959448,649.3413952,635.341351,726.7340548,974.5803384,28.801,30.332,31.997,34.02,36.088,38.438,39.854,40.822,41.674,41.763,42.129,43.828,8425333,9240934,10267083,11537966,13079460,14880372,12881816,13867957,16317921,22227415,25268405,31889923 +"Asia","Bahrain",9867.084765,11635.79945,12753.27514,14804.6727,18268.65839,19340.10196,19211.14731,18524.02406,19035.57917,20292.01679,23403.55927,29796.04834,50.939,53.832,56.923,59.923,63.3,65.593,69.052,70.75,72.601,73.925,74.795,75.635,120447,138655,171863,202182,230800,297410,377967,454612,529491,598561,656397,708573 +"Asia","Bangladesh",684.2441716,661.6374577,686.3415538,721.1860862,630.2336265,659.8772322,676.9818656,751.9794035,837.8101643,972.7700352,1136.39043,1391.253792,37.484,39.348,41.216,43.453,45.252,46.923,50.009,52.819,56.018,59.412,62.013,64.062,46886859,51365468,56839289,62821884,70759295,80428306,93074406,103764241,113704579,123315288,135656790,150448339 +"Asia","Cambodia",368.4692856,434.0383364,496.9136476,523.4323142,421.6240257,524.9721832,624.4754784,683.8955732,682.3031755,734.28517,896.2260153,1713.778686,39.417,41.366,43.415,45.415,40.317,31.22,50.957,53.914,55.803,56.534,56.752,59.723,4693836,5322536,6083619,6960067,7450606,6978607,7272485,8371791,10150094,11782962,12926707,14131858 +"Asia","China",400.448610699994,575.9870009,487.6740183,612.7056934,676.9000921,741.2374699,962.4213805,1378.904018,1655.784158,2289.234136,3119.280896,4959.114854,44,50.54896,44.50136,58.38112,63.11888,63.96736,65.525,67.274,68.69,70.426,72.028,72.961,556263527.999989,637408000,665770000,754550000,862030000,943455000,1000281000,1084035000,1164970000,1230075000,1280400000,1318683096 +"Asia","Hong Kong China",3054.421209,3629.076457,4692.648272,6197.962814,8315.928145,11186.14125,14560.53051,20038.47269,24757.60301,28377.63219,30209.01516,39724.97867,60.96,64.75,67.65,70,72,73.6,75.45,76.2,77.601,80,81.495,82.208,2125900,2736300,3305200,3722800,4115700,4583700,5264500,5584510,5829696,6495918,6762476,6980412 +"Asia","India",546.5657493,590.061996,658.3471509,700.7706107,724.032527,813.337323,855.7235377,976.5126756,1164.406809,1458.817442,1746.769454,2452.210407,37.373,40.249,43.605,47.193,50.651,54.208,56.596,58.553,60.223,61.765,62.879,64.698,3.72e+08,4.09e+08,4.54e+08,5.06e+08,5.67e+08,6.34e+08,7.08e+08,7.88e+08,8.72e+08,9.59e+08,1034172547,1110396331 +"Asia","Indonesia",749.6816546,858.9002707,849.2897701,762.4317721,1111.107907,1382.702056,1516.872988,1748.356961,2383.140898,3119.335603,2873.91287,3540.651564,37.468,39.918,42.518,45.964,49.203,52.702,56.159,60.137,62.681,66.041,68.588,70.65,82052000,90124000,99028000,109343000,121282000,136725000,153343000,169276000,184816000,199278000,211060000,223547000 +"Asia","Iran",3035.326002,3290.257643,4187.329802,5906.731805,9613.818607,11888.59508,7608.334602,6642.881371,7235.653188,8263.590301,9240.761975,11605.71449,44.869,47.181,49.325,52.469,55.234,57.702,59.62,63.04,65.742,68.042,69.451,70.964,17272000,19792000,22874000,26538000,30614000,35480679,43072751,51889696,60397973,63327987,66907826,69453570 +"Asia","Iraq",4129.766056,6229.333562,8341.737815,8931.459811,9576.037596,14688.23507,14517.90711,11643.57268,3745.640687,3076.239795,4390.717312,4471.061906,45.32,48.437,51.457,54.459,56.95,60.413,62.038,65.044,59.461,58.811,57.046,59.545,5441766,6248643,7240260,8519282,10061506,11882916,14173318,16543189,17861905,20775703,24001816,27499638 +"Asia","Israel",4086.522128,5385.278451,7105.630706,8393.741404,12786.93223,13306.61921,15367.0292,17122.47986,18051.52254,20896.60924,21905.59514,25523.2771,65.39,67.84,69.39,70.75,71.63,73.06,74.45,75.6,76.93,78.269,79.696,80.745,1620914,1944401,2310904,2693585,3095893,3495918,3858421,4203148,4936550,5531387,6029529,6426679 +"Asia","Japan",3216.956347,4317.694365,6576.649461,9847.788607,14778.78636,16610.37701,19384.10571,22375.94189,26824.89511,28816.58499,28604.5919,31656.06806,63.03,65.5,68.73,71.43,73.42,75.38,77.11,78.67,79.36,80.69,82,82.603,86459025,91563009,95831757,100825279,107188273,113872473,118454974,122091325,124329269,125956499,127065841,127467972 +"Asia","Jordan",1546.907807,1886.080591,2348.009158,2741.796252,2110.856309,2852.351568,4161.415959,4448.679912,3431.593647,3645.379572,3844.917194,4519.461171,43.158,45.669,48.126,51.629,56.528,61.134,63.739,65.869,68.015,69.772,71.263,72.535,607914,746559,933559,1255058,1613551,1937652,2347031,2820042,3867409,4526235,5307470,6053193 +"Asia","Korea Dem. Rep.",1088.277758,1571.134655,1621.693598,2143.540609,3701.621503,4106.301249,4106.525293,4106.492315,3726.063507,1690.756814,1646.758151,1593.06548,50.056,54.081,56.656,59.942,63.983,67.159,69.1,70.647,69.978,67.727,66.662,67.297,8865488,9411381,10917494,12617009,14781241,16325320,17647518,19067554,20711375,21585105,22215365,23301725 +"Asia","Korea Rep.",1030.592226,1487.593537,1536.344387,2029.228142,3030.87665,4657.22102,5622.942464,8533.088805,12104.27872,15993.52796,19233.98818,23348.13973,47.453,52.681,55.292,57.716,62.612,64.766,67.123,69.81,72.244,74.647,77.045,78.623,20947571,22611552,26420307,30131000,33505000,36436000,39326000,41622000,43805450,46173816,47969150,49044790 +"Asia","Kuwait",108382.3529,113523.1329,95458.11176,80894.88326,109347.867,59265.47714,31354.03573,28118.42998,34932.91959,40300.61996,35110.10566,47306.98978,55.565,58.033,60.47,64.624,67.712,69.343,71.309,74.174,75.19,76.156,76.904,77.588,160000,212846,358266,575003,841934,1140357,1497494,1891487,1418095,1765345,2111561,2505559 +"Asia","Lebanon",4834.804067,6089.786934,5714.560611,6006.983042,7486.384341,8659.696836,7640.519521,5377.091329,6890.806854,8754.96385,9313.93883,10461.05868,55.928,59.489,62.094,63.87,65.421,66.099,66.983,67.926,69.292,70.265,71.028,71.993,1439529,1647412,1886848,2186894,2680018,3115787,3086876,3089353,3219994,3430388,3677780,3921278 +"Asia","Malaysia",1831.132894,1810.066992,2036.884944,2277.742396,2849.09478,3827.921571,4920.355951,5249.802653,7277.912802,10132.90964,10206.97794,12451.6558,48.463,52.102,55.737,59.371,63.01,65.256,68,69.5,70.693,71.938,73.044,74.241,6748378,7739235,8906385,10154878,11441462,12845381,14441916,16331785,18319502,20476091,22662365,24821286 +"Asia","Mongolia",786.5668575,912.6626085,1056.353958,1226.04113,1421.741975,1647.511665,2000.603139,2338.008304,1785.402016,1902.2521,2140.739323,3095.772271,42.244,45.248,48.251,51.253,53.754,55.491,57.489,60.222,61.271,63.625,65.033,66.803,800663,882134,1010280,1149500,1320500,1528000,1756032,2015133,2312802,2494803,2674234,2874127 +"Asia","Myanmar",331,350,388,349,357,371,424,385,347,415,611,944,36.319,41.905,45.108,49.379,53.07,56.059,58.056,58.339,59.32,60.328,59.908,62.069,20092996,21731844,23634436,25870271,28466390,31528087,34680442,38028578,40546538,43247867,45598081,47761980 +"Asia","Nepal",545.8657229,597.9363558,652.3968593,676.4422254,674.7881296,694.1124398,718.3730947,775.6324501,897.7403604,1010.892138,1057.206311,1091.359778,36.157,37.686,39.393,41.472,43.971,46.748,49.594,52.537,55.727,59.426,61.34,63.785,9182536,9682338,10332057,11261690,12412593,13933198,15796314,17917180,20326209,23001113,25873917,28901790 +"Asia","Oman",1828.230307,2242.746551,2924.638113,4720.942687,10618.03855,11848.34392,12954.79101,18115.22313,18616.70691,19702.05581,19774.83687,22316.19287,37.578,40.08,43.165,46.988,52.143,57.367,62.728,67.734,71.197,72.499,74.193,75.64,507833,561977,628164,714775,829050,1004533,1301048,1593882,1915208,2283635,2713462,3204897 +"Asia","Pakistan",684.5971438,747.0835292,803.3427418,942.4082588,1049.938981,1175.921193,1443.429832,1704.686583,1971.829464,2049.350521,2092.712441,2605.94758,43.436,45.557,47.67,49.8,51.929,54.043,56.158,58.245,60.838,61.818,63.61,65.483,41346560,46679944,53100671,60641899,69325921,78152686,91462088,105186881,120065004,135564834,153403524,169270617 +"Asia","Philippines",1272.880995,1547.944844,1649.552153,1814.12743,1989.37407,2373.204287,2603.273765,2189.634995,2279.324017,2536.534925,2650.921068,3190.481016,47.752,51.334,54.757,56.393,58.065,60.06,62.082,64.151,66.458,68.564,70.303,71.688,22438691,26072194,30325264,35356600,40850141,46850962,53456774,60017788,67185766,75012988,82995088,91077287 +"Asia","Saudi Arabia",6459.554823,8157.591248,11626.41975,16903.04886,24837.42865,34167.7626,33693.17525,21198.26136,24841.61777,20586.69019,19014.54118,21654.83194,39.875,42.868,45.914,49.901,53.886,58.69,63.012,66.295,68.768,70.533,71.626,72.777,4005677,4419650,4943029,5618198,6472756,8128505,11254672,14619745,16945857,21229759,24501530,27601038 +"Asia","Singapore",2315.138227,2843.104409,3674.735572,4977.41854,8597.756202,11210.08948,15169.16112,18861.53081,24769.8912,33519.4766,36023.1054,47143.17964,60.396,63.179,65.798,67.946,69.521,70.795,71.76,73.56,75.788,77.158,78.77,79.972,1127000,1445929,1750200,1977600,2152400,2325300,2651869,2794552,3235865,3802309,4197776,4553009 +"Asia","Sri Lanka",1083.53203,1072.546602,1074.47196,1135.514326,1213.39553,1348.775651,1648.079789,1876.766827,2153.739222,2664.477257,3015.378833,3970.095407,57.593,61.456,62.192,64.266,65.042,65.949,68.757,69.011,70.379,70.457,70.815,72.396,7982342,9128546,10421936,11737396,13016733,14116836,15410151,16495304,17587060,18698655,19576783,20378239 +"Asia","Syria",1643.485354,2117.234893,2193.037133,1881.923632,2571.423014,3195.484582,3761.837715,3116.774285,3340.542768,4014.238972,4090.925331,4184.548089,45.883,48.284,50.305,53.655,57.296,61.195,64.59,66.974,69.249,71.527,73.053,74.143,3661549,4149908,4834621,5680812,6701172,7932503,9410494,11242847,13219062,15081016,17155814,19314747 +"Asia","Taiwan",1206.947913,1507.86129,1822.879028,2643.858681,4062.523897,5596.519826,7426.354774,11054.56175,15215.6579,20206.82098,23235.42329,28718.27684,58.5,62.4,65.2,67.5,69.39,70.59,72.16,73.4,74.26,75.25,76.99,78.4,8550362,10164215,11918938,13648692,15226039,16785196,18501390,19757799,20686918,21628605,22454239,23174294 +"Asia","Thailand",757.7974177,793.5774148,1002.199172,1295.46066,1524.358936,1961.224635,2393.219781,2982.653773,4616.896545,5852.625497,5913.187529,7458.396327,50.848,53.63,56.061,58.285,60.405,62.494,64.597,66.084,67.298,67.521,68.564,70.616,21289402,25041917,29263397,34024249,39276153,44148285,48827160,52910342,56667095,60216677,62806748,65068149 +"Asia","Vietnam",605.0664917,676.2854478,772.0491602,637.1232887,699.5016441,713.5371196,707.2357863,820.7994449,989.0231487,1385.896769,1764.456677,2441.576404,40.412,42.887,45.363,47.838,50.254,55.764,58.816,62.82,67.662,70.672,73.017,74.249,26246839,28998543,33796140,39463910,44655014,50533506,56142181,62826491,69940728,76048996,80908147,85262356 +"Asia","West Bank and Gaza",1515.592329,1827.067742,2198.956312,2649.715007,3133.409277,3682.831494,4336.032082,5107.197384,6017.654756,7110.667619,4515.487575,3025.349798,43.16,45.671,48.127,51.631,56.532,60.765,64.406,67.046,69.718,71.096,72.37,73.422,1030585,1070439,1133134,1142636,1089572,1261091,1425876,1691210,2104779,2826046,3389578,4018332 +"Asia","Yemen Rep.",781.7175761,804.8304547,825.6232006,862.4421463,1265.047031,1829.765177,1977.55701,1971.741538,1879.496673,2117.484526,2234.820827,2280.769906,32.548,33.97,35.18,36.984,39.848,44.175,49.113,52.922,55.599,58.02,60.308,62.698,4963829,5498090,6120081,6740785,7407075,8403990,9657618,11219340,13367997,15826497,18701257,22211743 +"Europe","Albania",1601.056136,1942.284244,2312.888958,2760.196931,3313.422188,3533.00391,3630.880722,3738.932735,2497.437901,3193.054604,4604.211737,5937.029526,55.23,59.28,64.82,66.22,67.69,68.93,70.42,72,71.581,72.95,75.651,76.423,1282697,1476505,1728137,1984060,2263554,2509048,2780097,3075321,3326498,3428038,3508512,3600523 +"Europe","Austria",6137.076492,8842.59803,10750.72111,12834.6024,16661.6256,19749.4223,21597.08362,23687.82607,27042.01868,29095.92066,32417.60769,36126.4927,66.8,67.48,69.54,70.14,70.63,72.17,73.18,74.94,76.04,77.51,78.98,79.829,6927772,6965860,7129864,7376998,7544201,7568430,7574613,7578903,7914969,8069876,8148312,8199783 +"Europe","Belgium",8343.105127,9714.960623,10991.20676,13149.04119,16672.14356,19117.97448,20979.84589,22525.56308,25575.57069,27561.19663,30485.88375,33692.60508,68,69.24,70.25,70.94,71.44,72.8,73.93,75.35,76.46,77.53,78.32,79.441,8730405,8989111,9218400,9556500,9709100,9821800,9856303,9870200,10045622,10199787,10311970,10392226 +"Europe","Bosnia and Herzegovina",973.5331948,1353.989176,1709.683679,2172.352423,2860.16975,3528.481305,4126.613157,4314.114757,2546.781445,4766.355904,6018.975239,7446.298803,53.82,58.45,61.93,64.79,67.45,69.86,70.69,71.14,72.178,73.244,74.09,74.852,2791000,3076000,3349000,3585000,3819000,4086000,4172693,4338977,4256013,3607000,4165416,4552198 +"Europe","Bulgaria",2444.286648,3008.670727,4254.337839,5577.0028,6597.494398,7612.240438,8224.191647,8239.854824,6302.623438,5970.38876,7696.777725,10680.79282,59.6,66.61,69.51,70.42,70.9,70.81,71.08,71.34,71.19,70.32,72.14,73.005,7274900,7651254,8012946,8310226,8576200,8797022,8892098,8971958,8658506,8066057,7661799,7322858 +"Europe","Croatia",3119.23652,4338.231617,5477.890018,6960.297861,9164.090127,11305.38517,13221.82184,13822.58394,8447.794873,9875.604515,11628.38895,14619.22272,61.21,64.77,67.13,68.5,69.61,70.64,70.46,71.52,72.527,73.68,74.876,75.748,3882229,3991242,4076557,4174366,4225310,4318673,4413368,4484310,4494013,4444595,4481020,4493312 +"Europe","Czech Republic",6876.14025,8256.343918,10136.86713,11399.44489,13108.4536,14800.16062,15377.22855,16310.4434,14297.02122,16048.51424,17596.21022,22833.30851,66.87,69.03,69.9,70.38,70.29,70.71,70.96,71.58,72.4,74.01,75.51,76.486,9125183,9513758,9620282,9835109,9862158,10161915,10303704,10311597,10315702,10300707,10256295,10228744 +"Europe","Denmark",9692.385245,11099.65935,13583.31351,15937.21123,18866.20721,20422.9015,21688.04048,25116.17581,26406.73985,29804.34567,32166.50006,35278.41874,70.78,71.81,72.35,72.96,73.47,74.69,74.63,74.8,75.33,76.11,77.18,78.332,4334000,4487831,4646899,4838800,4991596,5088419,5117810,5127024,5171393,5283663,5374693,5468120 +"Europe","Finland",6424.519071,7545.415386,9371.842561,10921.63626,14358.8759,15605.42283,18533.15761,21141.01223,20647.16499,23723.9502,28204.59057,33207.0844,66.55,67.49,68.75,69.83,70.87,72.52,74.55,74.83,75.7,77.13,78.37,79.313,4090500,4324000,4491443,4605744,4639657,4738902,4826933,4931729,5041039,5134406,5193039,5238460 +"Europe","France",7029.809327,8662.834898,10560.48553,12999.91766,16107.19171,18292.63514,20293.89746,22066.44214,24703.79615,25889.78487,28926.03234,30470.0167,67.41,68.93,70.51,71.55,72.38,73.83,74.89,76.34,77.46,78.64,79.59,80.657,42459667,44310863,47124000,49569000,51732000,53165019,54433565,55630100,57374179,58623428,59925035,61083916 +"Europe","Germany",7144.114393,10187.82665,12902.46291,14745.62561,18016.18027,20512.92123,22031.53274,24639.18566,26505.30317,27788.88416,30035.80198,32170.37442,67.5,69.1,70.3,70.8,71,72.5,73.8,74.847,76.07,77.34,78.67,79.406,69145952,71019069,73739117,76368453,78717088,78160773,78335266,77718298,80597764,82011073,82350671,82400996 +"Europe","Greece",3530.690067,4916.299889,6017.190733,8513.097016,12724.82957,14195.52428,15268.42089,16120.52839,17541.49634,18747.69814,22514.2548,27538.41188,65.86,67.86,69.51,71,72.34,73.68,75.24,76.67,77.03,77.869,78.256,79.483,7733250,8096218,8448233,8716441,8888628,9308479,9786480,9974490,10325429,10502372,10603863,10706290 +"Europe","Hungary",5263.673816,6040.180011,7550.359877,9326.64467,10168.65611,11674.83737,12545.99066,12986.47998,10535.62855,11712.7768,14843.93556,18008.94444,64.03,66.41,67.96,69.5,69.76,69.95,69.39,69.58,69.17,71.04,72.59,73.338,9504000,9839000,10063000,10223422,10394091,10637171,10705535,10612740,10348684,10244684,10083313,9956108 +"Europe","Iceland",7267.688428,9244.001412,10350.15906,13319.89568,15798.06362,19654.96247,23269.6075,26923.20628,25144.39201,28061.09966,31163.20196,36180.78919,72.49,73.47,73.68,73.73,74.46,76.11,76.99,77.23,78.77,78.95,80.5,81.757,147962,165110,182053,198676,209275,221823,233997,244676,259012,271192,288030,301931 +"Europe","Ireland",5210.280328,5599.077872,6631.597314,7655.568963,9530.772896,11150.98113,12618.32141,13872.86652,17558.81555,24521.94713,34077.04939,40675.99635,66.91,68.9,70.29,71.08,71.28,72.03,73.1,74.36,75.467,76.122,77.783,78.885,2952156,2878220,2830000,2900100,3024400,3271900,3480000,3539900,3557761,3667233,3879155,4109086 +"Europe","Italy",4931.404155,6248.656232,8243.58234,10022.40131,12269.27378,14255.98475,16537.4835,19207.23482,22013.64486,24675.02446,27968.09817,28569.7197,65.94,67.81,69.24,71.06,72.19,73.48,74.98,76.42,77.44,78.82,80.24,80.546,47666000,49182000,50843200,52667100,54365564,56059245,56535636,56729703,56840847,57479469,57926999,58147733 +"Europe","Montenegro",2647.585601,3682.259903,4649.593785,5907.850937,7778.414017,9595.929905,11222.58762,11732.51017,7003.339037,6465.613349,6557.194282,9253.896111,59.164,61.448,63.728,67.178,70.636,73.066,74.101,74.865,75.435,75.445,73.981,74.543,413834,442829,474528,501035,527678,560073,562548,569473,621621,692651,720230,684736 +"Europe","Netherlands",8941.571858,11276.19344,12790.84956,15363.25136,18794.74567,21209.0592,21399.46046,23651.32361,26790.94961,30246.13063,33724.75778,36797.93332,72.13,72.99,73.23,73.82,73.75,75.24,76.05,76.83,77.42,78.03,78.53,79.762,10381988,11026383,11805689,12596822,13329874,13852989,14310401,14665278,15174244,15604464,16122830,16570613 +"Europe","Norway",10095.42172,11653.97304,13450.40151,16361.87647,18965.05551,23311.34939,26298.63531,31540.9748,33965.66115,41283.16433,44683.97525,49357.19017,72.67,73.44,73.47,74.08,74.34,75.37,75.97,75.89,77.32,78.32,79.05,80.196,3327728,3491938,3638919,3786019,3933004,4043205,4114787,4186147,4286357,4405672,4535591,4627926 +"Europe","Poland",4029.329699,4734.253019,5338.752143,6557.152776,8006.506993,9508.141454,8451.531004,9082.351172,7738.881247,10159.58368,12002.23908,15389.92468,61.31,65.77,67.64,69.61,70.85,70.67,71.32,70.98,70.99,72.75,74.67,75.563,25730551,28235346,30329617,31785378,33039545,34621254,36227381,37740710,38370697,38654957,38625976,38518241 +"Europe","Portugal",3068.319867,3774.571743,4727.954889,6361.517993,9022.247417,10172.48572,11753.84291,13039.30876,16207.26663,17641.03156,19970.90787,20509.64777,59.82,61.51,64.39,66.6,69.26,70.41,72.77,74.06,74.86,75.97,77.29,78.098,8526050,8817650,9019800,9103000,8970450,9662600,9859650,9915289,9927680,10156415,10433867,10642836 +"Europe","Romania",3144.613186,3943.370225,4734.997586,6470.866545,8011.414402,9356.39724,9605.314053,9696.273295,6598.409903,7346.547557,7885.360081,10808.47561,61.05,64.1,66.8,66.8,69.21,69.46,69.66,69.53,69.36,69.72,71.322,72.476,16630000,17829327,18680721,19284814,20662648,21658597,22356726,22686371,22797027,22562458,22404337,22276056 +"Europe","Serbia",3581.459448,4981.090891,6289.629157,7991.707066,10522.06749,12980.66956,15181.0927,15870.87851,9325.068238,7914.320304,7236.075251,9786.534714,57.996,61.685,64.531,66.914,68.7,70.3,70.162,71.218,71.659,72.232,73.213,74.002,6860147,7271135,7616060,7971222,8313288,8686367,9032824,9230783,9826397,10336594,10111559,10150265 +"Europe","Slovak Republic",5074.659104,6093.26298,7481.107598,8412.902397,9674.167626,10922.66404,11348.54585,12037.26758,9498.467723,12126.23065,13638.77837,18678.31435,64.36,67.45,70.33,70.98,70.35,70.45,70.8,71.08,71.38,72.71,73.8,74.663,3558137,3844277,4237384,4442238,4593433,4827803,5048043,5199318,5302888,5383010,5410052,5447502 +"Europe","Slovenia",4215.041741,5862.276629,7402.303395,9405.489397,12383.4862,15277.03017,17866.72175,18678.53492,14214.71681,17161.10735,20660.01936,25768.25759,65.57,67.85,69.15,69.18,69.82,70.97,71.063,72.25,73.64,75.13,76.66,77.926,1489518,1533070,1582962,1646912,1694510,1746919,1861252,1945870,1999210,2011612,2011497,2009245 +"Europe","Spain",3834.034742,4564.80241,5693.843879,7993.512294,10638.75131,13236.92117,13926.16997,15764.98313,18603.06452,20445.29896,24835.47166,28821.0637,64.94,66.66,69.69,71.44,73.06,74.39,76.3,76.9,77.57,78.77,79.78,80.941,28549870,29841614,31158061,32850275,34513161,36439000,37983310,38880702,39549438,39855442,40152517,40448191 +"Europe","Sweden",8527.844662,9911.878226,12329.44192,15258.29697,17832.02464,18855.72521,20667.38125,23586.92927,23880.01683,25266.59499,29341.63093,33859.74835,71.86,72.49,73.37,74.16,74.72,75.44,76.42,77.19,78.16,79.39,80.04,80.884,7124673,7363802,7561588,7867931,8122293,8251648,8325260,8421403,8718867,8897619,8954175,9031088 +"Europe","Switzerland",14734.23275,17909.48973,20431.0927,22966.14432,27195.11304,26982.29052,28397.71512,30281.70459,31871.5303,32135.32301,34480.95771,37506.41907,69.62,70.56,71.32,72.77,73.78,75.39,76.21,77.41,78.03,79.37,80.62,81.701,4815000,5126000,5666000,6063000,6401400,6316424,6468126,6649942,6995447,7193761,7361757,7554661 +"Europe","Turkey",1969.10098,2218.754257,2322.869908,2826.356387,3450.69638,4269.122326,4241.356344,5089.043686,5678.348271,6601.429915,6508.085718,8458.276384,43.585,48.079,52.098,54.336,57.005,59.507,61.036,63.108,66.146,68.835,70.845,71.777,22235677,25670939,29788695,33411317,37492953,42404033,47328791,52881328,58179144,63047647,67308928,71158647 +"Europe","United Kingdom",9979.508487,11283.17795,12477.17707,14142.85089,15895.11641,17428.74846,18232.42452,21664.78767,22705.09254,26074.53136,29478.99919,33203.26128,69.18,70.42,70.76,71.36,72.01,72.76,74.04,75.007,76.42,77.218,78.471,79.425,50430000,51430000,53292000,54959000,56079000,56179000,56339704,56981620,57866349,58808266,59912431,60776238 +"Oceania","Australia",10039.59564,10949.64959,12217.22686,14526.12465,16788.62948,18334.19751,19477.00928,21888.88903,23424.76683,26997.93657,30687.75473,34435.36744,69.12,70.33,70.93,71.1,71.93,73.49,74.74,76.32,77.56,78.83,80.37,81.235,8691212,9712569,10794968,11872264,13177000,14074100,15184200,16257249,17481977,18565243,19546792,20434176 +"Oceania","New Zealand",10556.57566,12247.39532,13175.678,14463.91893,16046.03728,16233.7177,17632.4104,19007.19129,18363.32494,21050.41377,23189.80135,25185.00911,69.39,70.26,71.24,71.52,71.89,72.22,73.84,74.32,76.33,77.55,79.11,80.204,1994794,2229407,2488550,2728150,2929100,3164900,3210650,3317166,3437674,3676187,3908037,4115771 diff --git a/data/gatos-data.csv b/data/gatos-data.csv new file mode 100644 index 00000000..9276e4a2 --- /dev/null +++ b/data/gatos-data.csv @@ -0,0 +1,4 @@ +"color","peso","le_gusta_cuerda" +"mixto",2.1,1 +"negro",5,0 +"atigrado",3.2,1 diff --git a/data/inflammation.csv b/data/inflammation.csv new file mode 100644 index 00000000..07a2e604 --- /dev/null +++ b/data/inflammation.csv @@ -0,0 +1,60 @@ +0,0,1,3,1,2,4,7,8,3,3,3,10,5,7,4,7,7,12,18,6,13,11,11,7,7,4,6,8,8,4,4,5,7,3,4,2,3,0,0 +0,1,2,1,2,1,3,2,2,6,10,11,5,9,4,4,7,16,8,6,18,4,12,5,12,7,11,5,11,3,3,5,4,4,5,5,1,1,0,1 +0,1,1,3,3,2,6,2,5,9,5,7,4,5,4,15,5,11,9,10,19,14,12,17,7,12,11,7,4,2,10,5,4,2,2,3,2,2,1,1 +0,0,2,0,4,2,2,1,6,7,10,7,9,13,8,8,15,10,10,7,17,4,4,7,6,15,6,4,9,11,3,5,6,3,3,4,2,3,2,1 +0,1,1,3,3,1,3,5,2,4,4,7,6,5,3,10,8,10,6,17,9,14,9,7,13,9,12,6,7,7,9,6,3,2,2,4,2,0,1,1 +0,0,1,2,2,4,2,1,6,4,7,6,6,9,9,15,4,16,18,12,12,5,18,9,5,3,10,3,12,7,8,4,7,3,5,4,4,3,2,1 +0,0,2,2,4,2,2,5,5,8,6,5,11,9,4,13,5,12,10,6,9,17,15,8,9,3,13,7,8,2,8,8,4,2,3,5,4,1,1,1 +0,0,1,2,3,1,2,3,5,3,7,8,8,5,10,9,15,11,18,19,20,8,5,13,15,10,6,10,6,7,4,9,3,5,2,5,3,2,2,1 +0,0,0,3,1,5,6,5,5,8,2,4,11,12,10,11,9,10,17,11,6,16,12,6,8,14,6,13,10,11,4,6,4,7,6,3,2,1,0,0 +0,1,1,2,1,3,5,3,5,8,6,8,12,5,13,6,13,8,16,8,18,15,16,14,12,7,3,8,9,11,2,5,4,5,1,4,1,2,0,0 +0,1,0,0,4,3,3,5,5,4,5,8,7,10,13,3,7,13,15,18,8,15,15,16,11,14,12,4,10,10,4,3,4,5,5,3,3,2,2,1 +0,1,0,0,3,4,2,7,8,5,2,8,11,5,5,8,14,11,6,11,9,16,18,6,12,5,4,3,5,7,8,3,5,4,5,5,4,0,1,1 +0,0,2,1,4,3,6,4,6,7,9,9,3,11,6,12,4,17,13,15,13,12,8,7,4,7,12,9,5,6,5,4,7,3,5,4,2,3,0,1 +0,0,0,0,1,3,1,6,6,5,5,6,3,6,13,3,10,13,9,16,15,9,11,4,6,4,11,11,12,3,5,8,7,4,6,4,1,3,0,0 +0,1,2,1,1,1,4,1,5,2,3,3,10,7,13,5,7,17,6,9,12,13,10,4,12,4,6,7,6,10,8,2,5,1,3,4,2,0,2,0 +0,1,1,0,1,2,4,3,6,4,7,5,5,7,5,10,7,8,18,17,9,8,12,11,11,11,14,6,11,2,10,9,5,6,5,3,4,2,2,0 +0,0,0,0,2,3,6,5,7,4,3,2,10,7,9,11,12,5,12,9,13,19,14,17,5,13,8,11,5,10,9,8,7,5,3,1,4,0,2,1 +0,0,0,1,2,1,4,3,6,7,4,2,12,6,12,4,14,7,8,14,13,19,6,9,12,6,4,13,6,7,2,3,6,5,4,2,3,0,1,0 +0,0,2,1,2,5,4,2,7,8,4,7,11,9,8,11,15,17,11,12,7,12,7,6,7,4,13,5,7,6,6,9,2,1,1,2,2,0,1,0 +0,1,2,0,1,4,3,2,2,7,3,3,12,13,11,13,6,5,9,16,9,19,16,11,8,9,14,12,11,9,6,6,6,1,1,2,4,3,1,1 +0,1,1,3,1,4,4,1,8,2,2,3,12,12,10,15,13,6,5,5,18,19,9,6,11,12,7,6,3,6,3,2,4,3,1,5,4,2,2,0 +0,0,2,3,2,3,2,6,3,8,7,4,6,6,9,5,12,12,8,5,12,10,16,7,14,12,5,4,6,9,8,5,6,6,1,4,3,0,2,0 +0,0,0,3,4,5,1,7,7,8,2,5,12,4,10,14,5,5,17,13,16,15,13,6,12,9,10,3,3,7,4,4,8,2,6,5,1,0,1,0 +0,1,1,1,1,3,3,2,6,3,9,7,8,8,4,13,7,14,11,15,14,13,5,13,7,14,9,10,5,11,5,3,5,1,1,4,4,1,2,0 +0,1,1,1,2,3,5,3,6,3,7,10,3,8,12,4,12,9,15,5,17,16,5,10,10,15,7,5,3,11,5,5,6,1,1,1,1,0,2,1 +0,0,2,1,3,3,2,7,4,4,3,8,12,9,12,9,5,16,8,17,7,11,14,7,13,11,7,12,12,7,8,5,7,2,2,4,1,1,1,0 +0,0,1,2,4,2,2,3,5,7,10,5,5,12,3,13,4,13,7,15,9,12,18,14,16,12,3,11,3,2,7,4,8,2,2,1,3,0,1,1 +0,0,1,1,1,5,1,5,2,2,4,10,4,8,14,6,15,6,12,15,15,13,7,17,4,5,11,4,8,7,9,4,5,3,2,5,4,3,2,1 +0,0,2,2,3,4,6,3,7,6,4,5,8,4,7,7,6,11,12,19,20,18,9,5,4,7,14,8,4,3,7,7,8,3,5,4,1,3,1,0 +0,0,0,1,4,4,6,3,8,6,4,10,12,3,3,6,8,7,17,16,14,15,17,4,14,13,4,4,12,11,6,9,5,5,2,5,2,1,0,1 +0,1,1,0,3,2,4,6,8,6,2,3,11,3,14,14,12,8,8,16,13,7,6,9,15,7,6,4,10,8,10,4,2,6,5,5,2,3,2,1 +0,0,2,3,3,4,5,3,6,7,10,5,10,13,14,3,8,10,9,9,19,15,15,6,8,8,11,5,5,7,3,6,6,4,5,2,2,3,0,0 +0,1,2,2,2,3,6,6,6,7,6,3,11,12,13,15,15,10,14,11,11,8,6,12,10,5,12,7,7,11,5,8,5,2,5,5,2,0,2,1 +0,0,2,1,3,5,6,7,5,8,9,3,12,10,12,4,12,9,13,10,10,6,10,11,4,15,13,7,3,4,2,9,7,2,4,2,1,2,1,1 +0,0,1,2,4,1,5,5,2,3,4,8,8,12,5,15,9,17,7,19,14,18,12,17,14,4,13,13,8,11,5,6,6,2,3,5,2,1,1,1 +0,0,0,3,1,3,6,4,3,4,8,3,4,8,3,11,5,7,10,5,15,9,16,17,16,3,8,9,8,3,3,9,5,1,6,5,4,2,2,0 +0,1,2,2,2,5,5,1,4,6,3,6,5,9,6,7,4,7,16,7,16,13,9,16,12,6,7,9,10,3,6,4,5,4,6,3,4,3,2,1 +0,1,1,2,3,1,5,1,2,2,5,7,6,6,5,10,6,7,17,13,15,16,17,14,4,4,10,10,10,11,9,9,5,4,4,2,1,0,1,0 +0,1,0,3,2,4,1,1,5,9,10,7,12,10,9,15,12,13,13,6,19,9,10,6,13,5,13,6,7,2,5,5,2,1,1,1,1,3,0,1 +0,1,1,3,1,1,5,5,3,7,2,2,3,12,4,6,8,15,16,16,15,4,14,5,13,10,7,10,6,3,2,3,6,3,3,5,4,3,2,1 +0,0,0,2,2,1,3,4,5,5,6,5,5,12,13,5,7,5,11,15,18,7,9,10,14,12,11,9,10,3,2,9,6,2,2,5,3,0,0,1 +0,0,1,3,3,1,2,1,8,9,2,8,10,3,8,6,10,13,11,17,19,6,4,11,6,12,7,5,5,4,4,8,2,6,6,4,2,2,0,0 +0,1,1,3,4,5,2,1,3,7,9,6,10,5,8,15,11,12,15,6,12,16,6,4,14,3,12,9,6,11,5,8,5,5,6,1,2,1,2,0 +0,0,1,3,1,4,3,6,7,8,5,7,11,3,6,11,6,10,6,19,18,14,6,10,7,9,8,5,8,3,10,2,5,1,5,4,2,1,0,1 +0,1,1,3,3,4,4,6,3,4,9,9,7,6,8,15,12,15,6,11,6,18,5,14,15,12,9,8,3,6,10,6,8,7,2,5,4,3,1,1 +0,1,2,2,4,3,1,4,8,9,5,10,10,3,4,6,7,11,16,6,14,9,11,10,10,7,10,8,8,4,5,8,4,4,5,2,4,1,1,0 +0,0,2,3,4,5,4,6,2,9,7,4,9,10,8,11,16,12,15,17,19,10,18,13,15,11,8,4,7,11,6,7,6,5,1,3,1,0,0,0 +0,1,1,3,1,4,6,2,8,2,10,3,11,9,13,15,5,15,6,10,10,5,14,15,12,7,4,5,11,4,6,9,5,6,1,1,2,1,2,1 +0,0,1,3,2,5,1,2,7,6,6,3,12,9,4,14,4,6,12,9,12,7,11,7,16,8,13,6,7,6,10,7,6,3,1,5,4,3,0,0 +0,0,1,2,3,4,5,7,5,4,10,5,12,12,5,4,7,9,18,16,16,10,15,15,10,4,3,7,5,9,4,6,2,4,1,4,2,2,2,1 +0,1,2,1,1,3,5,3,6,3,10,10,11,10,13,10,13,6,6,14,5,4,5,5,9,4,12,7,7,4,7,9,3,3,6,3,4,1,2,0 +0,1,2,2,3,5,2,4,5,6,8,3,5,4,3,15,15,12,16,7,20,15,12,8,9,6,12,5,8,3,8,5,4,1,3,2,1,3,1,0 +0,0,0,2,4,4,5,3,3,3,10,4,4,4,14,11,15,13,10,14,11,17,9,11,11,7,10,12,10,10,10,8,7,5,2,2,4,1,2,1 +0,0,2,1,1,4,4,7,2,9,4,10,12,7,6,6,11,12,9,15,15,6,6,13,5,12,9,6,4,7,7,6,5,4,1,4,2,2,2,1 +0,1,2,1,1,4,5,4,4,5,9,7,10,3,13,13,8,9,17,16,16,15,12,13,5,12,10,9,11,9,4,5,5,2,2,5,1,0,0,1 +0,0,1,3,2,3,6,4,5,7,2,4,11,11,3,8,8,16,5,13,16,5,8,8,6,9,10,10,9,3,3,5,3,5,4,5,3,3,0,1 +0,1,1,2,2,5,1,7,4,2,5,5,4,6,6,4,16,11,14,16,14,14,8,17,4,14,13,7,6,3,7,7,5,6,3,4,2,2,1,1 +0,1,1,1,4,1,6,4,6,3,6,5,6,4,14,13,13,9,12,19,9,10,15,10,9,10,10,7,5,6,8,6,6,4,3,5,2,1,1,1 +0,0,0,1,4,5,6,3,8,7,9,10,8,6,5,12,15,5,10,5,8,13,18,17,14,9,13,4,10,11,10,8,8,6,5,5,2,0,2,0 +0,0,1,0,3,2,5,4,8,2,9,3,3,10,12,9,14,11,13,8,6,18,11,9,13,11,8,5,5,2,8,5,3,5,4,1,3,1,1,0 diff --git a/discuss.md b/discuss.md new file mode 100644 index 00000000..a89a31ca --- /dev/null +++ b/discuss.md @@ -0,0 +1,10 @@ +--- +title: Discussion +--- + +Please see [our other R lesson][r-gap] for a different presentation of these concepts. + +[r-gap]: https://swcarpentry.github.io/r-novice-gapminder/ + + + diff --git a/fig/01-rstudio-script.png b/fig/01-rstudio-script.png new file mode 100644 index 00000000..2ad48164 Binary files /dev/null and b/fig/01-rstudio-script.png differ diff --git a/fig/01-rstudio.png b/fig/01-rstudio.png new file mode 100644 index 00000000..a1588f80 Binary files /dev/null and b/fig/01-rstudio.png differ diff --git a/fig/06-rmd-generate-figures.sh b/fig/06-rmd-generate-figures.sh new file mode 100755 index 00000000..4cc23132 --- /dev/null +++ b/fig/06-rmd-generate-figures.sh @@ -0,0 +1,7 @@ +inkscape --export-png=06-rmd-inequality.0.png 06-rmd-inequality.0.svg +# use ImageMagick to grab top and bottom halves +# (surely there's a better way ... too much space at the bottom of the first) +convert 06-rmd-inequality.0.png -crop 100%x50% tmp.png +mv tmp-0.png 06-rmd-inequality.1.png +mv tmp-1.png 06-rmd-inequality.2.png + diff --git a/fig/06-rmd-inequality.0.png b/fig/06-rmd-inequality.0.png new file mode 100644 index 00000000..aa6d3f1e Binary files /dev/null and b/fig/06-rmd-inequality.0.png differ diff --git a/fig/06-rmd-inequality.0.svg b/fig/06-rmd-inequality.0.svg new file mode 100644 index 00000000..b8953dcb --- /dev/null +++ b/fig/06-rmd-inequality.0.svg @@ -0,0 +1,311 @@ + + + + + + + + + + image/svg+xml + + + + + + + c("a", "b", "c") + c("a", "c") + + + + + + + FALSE + TRUE + ?? + ?? + c("a", "b", "c") + c("a", "c") + + + + + + + FALSE + TRUE + c("a"... + FALSE + != + != + + diff --git a/fig/06-rmd-inequality.1.png b/fig/06-rmd-inequality.1.png new file mode 100644 index 00000000..58003850 Binary files /dev/null and b/fig/06-rmd-inequality.1.png differ diff --git a/fig/06-rmd-inequality.2.png b/fig/06-rmd-inequality.2.png new file mode 100644 index 00000000..d3f438dc Binary files /dev/null and b/fig/06-rmd-inequality.2.png differ diff --git a/fig/08-plot-ggplot2-rendered-axis-scale-1.png b/fig/08-plot-ggplot2-rendered-axis-scale-1.png new file mode 100644 index 00000000..3349b33e Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-axis-scale-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-build-ggplot-3-1.png b/fig/08-plot-ggplot2-rendered-build-ggplot-3-1.png new file mode 100644 index 00000000..44db5466 Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-build-ggplot-3-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-ch1-sol-1.png b/fig/08-plot-ggplot2-rendered-ch1-sol-1.png new file mode 100644 index 00000000..6dcaa2a7 Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-ch1-sol-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-ch2-sol-1.png b/fig/08-plot-ggplot2-rendered-ch2-sol-1.png new file mode 100644 index 00000000..4559e25e Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-ch2-sol-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-ch3-sol-1.png b/fig/08-plot-ggplot2-rendered-ch3-sol-1.png new file mode 100644 index 00000000..1b128629 Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-ch3-sol-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-ch4a-sol-1.png b/fig/08-plot-ggplot2-rendered-ch4a-sol-1.png new file mode 100644 index 00000000..0f755f4c Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-ch4a-sol-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-ch4b-sol-1.png b/fig/08-plot-ggplot2-rendered-ch4b-sol-1.png new file mode 100644 index 00000000..e07c93aa Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-ch4b-sol-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-ch5-sol-1.png b/fig/08-plot-ggplot2-rendered-ch5-sol-1.png new file mode 100644 index 00000000..be0d0577 Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-ch5-sol-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-facet-1.png b/fig/08-plot-ggplot2-rendered-facet-1.png new file mode 100644 index 00000000..874a705e Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-facet-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-lifeExp-layer-example-1-1.png b/fig/08-plot-ggplot2-rendered-lifeExp-layer-example-1-1.png new file mode 100644 index 00000000..7890fe8c Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-lifeExp-layer-example-1-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-lifeExp-line-1.png b/fig/08-plot-ggplot2-rendered-lifeExp-line-1.png new file mode 100644 index 00000000..56157b9b Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-lifeExp-line-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-lifeExp-line-point-1.png b/fig/08-plot-ggplot2-rendered-lifeExp-line-point-1.png new file mode 100644 index 00000000..c02ce6ad Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-lifeExp-line-point-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-lifeExp-vs-gdpPercap-scatter3-1.png b/fig/08-plot-ggplot2-rendered-lifeExp-vs-gdpPercap-scatter3-1.png new file mode 100644 index 00000000..33af746b Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-lifeExp-vs-gdpPercap-scatter3-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-lm-fit-1.png b/fig/08-plot-ggplot2-rendered-lm-fit-1.png new file mode 100644 index 00000000..34f37f99 Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-lm-fit-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-lm-fit2-1.png b/fig/08-plot-ggplot2-rendered-lm-fit2-1.png new file mode 100644 index 00000000..313a1a3e Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-lm-fit2-1.png differ diff --git a/fig/08-plot-ggplot2-rendered-theme-1.png b/fig/08-plot-ggplot2-rendered-theme-1.png new file mode 100644 index 00000000..a7a3ee3f Binary files /dev/null and b/fig/08-plot-ggplot2-rendered-theme-1.png differ diff --git a/fig/09-vectorization-rendered-ch2-sol-1.png b/fig/09-vectorization-rendered-ch2-sol-1.png new file mode 100644 index 00000000..99fe38be Binary files /dev/null and b/fig/09-vectorization-rendered-ch2-sol-1.png differ diff --git a/fig/09-vectorization-rendered-ch2-sol-2.png b/fig/09-vectorization-rendered-ch2-sol-2.png new file mode 100644 index 00000000..5b630819 Binary files /dev/null and b/fig/09-vectorization-rendered-ch2-sol-2.png differ diff --git a/fig/12-plyr-fig1.png b/fig/12-plyr-fig1.png new file mode 100644 index 00000000..249bab4f Binary files /dev/null and b/fig/12-plyr-fig1.png differ diff --git a/fig/12-plyr-fig1.tex b/fig/12-plyr-fig1.tex new file mode 100644 index 00000000..ded41a78 --- /dev/null +++ b/fig/12-plyr-fig1.tex @@ -0,0 +1,143 @@ +\documentclass[convert]{standalone} + +\usepackage{tikz} +\usepackage{colortbl} +\renewcommand{\familydefault}{\sfdefault} + +\begin{document} + +\begin{tikzpicture} + +% Headings + +\node (INPUT-LABEL) at (0, 5) {Input Data}; +\node (GROUP-LABEL) at (3, 5) {Split}; +\node (SUMMARY-LABEL) at (6, 5) {Apply}; +\node (OUTPUT-LABEL) at (9, 5) {Combine}; + + +% Data Nodes + +\node (INPUT) at (0, 2) { + + \begin{tabular}{| c | r |} + \hline + \rowcolor[gray]{.7} + x & y \\ \hline + a & 2 \\ \hline + a & 4 \\ \hline + b & 0 \\ \hline + b & 5 \\ \hline + c & 5 \\ \hline + c & 10 \\ \hline + \end{tabular} + +}; + +\node (GROUP-A) at (3, 4) { + + \begin{tabular}{| c | r |} + \hline + \rowcolor[gray]{.7} + x & y \\ \hline + a & 2 \\ \hline + a & 4 \\ \hline + \end{tabular} + +}; + +\node (GROUP-B) at (3, 2) { + + \begin{tabular}{| c | r |} + \hline + \rowcolor[gray]{.7} + x & y \\ \hline + b & 0 \\ \hline + b & 5 \\ \hline + \end{tabular} + +}; + +\node (GROUP-C) at (3, 0) { + + \begin{tabular}{| c | r |} + \hline + \rowcolor[gray]{.7} + x & y \\ \hline + c & 5 \\ \hline + c & 10 \\ \hline + \end{tabular} + +}; + +\node (SUMMARY-A) at (6, 4) { + + \begin{tabular}{| c | r |} + \hline + \rowcolor[gray]{.7} + x & y \\ \hline + a & 3.0 \\ \hline + \end{tabular} + +}; + +\node (SUMMARY-B) at (6, 2) { + + \begin{tabular}{| c | r |} + \hline + \rowcolor[gray]{.7} + x & y \\ \hline + b & 2.5 \\ \hline + \end{tabular} + +}; + +\node (SUMMARY-C) at (6, 0) { + + \begin{tabular}{| c | r |} + \hline + \rowcolor[gray]{.7} + x & y \\ \hline + c & 7.5 \\ \hline + \end{tabular} + +}; + +\node (OUPUT) at (9, 2) { + + \begin{tabular}{| c | r |} + \hline + \rowcolor[gray]{.7} + x & y \\ \hline + a & 3.0 \\ \hline + b & 2.5 \\ \hline + c & 7.5 \\ \hline + \end{tabular} + +}; + + +% Arrows + +\draw[->, to path={-> (\tikztotarget)}] + (INPUT) edge (GROUP-A) + (INPUT) edge (GROUP-B) + (INPUT) edge (GROUP-C) + + (GROUP-A) edge (SUMMARY-A) + (GROUP-B) edge (SUMMARY-B) + (GROUP-C) edge (SUMMARY-C) + + (SUMMARY-A) edge (OUPUT) + (SUMMARY-B) edge (OUPUT) + (SUMMARY-C) edge (OUPUT) +; + +\end{tikzpicture} + +\end{document} + +%------------------------ +% References +% https://tex.stackexchange.com/questions/251642/draw-arrows-between-nodes-with-tikz +% https://tex.stackexchange.com/questions/11866/compile-a-latex-document-into-a-png-image-thats-as-short-as-possible diff --git a/fig/12-plyr-fig2.png b/fig/12-plyr-fig2.png new file mode 100644 index 00000000..d00d25f5 Binary files /dev/null and b/fig/12-plyr-fig2.png differ diff --git a/fig/12-plyr-fig2.tex b/fig/12-plyr-fig2.tex new file mode 100644 index 00000000..56fdfcd3 --- /dev/null +++ b/fig/12-plyr-fig2.tex @@ -0,0 +1,64 @@ +\documentclass[convert]{standalone} + +\usepackage{array} +\usepackage{multirow} +\usepackage{rotating} +\usepackage{colortbl} +\renewcommand{\familydefault}{\sfdefault} +\renewcommand{\arraystretch}{2.2} + +\begin{document} + +\begin{tabular}{crccccc} + +& +& \multicolumn{4}{c}{Output} +\\ + +& %\cellcolor[gray]{0.7} +& \cellcolor[gray]{0.7}array +& \cellcolor[gray]{0.7}data frame +& \cellcolor[gray]{0.7}list +& \cellcolor[gray]{0.7}nothing +\\ + +& \cellcolor[gray]{0.7}array +& aaply +& adply +& alply +& a\_ply +\\ + +& \cellcolor[gray]{0.7}data frame +& daply +& ddply +& dlply +& d\_ply +\\ + +& \cellcolor[gray]{0.7} list +& laply +& ldply +& llply +& l\_ply +\\ + +& \cellcolor[gray]{0.7}n replicates +& raply +& rdply +& rlply +& r\_ply +\\ + +\multirow{-5}{*}{\rotatebox[origin=c]{90}{Input}} +& \cellcolor[gray]{0.7}function arguments +& maply +& mdply +& mlply +& m\_ply +\\ + +\end{tabular} + + +\end{document} diff --git a/fig/12-plyr-generate-figures.sh b/fig/12-plyr-generate-figures.sh new file mode 100755 index 00000000..9236d34e --- /dev/null +++ b/fig/12-plyr-generate-figures.sh @@ -0,0 +1,10 @@ +#! /bin/bash + +pdflatex -shell-escape 12-plyr-fig1.tex + +rm 12-plyr-fig1.aux 12-plyr-fig1.log 12-plyr-fig1.pdf + +pdflatex -shell-escape 12-plyr-fig2.tex + +rm 12-plyr-fig2.aux 12-plyr-fig2.log 12-plyr-fig2.pdf + diff --git a/fig/13-dplyr-fig1.png b/fig/13-dplyr-fig1.png new file mode 100644 index 00000000..a3020a3f Binary files /dev/null and b/fig/13-dplyr-fig1.png differ diff --git a/fig/13-dplyr-fig2.png b/fig/13-dplyr-fig2.png new file mode 100644 index 00000000..0a819233 Binary files /dev/null and b/fig/13-dplyr-fig2.png differ diff --git a/fig/13-dplyr-fig3.png b/fig/13-dplyr-fig3.png new file mode 100644 index 00000000..f14f0eb8 Binary files /dev/null and b/fig/13-dplyr-fig3.png differ diff --git a/fig/13-dplyr-generate-figures.R b/fig/13-dplyr-generate-figures.R new file mode 100644 index 00000000..05d33c38 --- /dev/null +++ b/fig/13-dplyr-generate-figures.R @@ -0,0 +1,388 @@ +# export figures manually +library(DiagrammeR) +##################################### 13-dplyr-fig2.png ##################################### +grViz('digraph html { + table1 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abcd
>]; + + table2 [shape=none, margin=0, label=< + + + + + + + + + + + + + + + + + + + + +
ac
>]; + + table1:f1 -> table2:f1 + table1:f0 -> table2:f0 + + subgraph { + rank = same; table1; table2; + } + + labelloc="t"; + fontname="Courier"; + label="select(data.frame,a,c)"; + } + ') + +##################################### 13-dplyr-fig2.png ##################################### +grViz('digraph html { + table1 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abcd
1
1
2
2
3
3
>]; + table2 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + + +
abcd
1
1
>]; + table3 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + +
abcd
2
2
>]; + table4 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + +
abcd
3
3
>]; + + + + table1:f0 -> table2:f0 + table1:f1 -> table3:f1 + table1:f2 -> table4:f2 + + subgraph { + rank = same; table1; table2; table3 ;table4; + } + subgraph { + table2 + table3 + table4 + } + + labelloc="t"; + fontname="Courier"; + label="gapminder %>% group_by(a)"; + } + ') + +##################################### 13-dplyr-fig3.png ##################################### +grViz('digraph html { + table1 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abcd
1
1
2
2
3
3
>]; + + table2 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + + +
abcd
1
1
>]; + + table3 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + +
abcd
2
2
>]; + + table4 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + +
abcd
3
3
>]; + + table5 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + +
amean_b
1
2
3
>]; + + + table1:f0 -> table2:f0 + table1:f1 -> table3:f1 + table1:f2 -> table4:f2 + table2:f3 -> table5:f0 + table3:f3 -> table5:f1 + table4:f3 -> table5:f2 + subgraph { + rank = same; table1; table2; table3 ; table4; + } + subgraph { + table2 + table3 + table4 + } + + labelloc="t"; + fontname="Courier"; + label="gapminder %>%\\l\tgroup_by(a) %>%\\l\tsummarize(mean_b=mean(b))\\l"; + } + ') diff --git a/fig/14-tidyr-fig1.png b/fig/14-tidyr-fig1.png new file mode 100644 index 00000000..4ce00666 Binary files /dev/null and b/fig/14-tidyr-fig1.png differ diff --git a/fig/14-tidyr-fig2.png b/fig/14-tidyr-fig2.png new file mode 100644 index 00000000..7287d019 Binary files /dev/null and b/fig/14-tidyr-fig2.png differ diff --git a/fig/14-tidyr-fig3.png b/fig/14-tidyr-fig3.png new file mode 100644 index 00000000..aafcbe2b Binary files /dev/null and b/fig/14-tidyr-fig3.png differ diff --git a/fig/14-tidyr-fig3.svg b/fig/14-tidyr-fig3.svg new file mode 100644 index 00000000..3bcffd63 --- /dev/null +++ b/fig/14-tidyr-fig3.svg @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ID +a1 +a2 +a3 +ID +2 +1 +3 +2 +1 +3 +2 +1 +3 +2 +1 +3 +a1 +a2 +a3 +a1 +a2 +a3 +a1 +a2 +a3 +key +value +wide format +long format +gather(data, key = "key", value = "value", c(”a1”, “a2”, ”a3”)) + + + + + + + + + + + + + + + + +ID +a1 +a2 +a3 +2 +1 +3 + + + + +ID +2 +1 +3 + + + + +ID +2 +1 +3 + + + + + + + + + + + + + + + + +ID +a1 +a2 +a3 +2 +1 +3 + + + + +ID +2 +1 +3 + + + + +ID +2 +1 +3 + + + + + + + + + + + + + +ID +2 +1 +3 + + + + +ID +2 +1 +3 + + + + +ID +2 +1 +3 + + + +a1 +a2 +a3 + + + +a1 +a2 +a3 + + + +a1 +a2 +a3 + + + + + + + + +separate byselected columns + + + + + + + + +convert column names to column + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +name columns with keyand value arguments + diff --git a/fig/14-tidyr-fig4.png b/fig/14-tidyr-fig4.png new file mode 100644 index 00000000..fd5d68c6 Binary files /dev/null and b/fig/14-tidyr-fig4.png differ diff --git a/fig/14-tidyr-generate-figures.R b/fig/14-tidyr-generate-figures.R new file mode 100644 index 00000000..9ed954ae --- /dev/null +++ b/fig/14-tidyr-generate-figures.R @@ -0,0 +1,385 @@ +# export figures manually +library(DiagrammeR) +##################################### 14-tidyr-fig1.png ##################################### +grViz('digraph html { + + table1 [shape=none, margin=0, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDa1a2a3
>]; + + table2 [shape=none, margin=0,label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDID2A
1a1
2a1
3a1
1a2
2a2
3a2
1a3
2a3
3a3
>]; + + subgraph { + rank = same; table1; table2; + } + + + labelloc="t"; + fontname="Courier"; + label="wide vs long"; + } + ') + +##################################### 14-tidyr-fig2.png ##################################### +grViz('digraph html { + table1 [shape=none, margin=0, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
continentcountrygdpPercap_1952gdpPercap_1957gdpPercap_...lifeExp_1952lifeExp_1957lifeExp_...pop_1952pop_1957pop_...
AfricaAlgeria
AfricaAngola
......
>]; + + labelloc="t"; + fontname="Courier"; + label="wide format"; + } + ') + +##################################### 14-tidyr-fig3.png ##################################### +grViz('digraph html { + + table1 [shape=none, margin=0, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
continentcountryobstype_yearobs_value
AfricaAlgeriagdpPercap_1952
AfricaAlgeriagdpPercap_1957
AfricaAlgeriagdpPercap_...
AfricaAlgerialifeExp_1952
AfricaAlgerialifeExp_1957
AfricaAlgerialifeExp_...
AfricaAlgeriapop_1952
AfricaAlgeriapop_1957
AfricaAlgeriapop_...
AfricaAngolagdpPercap_1952
AfricaAngolagdpPercap_1957
AfricaAngolagdpPercap_...
AfricaAngolalifeExp_1952
AfricaAngolalifeExp_1957
AfricaAngolalifeExp_...
AfricaAngolapop_1952
AfricaAngolapop_1957
AfricaAngolapop_...
Africa...gdpPercap_1952
Africa...gdpPercap_1957
Africa...gdpPercap_...
Africa...lifeExp_1952
Africa...lifeExp_1957
Africa...lifeExp_...
Africa...pop_1952
Africa...pop_1957
Africa...pop_...
>]; + + labelloc="t"; + fontname="Courier"; + label="long format"; + } + ') diff --git a/fig/15-knitr-markdown-rendered-rmd_to_html_fig-1.png b/fig/15-knitr-markdown-rendered-rmd_to_html_fig-1.png new file mode 100644 index 00000000..976f7bc7 Binary files /dev/null and b/fig/15-knitr-markdown-rendered-rmd_to_html_fig-1.png differ diff --git a/fig/New_R_Markdown.png b/fig/New_R_Markdown.png new file mode 100644 index 00000000..864c9177 Binary files /dev/null and b/fig/New_R_Markdown.png differ diff --git a/fig/bad_layout.png b/fig/bad_layout.png new file mode 100644 index 00000000..fcfda0c5 Binary files /dev/null and b/fig/bad_layout.png differ diff --git a/fig/rmd-06-equality.0.svg b/fig/rmd-06-equality.0.svg new file mode 100644 index 00000000..9671b0b3 --- /dev/null +++ b/fig/rmd-06-equality.0.svg @@ -0,0 +1,288 @@ + + + + + + + + + + image/svg+xml + + + + + + + c("a", "a", "a") + c("a", "c") + + + + + + + TRUE + FALSE + ?? + ?? + c("a", "a", "a") + c("a", "c") + + + + + + + TRUE + FALSE + c("a"... + TRUE + + diff --git a/fig/rmd-06-equality.1.png b/fig/rmd-06-equality.1.png new file mode 100644 index 00000000..f4152a33 Binary files /dev/null and b/fig/rmd-06-equality.1.png differ diff --git a/fig/rmd-06-equality.2.png b/fig/rmd-06-equality.2.png new file mode 100644 index 00000000..e33f4cf4 Binary files /dev/null and b/fig/rmd-06-equality.2.png differ diff --git a/fig/software-carpentry-banner.png b/fig/software-carpentry-banner.png new file mode 100644 index 00000000..746a9c53 Binary files /dev/null and b/fig/software-carpentry-banner.png differ diff --git a/index.md b/index.md new file mode 100644 index 00000000..e5da8616 --- /dev/null +++ b/index.md @@ -0,0 +1,22 @@ +--- +site: sandpaper::sandpaper_site +--- + +El objetivo de esta lección es enseñar a las personas programadoras principiantes a escribir códigos modulares y adoptar buenas prácticas en el uso de R para el análisis de datos. R nos provee un conjunto de paquetes desarrollados por terceros que se usan comúnmente en diversas disciplinas científicas para el análisis estadístico. Encontramos que muchos científicos que asisten a los talleres de Software Carpentry utilizan R y quieren aprender más. Nuestros materiales son relevantes ya que proporcionan a los asistentes una base sólida en los fundamentos de R y enseñan las mejores prácticas del cómputo científico: desglose del análisis en módulos, automatización tareas y encapsulamiento. + +Ten en cuenta que este taller se enfoca en los fundamentos del lenguaje de programación R y no en el análisis estadístico. + +A lo largo de este taller se utilizan una variedad de paquetes desarrolados por terceros, los cuales no son necesariamente los mejores ni se encuentran explicadas todas sus funcionalidades, pero son paquetes que consideramos útiles y han sido elegidos principalmente por su facilidad de uso. + +:::::::::::::::::::::::::::::::::::::::::: prereq + +## Prerrequisitos + +Entender que los archivos estan organizados en directorios (folders). +Entender que las computadoras guardan datos e instrucciones (programas, **scripts**) en archivos. +Saber como acceder a los archivos que no están en el directorio de trabajo, especificando el **path**. + + +:::::::::::::::::::::::::::::::::::::::::::::::::: + + diff --git a/instructor-notes.md b/instructor-notes.md new file mode 100644 index 00000000..619f79ae --- /dev/null +++ b/instructor-notes.md @@ -0,0 +1,128 @@ +--- +title: Guía del instructor +--- + +## Tiempo + +Dedicar unos 30 minutos antes del comienzo de cada taller y otros 15 minutos +al comienzo de cada sesión para resolver dificultades técnicas como WiFi e +instalación cosas (incluso si le pediste a los estudiantes que instalen programas con anticipación, y reservar más tiempo +si no lo hiciste). + +## Planificación de la lección + +La lección contiene mucho más material del que puede ser enseñado en un día. +Los instructores deberán elegir un subgrupo apropiado de episodios a usar +para un curso estándar de un día de duración. + +Algunos lineamientos sugeridos del material a utilizar son: + +(sugerido por [@liz-is](https://github.com/swcarpentry/r-novice-gapminder/issues/104#issuecomment-276529213)) + +- 01 Introducción a R y RStudio +- 04 Estructuras de datos +- 05 Explorando data frames (desde la sección "Ejemplo realista") +- 08 Creando gráficas con calidad para publicación con ggplot2 +- 10 Funciones +- 13 Manipulación de data frames con dplyr +- 15 Produciendo informes con knitr + +(sugerido por [@naupaka](https://github.com/swcarpentry/r-novice-gapminder/issues/104#issuecomment-312547509)) + +- 01 Introducción a R y RStudio +- 02 Gestión de proyectos con RStudio +- 03 Buscando ayuda +- 04 Estructuras de datos +- 05 Explorando data frames +- 06 Haciendo subconjuntos de datos +- 09 Vectorization +- 08 Creando gráficas con calidad para publicación con ggplot2 *OR* + 13 Manipulación de data frames con dplyr +- 15 Produciendo informes con knitr + +Medio día de curso podría consistir en (sugerido por [@karawoo](https://github.com/swcarpentry/r-novice-gapminder/issues/104#issuecomment-277599864)): + +- 01 Introducción a R y RStudio +- 04 Estructuras de datos (únicamente creando vectores con `c()`) +- 05 Explorando data frames (desde la sección "Ejemplo realista") +- 06 Haciendo subconjuntos de datos (excluyendo subconjuntos de factores, matrices y listas) +- 08 Creando gráficas con calidad para publicación con ggplot2 + +## Configurando git en RStudio + +Pueden haber dificultades relacionando git a RStudio dependiendo del +sistema operativo y de su versión. Para asegurarse que Git está correctamente +instalado y configurado, los alumnos deberán ir a la ventana Opciones de +la aplicación RStudio. + +- **Mac OS X:** + - Ir a RStudio -> Preferencias... -> Git/SVN + - Chequear si existe un **path** a un archivo en la ventana "Git ejecutable". Si no lo hay, el siguiente desafío será averiguar dónde está ubicado Git. + - En la terminal, ingresa `which git` y obtendrás el **path** al archivo ejecutable de git. En la ventana "Git ejecutable" quizás tengas dificultades encontrando el directorio, ya que OS X oculta muchos de sus archivos del sistema operativo. Con la ventana de selección de archivo abierta, presionar las teclas "Comando-Shift-G" hará que se abra un cuadro de texto donde podrás tipear o pegar el **path** completo a tu archivo ejecutable de Git: e.g. /usr/bin/git o lo que corresponda. +- **Windows:** + - Ir a Herramientas -> Opciones Globales... -> Git/SVN + - Si usas el Instalador de Software Carpentry, entonces 'git.exe' debe ser instalado en `C:/Archivos de Programa/Git/bin/git.exe`. + +Para evitar que los alumnos tengan que re-ingresar su **password** cada vez que hacen un **push** a GitHub, éste comando (que puede ser corrido desde un **prompt** de **bash**) hará que solo tengan que ingresar su **password** una única vez: + +```bash +$ git config --global credential.helper 'cache --timeout=10000000' +``` + +## Obteniendo datos + +La forma más simple de obtener los datos usados en esta lección durante un taller es +hacer que los asistentes ejecuten lo siguiente: + +```bash +git remote add data https://github.com/resbaz/r-novice-gapminder-files +git pull data master +``` + +Si Git no está siendo enseñado como parte del taller, entonces los datos crudos pueden ser descargados desde +[gapminder-FiveYearData][gapminder-data] y +[gapminder-FiveYearData-Wide][gapminder-data-wide]. + +Los asistentes pueden usar el diálogo `Archivo - Guardar como...` de su navegador para guardar el archivo. + +## En general + +Asegurarse de enfatizar las buenas prácticas: escribir el código en **scripts** y hacer +que esté bajo control de versiones. Alentar a los estudiantes a crear archivos de **scripts** +para resolver los desafíos. + +Si estás trabajando en un ambiente remoto (en "la nube"), puedes pedirles que suban los datos de **gapminder** +luego de la segunda lección. + +Asegurate de enfatizar que, a fin de cuentas, las matrices son vectores y que las **data frames** +son listas: esto explicará mucho del comportamiento esotérico encontrado +en las operaciones básicas. + +El reciclado de vectores y funciones probablemente se explican mejor usando +diagramas en una pizarra. + +Es recomendado mirar y hacer los ejemplos de una página de ayuda de R: los +archivos de ayuda pueden ser intimidantes al principio, pero saber cómo leerlos es +tremendamente útil. + +Mostrar las **CRAN task views**, verlas con uno de los temas. + +Hay mucho contenido: muévete rápidamente por las primeras lecciones. Éstas son extensas +mayormente con el propósito de aprender por ósmosis: de forma que su recuerdo +se dispare cuando se encuentren luego con un problema o comportamiento esotérico. + +Lecciones clave en las cuales dedicar tiempo: + +- Haciendo subconjuntos de datos - conceptualmente difíciles para novatos +- Funciones - los estudiantes tienen problemas especialmente con ellas +- Estructuras de datos - vale la pena ser completo, pero puedes avanzar por la lección rápidamente. + +No se preocupes por no equivocarte o conocer el material de pies a cabeza. Usa +los errores como momentos de aprendizaje: la habilidad más importante que puedes +enseñar es cómo eliminar errores (**debug**) y recuperarse de errores inesperados. + +[gapminder-data]: data/gapminder-FiveYearData.csv +[gapminder-data-wide]: data/gapminder_wide.csv + + + diff --git a/learner-profiles.md b/learner-profiles.md new file mode 100644 index 00000000..434e335a --- /dev/null +++ b/learner-profiles.md @@ -0,0 +1,5 @@ +--- +title: FIXME +--- + +This is a placeholder file. Please add content here. diff --git a/md5sum.txt b/md5sum.txt new file mode 100644 index 00000000..33ea5c8f --- /dev/null +++ b/md5sum.txt @@ -0,0 +1,28 @@ +"file" "checksum" "built" "date" +"CODE_OF_CONDUCT.md" "c93c83c630db2fe2462240bf72552548" "site/built/CODE_OF_CONDUCT.md" "2023-11-10" +"LICENSE.md" "b24ebbb41b14ca25cf6b8216dda83e5f" "site/built/LICENSE.md" "2023-11-10" +"NEWS.md" "5f095ea326686e040515b3a4083dac0c" "site/built/NEWS.md" "2023-11-10" +"config.yaml" "6937e343b4e3568a3bba5f2625125296" "site/built/config.yaml" "2023-11-10" +"index.md" "ebed87c856179ccf6edc852ade633afe" "site/built/index.md" "2023-11-10" +"episodes/01-rstudio-intro.Rmd" "df5a9cad0039f566bfc718b5f7c4a380" "site/built/01-rstudio-intro.md" "2023-11-10" +"episodes/02-project-intro.Rmd" "60939608000d5f306bc0e6fe0942a41f" "site/built/02-project-intro.md" "2023-11-10" +"episodes/03-seeking-help.Rmd" "f4deeccd811d73e36fea077fbb9c4032" "site/built/03-seeking-help.md" "2023-11-10" +"episodes/04-data-structures-part1.Rmd" "b6d6bc3443c6cdf89979a7365204574b" "site/built/04-data-structures-part1.md" "2023-11-10" +"episodes/05-data-structures-part2.Rmd" "da58cc64c0e5abcd959e9f0658f085e1" "site/built/05-data-structures-part2.md" "2023-11-10" +"episodes/06-data-subsetting.Rmd" "c67848164213c376b967f16a8a05f7d5" "site/built/06-data-subsetting.md" "2023-11-10" +"episodes/07-control-flow.Rmd" "c61eb1b5dce6e7ac620653e1b0b66ee9" "site/built/07-control-flow.md" "2023-11-10" +"episodes/08-plot-ggplot2.Rmd" "c404c7c88a8ff8f42987ca72f4a2a586" "site/built/08-plot-ggplot2.md" "2023-11-10" +"episodes/09-vectorization.Rmd" "9e8cc20afc79d243189bd9a19a54e174" "site/built/09-vectorization.md" "2023-11-10" +"episodes/10-functions.Rmd" "3c24c68a1c2a6f92b6c118c77b4bb23e" "site/built/10-functions.md" "2023-11-10" +"episodes/11-writing-data.Rmd" "f42fe99984f6768838eeb49d1bd518d9" "site/built/11-writing-data.md" "2023-11-10" +"episodes/12-plyr.Rmd" "a2aa9bef9e4e16f3ba3f277565aaf76a" "site/built/12-plyr.md" "2023-11-10" +"episodes/13-dplyr.Rmd" "fca99660f5859ef49493177aa0bc69de" "site/built/13-dplyr.md" "2023-11-10" +"episodes/14-tidyr.Rmd" "8861bff8f34f2054b75a1daef3cdcc39" "site/built/14-tidyr.md" "2023-11-10" +"episodes/15-knitr-markdown.Rmd" "e19009b2aedaaee3a6000f1ae81e6ecc" "site/built/15-knitr-markdown.md" "2023-11-10" +"episodes/16-wrap-up.Rmd" "f6f1d90a11b7c4b7a61813a1d678ba14" "site/built/16-wrap-up.md" "2023-11-10" +"instructors/instructor-notes.md" "3d04325668f1c897df5a0b46d5ac5a53" "site/built/instructor-notes.md" "2023-11-10" +"learners/discuss.md" "42ad66ab1907e030914dbb2a94376a47" "site/built/discuss.md" "2023-11-10" +"learners/reference.md" "c91dec1b149883b985376c211c6eba3e" "site/built/reference.md" "2023-11-10" +"learners/setup.md" "617894179d03d28c84916feeb439d542" "site/built/setup.md" "2023-11-10" +"profiles/learner-profiles.md" "60b93493cf1da06dfd63255d73854461" "site/built/learner-profiles.md" "2023-11-10" +"renv/profiles/lesson-requirements/renv.lock" "14ffda8a8a972130d31f6d9df4ec63ca" "site/built/renv.lock" "2023-11-10" diff --git a/reference.md b/reference.md new file mode 100644 index 00000000..a76317f3 --- /dev/null +++ b/reference.md @@ -0,0 +1,337 @@ +--- +title: 'Referencia' +--- + +## Referencia + +## [Introducción a R y RStudio](episodes/01-rstudio-intro.md) + +- Usa la tecla **escape** para cancelar comandos incompletos o código en ejecución + (Ctrl+C) si estas usando R desde el **shell**. +- Las operaciones aritméticas básicas siguen el orden estándar de precedencia: + - Paréntesis: `(`, `)` + - Exponentes: `^` or `**` + - División: `/` + - Multiplicación: `*` + - Suma: `+` + - Resta: `-` +- La notación científica está disponible, por ejemplo: `2e-3` +- Cualquier cosa a la derecha de `#` es un comentario, R lo ignorará! +- Las funciones se denotan por `function_name()`. Las expresiones dentro de los paréntesis se evaluan antes de pasarse a la función, y las funciones se pueden anidar. +- Funciones matemáticas: `exp`, `sin`, `log`, `log10`, `log2` etc. +- Operadores de comparación: `<`, `<=`, `>`, `>=`, `==`, `!=` +- Usa `all.equal` para comparar valores numéricos! +- `<-` es el operador de asignación. Cualquier expresión a la derecha del operador es evaluada, luego se almacena en la variable nombrada a la izquierda. +- `ls` lista todas las variables y funciones que has creado +- `rm` puede utilizarse para borrarlas +- Al asignar valores a los argumentos de la función, debes usar `=`. + +## [Manejo de proyectos con RStudio](episodes/02-project-intro.md) + +- Para crear un nuevo proyecto, ve a File -> New Project +- Instala el paquete `packrat` para crear proyectos independientes +- `install.packages` para instalar paquetes desde CRAN +- `library` para cargar un paquete en R +- `packrat::status` para verificar si se han instalado todos los paquetes a los que se hace referencia en tus **scripts**. + +## [Buscando ayuda](episodes/03-seeking-help.md) + +- Para acceder a la ayuda de una función `?function_name` o `help(function_name)` +- Usa comillas para operadores especiales, por ejemplo: `?"+"` +- Utiliza la búsqueda ambigua si no puedes recordar un nombre `??search_term` +- [CRAN task views](https://cran.at.r-project.org/web/views) son un buen punto de partida. +- [Stack Overflow](https://stackoverflow.com/) es un buen lugar para obtener ayuda con tu código. + - `?dput` Guardará datos que estás trabajando, para que otros puedan cargarlos fácilmente. + - `sessionInfo()` te dará detalles de tu configuración. + +## [Estructuras de datos](episodes/04-data-structures-part1.md) + +Los valores atómicos en R deben ser de alguno de los 5 **tipos de datos**, múltiples valores se pueden agrupar en **estructuras de datos**. + +**Tipos de datos** + +- `typeof(object)` proporciona información sobre el tipo de dato de un objeto. + +- Existen 5 tipos de datos principales: + + - `?numeric` números reales(decimal) + - `?integer` sólo números enteros + - `?character` texto + - `?complex` números complejos + - `?logical` valores **TRUE** o **FALSE** + + **Tipos especiales:** + + - `?NA` valores faltantes + - `?NaN` "no es número" para valores indefinidos (por ejemplo, `0/0`). + - `?Inf`, `-Inf` infinito. + - `?NULL` una estructura de datos que no existe + + `NA` puede ocurrir en cualquier vector atómico. `NaN`, and `Inf` sólo pueden aparecer en vectores de tipo **complex**, **integer** o **numeric**. Los vectores atómicos son los bloques de construcción para todas las demás estructuras de datos. Un valor `NULL` ocurrirá en una estructura de datos entera (pero puede ocurrir como lista de elementos). + +**Estructuras de datos básicas en R:** + +- `?vector` atómico (sólo puede contener un tipo de dato) +- `?list` (contenedores para otros objetos) +- `?data.frame` objetos bidimensionales cuyas columnas pueden contener diferentes tipos de datos +- `?matrix` objeto bidimensional que puede contener sólo un tipo de dato. +- `?factor` vectores que contienen datos categóricos predefinidos. +- `?array` objeto multi-dimensional que puede contener sólo un tipo de dato. + +Recuerda que las matrices son realmente vectores atómicos, y que los +**data.frames** son realmente listas(esto explica algunos de los comportamientos extraños de R). + +**[Vectores](episodes/04-data-structures-part1.md)** + +- `?vector()` Todos los elementos del vector deben ser del mismo tipo. +- Los elementos se pueden convertir de un tipo a otro utilizando *coerción*. +- La función concatenar 'c()' agrega elementos al vector. +- `seq(from=0, to=1, by=1)` crea una secuencia de números. +- Los elementos de un vector se pueden nombrar usando la función `names()`. + +**[Factores](episodes/04-data-structures-part1.md)** + +- `?factor()` Los factores son una estructura de datos diseñada para almacenar datos categóricos. +- `levels()` muestra los valores válidos que se pueden almacenar en un vector de tipo factor. + +**[Listas](episodes/04-data-structures-part1.md)** + +- `?list()` Las listas son una estructura de datos diseñada para almacenar datos de diferente tipos. + +**[Matrices](episodes/04-data-structures-part1.md)** + +- `?matrix()` Las matrices son una estructura de datos diseñada para almacenar datos bidimensionales. + +**[Data Frames](episodes/05-data-structures-part2.md)** + +- `?data.frame` es una estructura de datos clave. Es una `lista` de `vectores`. +- `cbind()` agregará una columna (vector) a un **data.frame**. +- `rbind()` agregará un renglón (list) a un **data.frame**. + +**Funciones útiles para consultar estructuras de datos:** + +- `?str` estructura, imprime un resumen de toda la estructura de datos +- `?typeof` te dice el tipo dentro de un vector atómico +- `?class` Indica cual es la estructura de datos +- `?head` Imprime los primeros `n` elementos (filas para objetos bidimensionales) +- `?tail` imprime los últimos `n` elementos (filas para objetos bidimensionales) +- `?rownames`, `?colnames`, `?dimnames` recupera o modifica los nombres de fila y columna de un objeto. +- `?names` recupera o modifica los nombres de un vector o lista atómica (o columnas de un **dataframe**). +- `?length` obtiene el número de elementos de un vector atómico +- `?nrow`, `?ncol`, `?dim` obtiene las dimensiones de un objeto n-dimensional + (No funcionará en vectores o listas atómicas). + +## [Explorando Dataframes](episodes/05-data-structures-part2.md) + +- `read.csv` para leer datos en una estructura regular + - `sep` argumento para especificar el separador + - "," para valores separados por coma + - "\\t" para valores separados por tabulador + - Otros argumentos: + - `header=TRUE` si hay una fila de encabezado + +## [Subconjunto de datos](episodes/06-data-subsetting.md) + +- Se puede acceder a los elementos por: + + - Indice + - Nombre + - Vectores lógicos + +- `[` corchetes: + + - *extrae* elementos individuales o **subset** de vectores + - por ejemplo,`x[1]` extrae el primer elemento del vector x. + - *extrae* elementos individuales de una lista. El valor devuelto será otra `list()`. + - *extrae* columnas de un **data.frame**. + +- `[` con dos argumentos para: + + - *extrae* filas y/o columnas de + - matrices + - **data.frames** + - por ejemplo: `x[1,2]` extraerá el valor de la fila 1, columna 2. + - por ejemplo: `x[2,:]` extraerá toda la segunda fila. + +- `[[` dobles corchetes para extraer elementos de las listas. + +- `$` para acceder a columnas o listar elementos por nombre + +- índices negativos omiten elementos + +## [Control de flujo](episodes/07-control-flow.md) + +- Usa la condición `if` para iniciar una instrucción condicional, `else if` para proporcionar pruebas adicionales, y `else` para proporcionar un valor predeterminado. +- Las instrucciones que se encuentran entre las llaves de las declaraciones condicionales deben estar indentadas. +- Usa `==` para probar la igualdad. +- `X && Y` sólo es cierto si tanto X como Y son `TRUE`. +- `X || Y` es cierto si ya sea X o Y, o ambos, son `TRUE`. +- Cero se considera `FALSE`; todos los demás números se consideran `TRUE` +- Anidar loops para operar en datos multidimensionales. + +## [Creación de gráficos con calidad para publicación](episodes/08-plot-ggplot2.md) + +- las figuras se pueden crear con la gramática de los gráficos: + - `library(ggplot2)` + - `ggplot` para crear la figura base + - `aes`especifica la estética de los ejes de datos, la forma, color y tamaño + - `geom`especifica el tipo de gráfico, por ejemplo, `point`, `line`, `density`, `box` + - `geom`agrega también transformaciones estadísticas, por ejemplo. `geom_smooth` + - `scale` funciones que controla la relación entre los valores de los datos y los valores visuales o estéticos + - `facet` funciones para estratificar la figura en paneles + - `aes` Las características estéticas se aplican a capas individuales, o se pueden establecer para todo el gráfico dentro de `ggplot`. + - `theme` cambia el aspecto general del gráfico + - ¡El orden de las capas importa! + - `ggsave` salva una figura. + +## [Vectorización](episodes/09-vectorization.md) + +- La mayoría de las funciones y operaciones se aplican a cada elemento de un vector +- `*` la multiplicación de elemento a elemento +- `%*%` para una verdadera multiplicación de matrices +- `any()` regresará `TRUE` si cualquier elemento de un vector es `TRUE` +- `all()` regresará `TRUE` si *todos* los elementos de un vector son `TRUE` + +## [Funciones](episodes/10-functions.md) + +- `?"function"` +- Coloque el código cuyos parámetros cambian frecuentemente en una función, luego llámelo con diferentes valores de parámetros para personalizar su comportamiento. +- Se devuelve la última línea de una función, o puede usar `return` explícitamente +- Cualquier código escrito en el cuerpo de la función buscará preferiblemente variables definidas dentro de la función +- Documente ¿por qué?, luego ¿qué?, y finalmente ¿cómo? (si el código no se explica por sí mismo) + +## [Escribiendo datos](episodes/11-writing-data.md) + +- `write.table` para escribir objetos en formato regular +- asigna `quote = FALSE` para que el texto no sea envuelto entre comillas ` "` + +## [Split-apply-combine](episodes/12-plyr.md) + +- Use la familia de funciones `xxply` para aplicar funciones a grupos dentro de algunos datos. +- la primera letra, `a`rray,`d`ata.frame o `l`ist corresponde a los datos de entrada +- la segunda letra denota la estructura de datos de salida +- Las funciones anónimas (aquellas que no tienen un nombre asignado) se usan dentro de la familia de funciones `plyr` + en grupos dentro de los datos. + +## [Manejo de dataframe con dplyr](episodes/13-dplyr.md) + +- `library(dplyr)` +- `?select` extrae variables por nombre. +- `?filter` regresa filas que coincidan con las condiciones. +- `?group_by` agrupa datos por una de muchas variables. +- `?summarize` resume valores múltiples a un solo valor. +- `?mutate` agrega nuevas variables a un **data.frame**. +- Combina operaciones usando el operador **pipe** `?"%>%"`. + +## [Manejo de dataframe con tidyr](episodes/14-tidyr.md) + +- `library(tidyr)` +- '?gather' convierte datos del formato *ancho* al *largo*. +- '?spread' convierte datos del formato *largo* al *ancho*. +- '?separate' separa un único valor en múltiples valores. +- '?unite' fusionar valores múltiples en un solo valor. + +## [Generando reportes con knitr](episodes/15-knitr-markdown.md) + +- Valor de informes reproducibles +- Conceptos básicos de Markdown +- fragmentos de código R +- Opciones de fragmentos +- Código R en línea +- Otros formatos de salida + +## [Buenas prácticas para escribir un buen código](episodes/16-wrap-up.md) + +- Programa defensivamente, es decir, asume que van a surgir errores y escribe el código para detectarlos cuando surjan. +- Escriba pruebas antes de escribir el código para ayudar a determinar exactamente qué se supone que debe hacer ese código. +- Conoce que se supone hace el código, antes de tratar de corregirlo. +- Haz que falle cada vez. +- Haz que falle rápido. +- Cambia una cosa a la vez, y por una razón. +- Ten un registro de lo que has hecho. +- Se humilde. + +## Glosario + +[argument]{#argument} +: Un valor dado a una función o programa cuando se ejecuta. +El término a menudo se usa indistintamente (y de manera inconsistente) con [parámetro](#parameter). + +[assign]{#assign} +: Para darle a un valor un nombre asociandolo a una variable. + +[body]{#body} +: (de una función): las instrucciones que se ejecutan cuando se ejecuta una función. + +[comment]{#comment} +: Una observación en un programa que pretende ayudar a los lectores humanos a comprender lo que está sucediendo, +pero es ignorado por la computadora. +Los comentarios en Python, R y el shell de Unix comienzan con un caracter `#` y se ejecutan hasta el final de la linea; +los comentarios en SQL comienzan con `--`, +y otros idiomas tienen otras convenciones. + +[comma-separated values]{#comma-separated-values} +: (CSV) Una representación textual común para tablas +en el cual los valores en cada fila están separados por comas. + +[delimiter]{#delimiter} +: Un caracter or caracteres usados para separar valores individuales, +tales como las comas entre columnas en un archivo [CSV](#comma-separated-values). + +[documentation]{#documentation} +: Texto en lenguaje humano escrito para explicar lo que hace el software +cómo funciona, o cómo usarlo. + +[floating-point number]{#floating-point-number} +: Un número que contiene una parte fraccionaria y un exponente. +Ver también: [integer](#integer). + +[for loop]{#for-loop} +: Un ciclo que se ejecuta una vez para cada valor en algún tipo de conjunto, lista o rango. +Ver también: [while loop](#while-loop). + +[index]{#index} +: Un subíndice que especifica la ubicación de un único valor en una colección, +como un solo píxel en una imagen. + +[integer]{#integer} +: Un número entero, como -12343. +Ver también: [floating-point number](#floating-point-number). + +[library]{#library} +: En R, es el directorio(s) donde los [paquetes](#package) son almacenados. + +[package]{#package} +: Una colección de funciones R, datos y código compilado en un formato bien definido. Los paquetes se almacenan en una [biblioteca](#library) y se cargan usando la función de library(). + +[parameter]{#parameter} +: Nombre de variable en la declaración de la función que se usa para guardar un valor cuando la función es llamada. +El término a menudo se usa indistintamente (y de manera inconsistente) con [argumento](#argumento). + +[return statement]{#return-statement} +: Una declaración que hace que una función deje de ejecutarse y devuelva un valor en donde fue llamada. + +[sequence]{#sequence} +: Una colección de información que se presenta en un orden específico. + +[shape]{#shape} +: Las dimensiones de una matriz, representadas como un vector. +Por ejemplo, una forma de matriz de 5 × 3 es `(5,3)`. + +[string]{#string} +: Abreviatura de "cadena de caracteres", +una [secuencia](#sequence) de cero o más caracteres. + +[syntax error]{#syntax-error} +: Un error de programación que ocurre cuando las instrucciones están en un orden o contienen caracteres no esperados por el lenguaje de programación. + +[type]{#type} +: La clasificación de algo en un programa (por ejemplo, el contenido de una variable) +como un tipo de número (por ejemplo [floating-point](#float), [integer](#integer)), [string](#string), +o algo más. En R el comando typeof() se usa para consultar el tipo de una variable. + +[while loop]{#while-loop} +: Un bucle que se ejecuta siempre que una condición dada sea verdadera. +Ver también: [for loop](#for-loop). + + diff --git a/renv.lock b/renv.lock new file mode 100644 index 00000000..b5e8065a --- /dev/null +++ b/renv.lock @@ -0,0 +1,1088 @@ +{ + "R": { + "Version": "4.3.1", + "Repositories": [ + { + "Name": "carpentries", + "URL": "https://carpentries.r-universe.dev" + }, + { + "Name": "carpentries_archive", + "URL": "https://carpentries.github.io/drat" + }, + { + "Name": "CRAN", + "URL": "https://cran.rstudio.com" + } + ] + }, + "Packages": { + "DiagrammeR": { + "Package": "DiagrammeR", + "Version": "1.0.10", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "RColorBrewer", + "downloader", + "dplyr", + "glue", + "htmltools", + "htmlwidgets", + "igraph", + "magrittr", + "purrr", + "readr", + "rlang", + "rstudioapi", + "scales", + "stringr", + "tibble", + "tidyr", + "viridis", + "visNetwork" + ], + "Hash": "f3de4a4878163a4629a528bbcc6e655d" + }, + "MASS": { + "Package": "MASS", + "Version": "7.3-60", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "graphics", + "methods", + "stats", + "utils" + ], + "Hash": "a56a6365b3fa73293ea8d084be0d9bb0" + }, + "Matrix": { + "Package": "Matrix", + "Version": "1.6-1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "graphics", + "grid", + "lattice", + "methods", + "stats", + "utils" + ], + "Hash": "1a00d4828f33a9d690806e98bd17150c" + }, + "R6": { + "Package": "R6", + "Version": "2.5.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "470851b6d5d0ac559e9d01bb352b4021" + }, + "RColorBrewer": { + "Package": "RColorBrewer", + "Version": "1.1-3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "45f0398006e83a5b10b72a90663d8d8c" + }, + "Rcpp": { + "Package": "Rcpp", + "Version": "1.0.11", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods", + "utils" + ], + "Hash": "ae6cbbe1492f4de79c45fce06f967ce8" + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "543776ae6848fde2f48ff3816d0628bc" + }, + "bit": { + "Package": "bit", + "Version": "4.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "d242abec29412ce988848d0294b208fd" + }, + "bit64": { + "Package": "bit64", + "Version": "4.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bit", + "methods", + "stats", + "utils" + ], + "Hash": "9fe98599ca456d6552421db0d6772d8f" + }, + "bslib": { + "Package": "bslib", + "Version": "0.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "cachem", + "grDevices", + "htmltools", + "jquerylib", + "jsonlite", + "memoise", + "mime", + "rlang", + "sass" + ], + "Hash": "283015ddfbb9d7bf15ea9f0b5698f0d9" + }, + "cachem": { + "Package": "cachem", + "Version": "1.0.8", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "fastmap", + "rlang" + ], + "Hash": "c35768291560ce302c0a6589f92e837d" + }, + "cli": { + "Package": "cli", + "Version": "3.6.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "89e6d8219950eac806ae0c489052048a" + }, + "clipr": { + "Package": "clipr", + "Version": "0.8.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "utils" + ], + "Hash": "3f038e5ac7f41d4ac41ce658c85e3042" + }, + "colorspace": { + "Package": "colorspace", + "Version": "2.1-0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "graphics", + "methods", + "stats" + ], + "Hash": "f20c47fd52fae58b4e377c37bb8c335b" + }, + "cpp11": { + "Package": "cpp11", + "Version": "0.4.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "707fae4bbf73697ec8d85f9d7076c061" + }, + "crayon": { + "Package": "crayon", + "Version": "1.5.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "grDevices", + "methods", + "utils" + ], + "Hash": "e8a1e41acf02548751f45c718d55aa6a" + }, + "digest": { + "Package": "digest", + "Version": "0.6.33", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "b18a9cf3c003977b0cc49d5e76ebe48d" + }, + "downloader": { + "Package": "downloader", + "Version": "0.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "digest", + "utils" + ], + "Hash": "f4f2a915e0dedbdf016a83b63477349f" + }, + "dplyr": { + "Package": "dplyr", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "R6", + "cli", + "generics", + "glue", + "lifecycle", + "magrittr", + "methods", + "pillar", + "rlang", + "tibble", + "tidyselect", + "utils", + "vctrs" + ], + "Hash": "e85ffbebaad5f70e1a2e2ef4302b4949" + }, + "ellipsis": { + "Package": "ellipsis", + "Version": "0.3.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "rlang" + ], + "Hash": "bb0eec2fe32e88d9e2836c2f73ea2077" + }, + "evaluate": { + "Package": "evaluate", + "Version": "0.23", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "daf4a1246be12c1fa8c7705a0935c1a0" + }, + "fansi": { + "Package": "fansi", + "Version": "1.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "utils" + ], + "Hash": "3e8583a60163b4bc1a80016e63b9959e" + }, + "farver": { + "Package": "farver", + "Version": "2.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "8106d78941f34855c440ddb946b8f7a5" + }, + "fastmap": { + "Package": "fastmap", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "f7736a18de97dea803bde0a2daaafb27" + }, + "fontawesome": { + "Package": "fontawesome", + "Version": "0.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "htmltools", + "rlang" + ], + "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d" + }, + "fs": { + "Package": "fs", + "Version": "1.6.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "47b5f30c720c23999b913a1a635cf0bb" + }, + "generics": { + "Package": "generics", + "Version": "0.1.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "methods" + ], + "Hash": "15e9634c0fcd294799e9b2e929ed1b86" + }, + "ggplot2": { + "Package": "ggplot2", + "Version": "3.4.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "MASS", + "R", + "cli", + "glue", + "grDevices", + "grid", + "gtable", + "isoband", + "lifecycle", + "mgcv", + "rlang", + "scales", + "stats", + "tibble", + "vctrs", + "withr" + ], + "Hash": "313d31eff2274ecf4c1d3581db7241f9" + }, + "glue": { + "Package": "glue", + "Version": "1.6.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "methods" + ], + "Hash": "4f2596dfb05dac67b9dc558e5c6fba2e" + }, + "gridExtra": { + "Package": "gridExtra", + "Version": "2.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "grDevices", + "graphics", + "grid", + "gtable", + "utils" + ], + "Hash": "7d7f283939f563670a697165b2cf5560" + }, + "gtable": { + "Package": "gtable", + "Version": "0.3.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "grid", + "lifecycle", + "rlang" + ], + "Hash": "b29cf3031f49b04ab9c852c912547eef" + }, + "highr": { + "Package": "highr", + "Version": "0.10", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "xfun" + ], + "Hash": "06230136b2d2b9ba5805e1963fa6e890" + }, + "hms": { + "Package": "hms", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "lifecycle", + "methods", + "pkgconfig", + "rlang", + "vctrs" + ], + "Hash": "b59377caa7ed00fa41808342002138f9" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "base64enc", + "digest", + "ellipsis", + "fastmap", + "grDevices", + "rlang", + "utils" + ], + "Hash": "2d7b3857980e0e0d0a1fd6f11928ab0f" + }, + "htmlwidgets": { + "Package": "htmlwidgets", + "Version": "1.6.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "grDevices", + "htmltools", + "jsonlite", + "knitr", + "rmarkdown", + "yaml" + ], + "Hash": "a865aa85bcb2697f47505bfd70422471" + }, + "igraph": { + "Package": "igraph", + "Version": "1.5.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "Matrix", + "R", + "cli", + "cpp11", + "grDevices", + "graphics", + "lifecycle", + "magrittr", + "methods", + "pkgconfig", + "rlang", + "stats", + "utils" + ], + "Hash": "80401cb5ec513e8ddc56764d03f63669" + }, + "isoband": { + "Package": "isoband", + "Version": "0.2.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "grid", + "utils" + ], + "Hash": "0080607b4a1a7b28979aecef976d8bc2" + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "htmltools" + ], + "Hash": "5aab57a3bd297eee1c1d862735972182" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "1.8.7", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "methods" + ], + "Hash": "266a20443ca13c65688b2116d5220f76" + }, + "knitr": { + "Package": "knitr", + "Version": "1.45", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "evaluate", + "highr", + "methods", + "tools", + "xfun", + "yaml" + ], + "Hash": "1ec462871063897135c1bcbe0fc8f07d" + }, + "labeling": { + "Package": "labeling", + "Version": "0.4.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "graphics", + "stats" + ], + "Hash": "b64ec208ac5bc1852b285f665d6368b3" + }, + "lattice": { + "Package": "lattice", + "Version": "0.22-5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "graphics", + "grid", + "stats", + "utils" + ], + "Hash": "7c5e89f04e72d6611c77451f6331a091" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cli", + "glue", + "rlang" + ], + "Hash": "001cecbeac1cff9301bdc3775ee46a86" + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "7ce2733a9826b3aeb1775d56fd305472" + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "cachem", + "rlang" + ], + "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" + }, + "mgcv": { + "Package": "mgcv", + "Version": "1.9-0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "Matrix", + "R", + "graphics", + "methods", + "nlme", + "splines", + "stats", + "utils" + ], + "Hash": "086028ca0460d0c368028d3bda58f31b" + }, + "mime": { + "Package": "mime", + "Version": "0.12", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "tools" + ], + "Hash": "18e9c28c1d3ca1560ce30658b22ce104" + }, + "munsell": { + "Package": "munsell", + "Version": "0.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "colorspace", + "methods" + ], + "Hash": "6dfe8bf774944bd5595785e3229d8771" + }, + "nlme": { + "Package": "nlme", + "Version": "3.1-163", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "graphics", + "lattice", + "stats", + "utils" + ], + "Hash": "8d1938040a05566f4f7a14af4feadd6b" + }, + "pillar": { + "Package": "pillar", + "Version": "1.9.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "cli", + "fansi", + "glue", + "lifecycle", + "rlang", + "utf8", + "utils", + "vctrs" + ], + "Hash": "15da5a8412f317beeee6175fbc76f4bb" + }, + "pkgconfig": { + "Package": "pkgconfig", + "Version": "2.0.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "utils" + ], + "Hash": "01f28d4278f15c76cddbea05899c5d6f" + }, + "plyr": { + "Package": "plyr", + "Version": "1.8.9", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "Rcpp" + ], + "Hash": "6b8177fd19982f0020743fadbfdbd933" + }, + "prettyunits": { + "Package": "prettyunits", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "6b01fc98b1e86c4f705ce9dcfd2f57c7" + }, + "progress": { + "Package": "progress", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R6", + "crayon", + "hms", + "prettyunits" + ], + "Hash": "14dc9f7a3c91ebb14ec5bb9208a07061" + }, + "purrr": { + "Package": "purrr", + "Version": "1.0.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "lifecycle", + "magrittr", + "rlang", + "vctrs" + ], + "Hash": "1cba04a4e9414bdefc9dcaa99649a8dc" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "5e3c5dc0b071b21fa128676560dbe94d" + }, + "readr": { + "Package": "readr", + "Version": "2.1.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "cli", + "clipr", + "cpp11", + "crayon", + "hms", + "lifecycle", + "methods", + "rlang", + "tibble", + "tzdb", + "utils", + "vroom" + ], + "Hash": "b5047343b3825f37ad9d3b5d89aa1078" + }, + "renv": { + "Package": "renv", + "Version": "1.0.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "utils" + ], + "Hash": "41b847654f567341725473431dd0d5ab" + }, + "rlang": { + "Package": "rlang", + "Version": "1.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "50a6dbdc522936ca35afc5e2082ea91b" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.25", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bslib", + "evaluate", + "fontawesome", + "htmltools", + "jquerylib", + "jsonlite", + "knitr", + "methods", + "stringr", + "tinytex", + "tools", + "utils", + "xfun", + "yaml" + ], + "Hash": "d65e35823c817f09f4de424fcdfa812a" + }, + "rstudioapi": { + "Package": "rstudioapi", + "Version": "0.15.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "5564500e25cffad9e22244ced1379887" + }, + "sass": { + "Package": "sass", + "Version": "0.4.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R6", + "fs", + "htmltools", + "rappdirs", + "rlang" + ], + "Hash": "6bd4d33b50ff927191ec9acbf52fd056" + }, + "scales": { + "Package": "scales", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "RColorBrewer", + "farver", + "labeling", + "lifecycle", + "munsell", + "rlang", + "viridisLite" + ], + "Hash": "906cb23d2f1c5680b8ce439b44c6fa63" + }, + "stringi": { + "Package": "stringi", + "Version": "1.7.12", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "stats", + "tools", + "utils" + ], + "Hash": "ca8bd84263c77310739d2cf64d84d7c9" + }, + "stringr": { + "Package": "stringr", + "Version": "1.5.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "magrittr", + "rlang", + "stringi", + "vctrs" + ], + "Hash": "671a4d384ae9d32fc47a14e98bfa3dc8" + }, + "tibble": { + "Package": "tibble", + "Version": "3.2.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "fansi", + "lifecycle", + "magrittr", + "methods", + "pillar", + "pkgconfig", + "rlang", + "utils", + "vctrs" + ], + "Hash": "a84e2cc86d07289b3b6f5069df7a004c" + }, + "tidyr": { + "Package": "tidyr", + "Version": "1.3.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "cpp11", + "dplyr", + "glue", + "lifecycle", + "magrittr", + "purrr", + "rlang", + "stringr", + "tibble", + "tidyselect", + "utils", + "vctrs" + ], + "Hash": "e47debdc7ce599b070c8e78e8ac0cfcf" + }, + "tidyselect": { + "Package": "tidyselect", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "rlang", + "vctrs", + "withr" + ], + "Hash": "79540e5fcd9e0435af547d885f184fd5" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.48", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "xfun" + ], + "Hash": "8f96d229b7311beb32b94cf413b13f84" + }, + "tzdb": { + "Package": "tzdb", + "Version": "0.4.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cpp11" + ], + "Hash": "f561504ec2897f4d46f0c7657e488ae1" + }, + "utf8": { + "Package": "utf8", + "Version": "1.2.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "62b65c52671e6665f803ff02954446e9" + }, + "vctrs": { + "Package": "vctrs", + "Version": "0.6.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "rlang" + ], + "Hash": "266c1ca411266ba8f365fcc726444b87" + }, + "viridis": { + "Package": "viridis", + "Version": "0.6.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "ggplot2", + "gridExtra", + "viridisLite" + ], + "Hash": "80cd127bc8c9d3d9f0904ead9a9102f1" + }, + "viridisLite": { + "Package": "viridisLite", + "Version": "0.4.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "c826c7c4241b6fc89ff55aaea3fa7491" + }, + "visNetwork": { + "Package": "visNetwork", + "Version": "2.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "htmltools", + "htmlwidgets", + "jsonlite", + "magrittr", + "methods", + "stats", + "utils" + ], + "Hash": "3e48b097e8d9a91ecced2ed4817a678d" + }, + "vroom": { + "Package": "vroom", + "Version": "1.6.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bit64", + "cli", + "cpp11", + "crayon", + "glue", + "hms", + "lifecycle", + "methods", + "progress", + "rlang", + "stats", + "tibble", + "tidyselect", + "tzdb", + "vctrs", + "withr" + ], + "Hash": "9db52c1656cf19c124f93124ea57f0fd" + }, + "withr": { + "Package": "withr", + "Version": "2.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "grDevices", + "graphics", + "stats" + ], + "Hash": "4b25e70111b7d644322e9513f403a272" + }, + "xfun": { + "Package": "xfun", + "Version": "0.41", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "stats", + "tools" + ], + "Hash": "460a5e0fe46a80ef87424ad216028014" + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.7", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "0d0056cc5383fbc240ccd0cb584bf436" + } + } +} diff --git a/setup.md b/setup.md new file mode 100644 index 00000000..c3f51813 --- /dev/null +++ b/setup.md @@ -0,0 +1,13 @@ +--- +title: Configuración +--- + +Esta lección supone que tienes el software R y RStudio instalado en tu computadora. + +R se puede descargar [aquí](https://cran.r-project.org/mirrors.html). + +RStudio es un entorno de desarrollo integrado para R. +Se puede descargar [aquí](https://www.rstudio.com/products/rstudio/download/). +Necesitarás la versión de escritorio para tu computadora. + +