forked from SCAR/EGABIcourse19
-
Notifications
You must be signed in to change notification settings - Fork 0
/
10_Introduction_to_R.Rmd
353 lines (268 loc) · 10.1 KB
/
10_Introduction_to_R.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# Introducción a `R` y a `Tidyverse`
[Presentation (PDF)](./course_material/tidyverse/Tidyverse.pdf)
## Ejercicio `R` script
El script se puede descargar en el siguiente link [downloaded here](./course_material/tidyverse/Intro_to_tidyverse.R) y también esta copiado abajo.
```{r eval = FALSE}
## Aquí cargamos el tidyverse. Tidyverse incluye múltiples paquetes que pueden
# trabajar juntos.
## Si lo cargamos directamente como lo hacemos aquí, nos arroja una tabla
#identificando todos los paquetes que están adjuntos.
library(tidyverse)
## también se puede ver una lista de funciones que arrojan conflictos - ver
#nombres de funciones que aparecen bajo múltiples paquetes
## Por ejemplo, Hay una función "filter" (filtro) repetida en los paquetes
#'stats'
## y en 'dplyr'. Mira las notas del curso sobre los prefijos de espacio de
# nombres (por ejemplo, los usos de "dplyr::filter()" a continuación).
library(broom)
library(readxl)
```
Carguemos el conjunto de datos (dataset) 'starwars' que se encuentra en el paquete dplyr (lo usaremos más adelante)
```{r}
data(starwars)
```
### Cargando datos
Usando la función `read.csv` de `R` base, las clases de las columnas se importan de manera deficiente y tendríamos que convertirlas manualmente más tarde.
```{r}
#Ubicacion de carpeta con datos
data_folder <- "docs/course_material/tidyverse/"
#Cargando datos
X.csv <- read.csv(file.path(data_folder, "tidyverse_dummy_import.csv"))
sapply(X.csv, class)
```
La biblioteca `readr` puede leer archivos `CSV` de mejor manera y las columnas se pueden definir mejor.
```{r}
X.csv_r <- read_csv(file.path(data_folder, "tidyverse_dummy_import.csv"),
col_types = list(Occurrence_field = col_factor()))
X.csv_r
```
La biblioteca `readxl` se utiliza para leer otros formatos de Excel y funciona bien para columnas de fecha y hora. Sin embargo, no tiene una opción de tipo de columna para factores (si quisieras definir una columna como factor).
```{r}
X.xlsx_t <- read_xlsx(file.path(data_folder, "tidyverse_dummy_import.xlsx"), 1,
col_types = c("guess", "numeric", "numeric", "text",
"date"))
## si necesitaras convertir una columna a factor puedes usar:
X.xlsx_t$Occurrence_field <- as.factor(X.xlsx_t$Occurrence_field)
```
### Manipulación de datos
Selecciona las columnas `name` (nombre), `gender` (género) y `homeworld` (mundo de origen).
```{r}
starwars |>
dplyr::select(name, gender, homeworld)
```
Ten en cuenta que usamos `dplyr::select()` en lugar de `select()` porque hay varias funciones `select` en diferentes paquetes. Usar el nombre del paquete como prefijo hace que sea claro cuál función y de qué paquete estamos usando y reduce la posibilidad de errores causados por paquetes que se cargan en un orden diferente.
El equivalente en `R` base se muestra abajo.
```{r}
starwars[,c('name','gender','homeworld')]
```
Filtra las columnas con personajes de Tatooine.
```{r}
starwars |>
dplyr::filter(homeworld == 'Tatooine')
```
Equivalente en `R` base.
```{r}
starwars[which(starwars$homeworld=='Tatooine'),]
```
### Encadenamiento "stringing" de argumentos
Aquí mostramos cómo aplicar varias funciones a una misma variable utilizando la pipa (`|>`) con el `tidyverse`.
```{r}
starwars |>
dplyr::select(name, gender, homeworld) |>
dplyr::filter(homeworld == "Tatooine")
```
Equivalente en `R` base.
```{r}
starwars[which(starwars$homeworld == "Tatooine"),
c("name", "gender", "homeworld")]
```
### Agrupamiento y resumen de datos
Con el `tidyverse` el agrupamiento de datos se hace con la función `group_by()`.
```{r}
starwars |>
group_by(homeworld)
```
Si queremos obtener la altura promedio de los personajes, agrupados por `homeworld`, y agregar un recuento para obtener el tamaño de la muestra. Lo podemos hacer de la siguiente manera.
```{r}
starwars |>
group_by(homeworld) |>
summarise(promedio_altura = mean(height), n = n())
```
Podemos obtener la altura promedio de los personajes, agrupados por `homeworld` y género (`gemder`), y agregar un recuento para obtener el tamaño de la muestra pero ignorando cualquier fila con valores `NA`.
```{r}
starwars |>
group_by(homeworld, gender) |>
summarise(altura_promedio = mean(height), n = n()) |>
dplyr::filter(!is.na(homeworld))
```
### Otras formas de contar
Podemos contar por grupo sin necesidad de agrupar de la siguiente manera.
```{r}
starwars |>
count(homeworld, gender) |>
#Removemos filas NA
dplyr::filter(!is.na(homeworld))
```
Otra opción es la siguiente:
```{r}
starwars |>
add_count(homeworld, gender) |>
dplyr::filter(!is.na(homeworld))
```
# TAREA 1
1. Crea una tabla con la media, mediana y desviación estándar de la masa para todos los humanos con cabello marrón.
```{r}
starwars |>
group_by(hair_color, species) |>
summarise(masa_promedio = mean(mass, na.rm = T),
masa_mediana = median(mass, na.rm = T),
masa_ds = sd(mass, na.rm = T)) |>
dplyr::filter(species == "Human", hair_color == "brown")
```
2. Obtén al personaje no humano más alto y el más bajo.
```{r}
starwars |>
dplyr::filter(species != 'Human') |>
arrange(height)
```
```{r}
starwars |>
dplyr::filter(species != 'Human') |>
arrange(-height)
```
3. ¿Cuántos droides aparecieron en "Attack of the Clones"?
```{r}
starwars |>
unnest(films) |>
count(species, films) |>
dplyr::filter(species == "Droid", films == "Attack of the Clones")
```
## Mutaciones
Esto calculará una nueva columna con la relación entre la altura y la masa (`height`:`mass`).
```{r}
starwars |>
mutate(hm_ratio = height/mass)
```
## Uniones
```{r}
df1 <- tibble(
category = c('a','a','b','c','c','a','b'),
id = c(1,2,3,4,5,6,7)
)
df2 <- tibble(
category = c('b','a','b','a','a','c','c'),
id = c(7,6,5,4,3,2,1)
)
## Esto unirá las dos tablas tibble por el valor de id.
df1 |>
left_join(df2, by='id')
```
## Reunir y Extender
Este es un conjunto de datos en el que podrás encontrar diferentes dispositivos que toman medidas en el mismo día.
```{r}
sst_data <- data.frame(
time = as.Date('2009-01-01') + 0:9,
unit_A = round(runif(10, 6, 9),2),
unit_B = round(runif(10, 7, 10),2),
unit_C = round(runif(10, 6, 10),2)
)
sst_data
```
`pivot_longer` hace que el marco de datos pase de un formato ANCHO (WIDE) a LARGO (LONG). El formato LARGO suele ser utilizado por `ggplot2`.
```{r}
sst_data |>
pivot_longer(!time, names_to = "unit", values_to = "sst")
```
`pivot_wider` es la función opuesta a `pivot_longer` y cambia el formato de LARGO a ANCHO.
```{r}
sst_data |>
pivot_longer(!time, names_to = "unit", values_to = "sst") |>
pivot_wider(names_from = "unit", values_from = "sst")
```
## Anidaciones
Esto anida las columnas `unit` y `sst` en una tabla para cada columna de tiempo.
```{r}
nested_sst <- sst_data |>
pivot_longer(!time, names_to = "unit", values_to = "sst") |>
nest_by(time)
nested_sst
```
Si queremos ver una tabla de datos en específico, podemos hacerlo de la siguiente manera.
```{r}
nested_sst$data[[1]]
```
# TAREA 1
1. Haz un `tibble` con películas de Star Wars clasificadas según tu preferencia.
```{r}
ranking_peliculas <- tibble(
films = c('The Phantom Menace', 'Attack of the Clones', 'Revenge of the Sith',
'A New Hope', 'The Empire Strikes Back', 'Return of the Jedi',
'The Force Awakens'),
rank = c(7,6,5,3,4,1,2)
)
ranking_peliculas
```
2. ¿En qué películas aparece el personaje Plo Koon, ordenadas por clasificación?
El resultado final debe ser una única tabla obtenida de una columna.
```{r}
Plo.Koon <- starwars |>
dplyr::select(name, films) |>
unnest(films) |>
left_join(ranking_peliculas, by = 'films') |>
dplyr::filter(name == 'Plo Koon') |>
nest_by(name)
Plo.Koon$data
```
3. Crea una tabla que anide los datos de altura (`height`) y masa (`mass`) solo para humanos en una columna anidada por el nombre de la película.
```{r}
masa_altura <- starwars |>
unnest(films)|>
dplyr::select(name, height, mass, films, species) |>
dplyr::filter(species == 'Human') |>
drop_na(height, mass) |>
nest_by(films)
masa_altura |>
head()
```
# TAREA FINAL - Programación funcional
1. Crea un objeto que sea una lista de vectores
```{r}
X <- c(list(seq(1,50,5)),
list(seq(40,100,2)))
X
```
Calculando el promedio por lista en `R` base.
```{r}
lapply(X, mean)
```
Equivalente en el `tidyverse`.
```{r}
map(X, mean)
```
El siguiente código muestra cómo puedes usar `rowwise` para ejecutar funciones en listas y obtener resultados de modelos interesantes para matrices de datos grandes. Es muy útil para resumir datos rápidamente.
```{r}
masa_altura |>
rowwise() |>
mutate(model = list(lm(mass ~ height, data = data)),
slope = coef(model)["height"],
r.sq = glance(model)$"r.squared",
sample_size = nrow(data),
tallest = data$name[which.max(data$height)],
heaviest = data$name[which.max(data$mass)]) |>
unnest(c(tallest, heaviest)) |>
rename(name = tallest, name1 = heaviest)
```
## Gráficos con `ggplot2`
Graficando datos.
```{r}
starwars |>
dplyr::filter(species == "Human", gender == "masculine") |>
drop_na() |>
ggplot(aes(x = mass, y = height))+
geom_point()+
geom_smooth(method = lm)
```
## Ver tambien
- [Introducción a `R` y RStudio de Software Carpentry](https://swcarpentry.github.io/r-novice-gapminder-es/01-rstudio-intro.html).
- [Introducción a `R` (en inglés)](https://obis.org/manual/intror/) por el Sistema de Información Biogeográficos de los Océanos (OBIS por sus siglas en inglés).
- [`R` para Ciencia de Datos](https://es.r4ds.hadley.nz/).