Skip to content

Commit

Permalink
revisión código
Browse files Browse the repository at this point in the history
  • Loading branch information
rivaquiroga committed May 22, 2019
1 parent 01c2609 commit c06e450
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 72 deletions.
2 changes: 1 addition & 1 deletion 03-visualize.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ El ajuste de `position = identity` es más útil para geoms 2-D, como puntos, do

```{r}
ggplot(data = diamantes) +
geom_bar(mapping = aes(x = corte, fill = claridad), position = "dodge")
geom_bar(mapping = aes(x = corte, fill = claridad), position = "fill")
```

* `position = "dodge"` coloca objetos superpuestos directamente uno al lado del otro. Esto hace que sea más fácil comparar valores individuales.
Expand Down
8 changes: 4 additions & 4 deletions 05-transform.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ La visualización es una herramienta importante para para la generación de cono
En este capítulo nos enfocaremos en cómo usar el paquete **dplyr**, otro miembro central de tidyverse. Ilustraremos las ideas clave con el conjunto de datos *vuelos* que aparecen originalmente en el paquete **nycflights13**, pero para este caso utilizaremos la versión traducida incluida en el paquete **datos** y usaremos **ggplot2** para ayudarnos a comprender los datos.

```{r setup, message = FALSE, cache = FALSE}
#devtools::install_github("cienciadedatos/datos")
#remotes::install_github("cienciadedatos/datos")
library(datos)
library(tidyverse)
```
Expand Down Expand Up @@ -222,9 +222,9 @@ arrange(vuelos, anio, mes, dia)

Usa `desc()` para reordenar por una columna en orden descendente:

`` `{r}
```{r}
arrange(vuelos, desc(atraso_salida))
`` `
```

Los valores faltantes siempre se ordenan al final:

Expand Down Expand Up @@ -584,7 +584,7 @@ Cuando graficas la habilidad del bateador (medido por el promedio de bateo, `ba`

```{r}
# Convierte a tibble para puedas imprimirlo de una manera legible
bateo <- as_tibble(bateadores)
bateo <- as_tibble(datos::bateadores)
rendimiento_bateadores <- bateo %>%
group_by(ID_jugador) %>%
Expand Down
4 changes: 2 additions & 2 deletions 10-tibble.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Los tibbles están diseñados para no inundar tu consola accidentalmente al mira
Primero, puedes usar `print()` en el data frame y controlar el número de filas (`n`) y el ancho (`width`) mostrado. Por otro lado, `width = Inf` muestra todas las columnas:

```{r, eval = FALSE}
vuelos %>%
datos::vuelos %>%
print(n = 10, width = Inf)
```

Expand All @@ -100,7 +100,7 @@ Puedes ver una lista completa de opciones en la ayuda del paquete con `package?t
La opción final es usar el visualizador de datos de RStudio para obtener una versión interactiva del data frame completo. Esto también es útil luego de realizar una larga cadena de manipulaciones.

```{r, eval = FALSE}
vuelos %>%
datos::vuelos %>%
View()
```

Expand Down
24 changes: 12 additions & 12 deletions 12-tidy.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,12 @@ Como te habrás dado cuenta a partir de los argumentos comunes `key` y `value`,
Observa cuidadosamente el siguiente ejemplo:
```{r, eval = FALSE}
stocks <- tibble(
acciones <- tibble(
anio = c(2015, 2015, 2016, 2016),
semestre = c(1, 2, 1, 2),
retorno = c(1.88, 0.59, 0.92, 0.17)
)
stocks %>%
acciones %>%
spread(anio, retorno) %>%
gather("anio", "retorno", `2015`:`2016`)
```
Expand All @@ -217,7 +217,7 @@ tabla4a %>%

```{r}
personas <- tribble(
~nombre, ~llave, ~valor,
~nombre, ~clave, ~valor,
#-----------------|--------|------
"Phillip Woods", "edad", 45,
"Phillip Woods", "estatura", 186,
Expand All @@ -232,7 +232,7 @@ personas <- tribble(
```{r}
embarazo <- tribble(
~embarazo, ~hombre, ~mujer,
"si", NA, 10,
"", NA, 10,
"no", 20, 12
)
```
Expand Down Expand Up @@ -426,15 +426,15 @@ Existen múltiples valores faltantes en la representación actual, por lo que de

```{r}
oms1 <- oms %>%
gather(nuevos_fpp_h014:nuevosrecaida_m65, key = "llave", value = "casos", na.rm = TRUE)
gather(nuevos_fpp_h014:nuevosrecaida_m65, key = "clave", value = "casos", na.rm = TRUE)
oms1
```

Podemos tener una noción de la estructura de los valores en la nueva columna `llave` si hacemos un conteo:
Podemos tener una noción de la estructura de los valores en la nueva columna `clave` si hacemos un conteo:

```{r}
oms1 %>%
count(llave)
count(clave)
```

Puedes deducir lo siguiente por cuenta propia pensando y experimentando un poco, pero afortunadamente tenemos el diccionario de datos a mano. Este nos dice lo siguiente:
Expand Down Expand Up @@ -465,15 +465,15 @@ Necesitamos hacer un pequeño cambio al formato de los nombres de las columnas:

```{r}
oms2 <- oms1 %>%
mutate(llave = stringr::str_replace(llave, "nuevosrecaida", "nuevos_recaida"))
mutate(clave = stringr::str_replace(clave, "nuevosrecaida", "nuevos_recaida"))
oms2
```

Podemos separar los valores en cada código aplicando `separate()` dos veces. La primera aplicación dividirá los códigos en cada `_`.

```{r}
oms3 <- oms2 %>%
separate(llave, c("nuevos", "tipo", "sexo_edad"), sep = "_")
separate(clave, c("nuevos", "tipo", "sexo_edad"), sep = "_")
oms3
```

Expand All @@ -500,9 +500,9 @@ Hemos mostrado el código parte por parte, asignando los resultados intermedios

```{r, results = "hide"}
oms %>%
gather(llave, valor, nuevos_fpp_h014:nuevosrecaida_m65, na.rm = TRUE) %>%
mutate(llave = stringr::str_replace(llave, "nuevosrecaida", "nuevos_recaida")) %>%
separate(llave, c("nuevos", "tipo", "sexo_edad")) %>%
gather(clave, valor, nuevos_fpp_h014:nuevosrecaida_m65, na.rm = TRUE) %>%
mutate(clave = stringr::str_replace(clave, "nuevosrecaida", "nuevos_recaida")) %>%
separate(clave, c("nuevos", "tipo", "sexo_edad")) %>%
select(-nuevos, -iso2, -iso3) %>%
separate(sexo_edad, c("sexo", "edad"), sep = 1)
```
Expand Down
7 changes: 3 additions & 4 deletions 15-factors.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ levels(f2)
Por el resto del capítulo, nos vamos a concentrar en `encuesta`. Ésta es la versión traducida al español de un conjunto de datos de ejemplo de [General Social Survey](http://gss.norc.org); ésta es una encuesta realizada en Estados Unidos desde hace mucho tiempo, conducida por la organización de investigación independiente llamada NORC, en la Universidad de Chicago. La encuesta tiene miles de preguntas, así que en el conjunto de datos he seleccionado aquellas que ilustran algunos de los desafíos comunes que encontrarás al trabajar con factores.

```{r}
library(datos)
encuesta
```

Expand Down Expand Up @@ -290,9 +289,9 @@ Si quieres colapsar muchos niveles, `fct_collapse()` (del inglés, _colapsar fac
encuesta %>%
mutate(partido = fct_collapse(partido,
otro = c("Sin respuesta", "No sabe", "Otro partido"),
republicano = c("Republicano Acérrimo", "Republicado No Acérrimo"),
independiente = c("Independiente, pro-Rep", "Independiente", "Independiente, pro-Dem"),
democrata = c("Demócrata No Acérrimo", "Demócrata Acérrimo")
republicano = c("Republicano duro", "Republicado moderado"),
independiente = c("Independiente pro republicano", "Independiente", "Independiente pro demócrata"),
democrata = c("Demócrata moderado", "Demócrata duro")
)) %>%
count(partido)
```
Expand Down
4 changes: 2 additions & 2 deletions 16-datetimes.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ Los datos de fecha/hora a menudo vienen como cadenas de caracteres. Ya has visto

```{r}
ymd("2017-01-31")
mdy("Enero 31, 2017")
dmy("31-Ene-2017")
mdy("enero 31, 2017")
dmy("31-ene-2017")
```

Estas funciones también reciben números sin comillas. Esta es la forma más concisa de crear un sólo objeto fecha/hora, ya que puedes necesitarlo cuando filtres datos temporales. `ymd()` (del inglés _año-mes-día_) es corto y no ambigüo:
Expand Down
22 changes: 12 additions & 10 deletions 20-vectors.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Hasta ahora este libro se ha enfocado en tibbles y sus paquetes correspondientes
Los vectores son particularmente importantes, al igual que la mayoría de las funciones que escribirás y utilizarás con dichos vectores. Es posible desarrollar funciones que trabajen con tibbles (como ggplot2, dplyr and tidyr) pero las herramientas que necesitas para ello son peculiares e inmaduras. Por esto, estoy desarrollando un mejor enfoque, el cual puedes consultar en https://github.com/hadley/lazyeval, pero este no estará listo a tiempo para la publicación del libro. Incluso aún cuando esté completo, de todas maneras necesitarás entender el concepto de vectores, esto solo facilitará la escritura de capas finales que sean user-friendly (amigables al usuario).


## Pre-requisitos
### Pre-requisitos

Este capítulo se enfoca en las estructuras de datos de R base, por lo que no es esencial cargar ningún paquete. Sin embargo, usaremos un conjunto de funciones del paquete purrr para evitar algunas insonsistencias en R Base.

Expand Down Expand Up @@ -106,7 +106,7 @@ Ya has aprendido un montón acerca de cómo trabajar con strings en [strings]. E


```{r}
x <- "Esto es un string razonablemente largo."
x <- "Esta es una cadena razonablemente larga."
pryr::object_size(x)
y <- rep(x, 1000)
Expand Down Expand Up @@ -326,8 +326,10 @@ Hasta ahora hemos usado `dplyr::filter()` para filtrar filas en una TIBBLE. La s
## Vectores Recursivos (listas)
Las listas son un escalon más en complejidad partiendo de los vectores atómicos, debido a que las listas pueden contener otras listas. Lo cual las hace adecuadas para representar una estructura jerárquica o de tipo árbol. Puedes crear una lista con ´list()´:

x <- list(1, 2, 3) (del inglés lista)
```{r}
x <- list(1, 2, 3)
x
```
Un herramienta muy útil para trabajar con listas es ´str()´ ya que se enfoca en la estructura, no en los contenidos.
```{r}
str(x)
Expand All @@ -348,7 +350,7 @@ z <- list(list(1, 2), list(3, 4))
str(z)
```

## Visualizando listas
### Visualizando listas
Para explicar funciones de manipulacion de listas más complicadas, es útil tener una representacion visual de las mismas. Por ejemplo, defino estas tres listas:
```{r}
x1 <- list(c(1, 2), c(3, 4))
Expand All @@ -369,7 +371,7 @@ Existen tres principios, al momento de observer el gráfico anterior:
Subdivisión (Subsetting)
Existen tres maneras de subdividir una lista, lo cual ilustraré con una lista denominada ´a´:
```{r}
a <- list(a = 1:3, b = "a string", c = pi, d = list(-1, -5))
a <- list(a = 1:3, b = "una cadena", c = pi, d = list(-1, -5))
```
El corchete simple ´[´ extrae una sub-lista. Por lo que, el resultado siempre será una lista.

Expand Down Expand Up @@ -397,7 +399,7 @@ lists-subsetting, echo = FALSE, out.width = "75%", fig.cap = "Subdividir una lis
knitr::include_graphics("diagrams_w_text_as_path/es/lists-subsetting.png")
```

## Listas de Condimentos
### Listas de Condimentos
La diferencia entre ambos `[` y `[[` es muy importante, pero es muy fácil confundirlos. Para ayudarte a recordar, permiteme mostrarte un pimientero inusual
```{r, echo = FALSE, out.width = "25%"}
knitr::include_graphics("images/pepper.jpg")
Expand Down Expand Up @@ -435,8 +437,8 @@ Cualquier vector puede contener metadata arbitraria adicional mediante sus atrib
```{r}
x <- 1:10
attr(x, "saludo")
attr(x, "saludo") <- "Hola!"
attr(x, " despedida") <- "Adiós!"
attr(x, "saludo") <- "¡Hola!"
attr(x, " despedida") <- "¡Adiós!"
attributes(x)
```

Expand Down Expand Up @@ -499,9 +501,9 @@ attributes(x)
```
El atributo `tzone` es opcional. Este controla como se muestra la hora, y no hace referencia al tiempo en términos absolutos.
```{r}
attr(x, "tzone") <- "US/Pacifico"
attr(x, "tzone") <- "US/Pacific"
x
attr(x, "tzone") <- "US/ Oriental"
attr(x, "tzone") <- "US/Eastern"
x
```
Existe otro tipo de vector date-time llamado POSIXlt. Éstos son construidos en base a listas con nombres (named lists).
Expand Down
12 changes: 6 additions & 6 deletions 23-model-basics.Rmd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Conceptos básicos
# Modelos: conceptos básicos

## Introducción

Expand Down Expand Up @@ -353,12 +353,12 @@ Generar una función a partir de una fórmula es directo cuando el predictor es

```{r}
df <- tribble(
~sex, ~response,
"male", 1,
"female", 2,
"male", 1
~genero, ~respuesta,
"masculino", 1,
"femenino", 2,
"masculino", 1
)
model_matrix(df, response ~ sex)
model_matrix(df, respuesta ~ genero)
```

Quizá te preguntes por qué R no crea la columna `sexo_mujer`. El problema es que eso crearía una columna perfectamente predecible a partir de las otras columnas (es decir, `sexo_mujer = 1 - sexo_hombre`). Desafortunadamete los detalles exactos de por qué esto es un problema van más allá del alcance del libro, pero básicamente crea una familia de modelos que es muy flexible y genera infinitos modelos igualmente cercanos a los datos.
Expand Down
2 changes: 1 addition & 1 deletion 25-model-many.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ df %>%

(Si usas mucho este patrón, asegúrate de chequear `tidyr::separate_rows()` (del inglés _separar filas_) que es un _wrapper_ (TODO: cuando esté el capítulo de Joshua poner explicación) alrededor de este patrón común).

Otro ejemplo de este patrón es usar `map()`, `map2()`, `pmap()` de __purrr__. Por ejemplo, podríamos tomar el ejemplo final de [Invoking different functions] (TODO: chequear nombre en español) y reescribirlo usando `mutate()`:
Otroejemplo de este patrón es usar `map()`, `map2()`, `pmap()` de __purrr__. Por ejemplo, podríamos tomar el ejemplo final de [Invoking different functions] (TODO: chequear nombre en español) y reescribirlo usando `mutate()`:

```{r}
sim <- tribble(
Expand Down
50 changes: 25 additions & 25 deletions 27-rmarkdown.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Necesitas el paquete __rmarkdown__, pero no necesitas cargarlo o instalarlo expl
chunk <- "```"
inline <- function(x = "") paste0("`` `r ", x, "` ``")
library(tidyverse)
library(datos)
```

## R Markdown básico
Expand Down Expand Up @@ -207,37 +208,36 @@ Hay también una gran cantidad de opciones para controlar como las figuras estan
Normalmente, cada *knit* de un documento empieza desde una sesión limpia. Esto es genial para reproducibilidad, porque se asegura que has capturado cada cómputo importante en el código. Sin embargo, puede ser dolorosos si tienes cómputos que toman mucho tiempo. La solución es `cache = TRUE`. Cuando está funcionando, esto guarda el output del bloque a un archivo especialmente en el disco. En corridas subsecuentes, _knitr_ revisara si el código ha cambiado y si no ha cambiado, reutilizará los resultados del cache.

El sistema de cache debe ser usado con cuidado, porque por defecto está solo basado en el código, no en sus dependencias. Por ejemplo , aqui el bloque `datos_procesados` depende del bloque `datos_crudos`:

`r chunk`{r datos_crudos}
datos_crudos <- readr::read_csv("un_archivo_muy_grande.csv")
`r chunk`

`r chunk`{r datos_procesados, cache = TRUE}
datos_procesados <- datos_crudos %>%
filter(!is.na(variable_important)) %>%
mutate(nueva_variable = transformacion_complicada(x, y, z))
`r chunk`


`r chunk`{r datos_crudos}
datosCrudos <- readr::read_csv("un_archivo_muy_grande.csv")
`r chunk`

`r chunk`{r datos_procesados, cache = TRUE}
datosProcesados <- datosCrudos %>%
filter(!is.na(variableImportada)) %>%
mutate(nuevaVariable = transformacionComplicada(x, y, z))
`r chunk`

*Caching* el bloque `processed_data` significa que tendrás que re-ejecutar si cambia el pipeline de _dplyr_, pero no podrás re-ejecutarlo si cambia el `read_csv()`. Puedes evitar este problema con la opción de bloque `dependson`:

`r chunk`{r datos_procesados, cache = TRUE, dependson = "raw_data"}
datosProcesados <- datosCrudos %>%
filter(!is.na(variableImportada)) %>%
mutate(nuevaVariable = transformacionComplicada(x, y, z))
`r chunk`

`r chunk`{r datos_procesados, cache = TRUE, dependson = "datos_crudos"}
datos_procesados <- datos_crudos %>%
filter(!is.na(variable_important)) %>%
mutate(nueva_variable = transformacion_complicada(x, y, z))
`r chunk`


`dependson` debería incluir un vector de caracteres para *cada* bloque en el que el bloque cached dependa. _Knitr_ actualizará los resultados para el vector cached cada vez que detecta que una de sus dependencias ha cambiado.

Nota que los bloques de código no se actualizaran si el archivo `un_archivo_muy_grande.csv` cambia, porque _knitr_ hace *cache* solo los cambios dentro del archivo `.Rmd`. Si quieres seguir los cambios a ese archivo puedes usar la opción `cache.extra`. Esta es una expresión arbritaria de R que invalidará el *cache* cada vez que cambie. Una buena función a usar es `file.info()`: genera mucha información sobre el archivo incluyendo cuando fue su última modificación. Puedes escribir entonces:

`r chunk`{r raw_data, cache.extra = file.info("a_very_large_file.csv")}
rawdata <- readr::read_csv("a_very_large_file.csv")
`r chunk`

`r chunk`{r datos_crudos, cache.extra = file.info("un_archivo_muy_grande.csv")}
datosCrudos <- readr::read_csv("un_archivo_muy_grande.csv")
`r chunk`
`r chunk`{r datos_crudos, cache.extra = file.info("un_archivo_muy_grande.csv")}
datos_crudos <- readr::read_csv("un_archivo_muy_grande.csv")
`r chunk`

A medida que tus estrategias de *caching* se vuelven progresivamente mas complicadas, es una buena idea limpiar regularmente todos tus *caches* con `knitr::clean_cache()`.

Expand Down Expand Up @@ -268,13 +268,13 @@ Esto ocultará el código por defecto, así que solo mostrará los bloques que d
Hay otro modo de incluir código R en un documento R Markdown: directamente en el texto, con:`r inline()`. Esto puede ser muy útil si mencionas propiedades de tu datos en el texto. Por ejemplo, en el documento de ejemplo que utilice al comienzo del capitulo tenía:

> Tenemos datos sobre `r inline('nrow(diamonds)')` diamantes.
> Solo `r inline('nrow(diamonds) - nrow(smaller)')` son mayores que
> 2.5 quilates. La distribución de lo restante se muestra abajo:
> Solo `r inline('nrow(diamonds) - nrow(smaller)')` son de más de
> 2.5 quilates. La distribución de los restante se muestra a continuación:
Cuando hacemos *knit*, los resultados de estos computós estan insertos en el texto:

> Tenemos datos de 53940 diamantes. solo 126 son mas grandes que
> 2.5 quilates. La distribución de lo restante se muestra abajo:
> Tenemos datos de 53940 diamantes. Solo 126 son de más de
> 2.5 quilates. La distribución de los restante se muestra a continuación:
Cuando insertas números en el texto, `format()` es tu amigo. Esto permite establecer el número de `digitos` para que no imprimas con un grado rídiculo de precision, y una `big.mark` para hacer que los números sean mas fáciles de leer. Siempre combino estos en una función de ayuda:

Expand Down
Loading

0 comments on commit c06e450

Please sign in to comment.