-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbasic_data_management.Rmd
594 lines (417 loc) · 18.9 KB
/
basic_data_management.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
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
---
title: "Gestión de datos"
author: "Christian Urcuqui"
date: "31 de enero de 2019"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
# Introducción
Este módulo tiene como objetivo introducir más mecanismos para la exploración y la manipulación de datos a través del lenguaje R, para ello se explorarán las siguientes secciones:
+ Funciones para recolección y análisis
+ Introducción a SQL y su aplicación en R
```{r start}
manager <- c(1, 2, 3, 4, 5)
date <- c("10/24/08", "10/28/08", "10/1/08", "10/12/08", "5/1/09")
country <- c("US", "US", "UK", "UK", "UK")
gender <- c("M", "F", "F", "M", "F")
age <- c(32, 45, 25, 39, 99)
q1 <- c(5, 3, 3, 3, 2)
q2 <- c(4, 5, 5, 3, 2)
q3 <- c(5, 2, 5, 4, 1)
q4 <- c(5, 5, 5, NA, 2)
q5 <- c(5, 5, 2, NA, 1)
leadership <- data.frame(manager, date, country, gender, age,
q1, q2, q3, q4, q5, stringsAsFactors=FALSE)
leadership
```
## Funciones para recolección y análisis
Recordemos que en R a diferencia de otros lenguajes la forma de asignar y crear una variable es a través de la sentencia:
```
variable <- expresión
```
Algunas operaciones aritméticas a tener en cuenta:
| __Operación__ | __Descripción__ |
|----------------|-----------------------------------------------------------------------|
| ```x + y``` | Suma |
| ```x - y``` | Resta |
| ```x * y``` | Multiplicación |
| ```x / y``` | División |
| ```^ or **``` | exponenciación |
| ```x%%y``` | Módulo |
__Ejemplo 1__
A continuación, veremos como agregar nuevas columnas a una data.frame con base en los resultados de sus datos.
```{r example1, echo=FALSE}
mydata <- data.frame(x1 = c(2, 2, 6, 4),
x2 = c(3, 4, 2, 8))
mydata
# primera forma de asignación
mydata$sumx <- mydata$x1 + mydata$x2
mydata$meanx <- (mydata$x1 + mydata$x2) / 2
mydata
# segunda forma de asignación
attach(mydata)
mydata$sumx <- x1 + x2
mydata$meanx <- (x1 + x2) / 2
detach(mydata)
# tercera forma de asignación
mydata <- transform(mydata,
sumx= x1 + x2,
meanx = (x1 + x2) / 2)
```
### Recodificación de variables
En algunas ocasiones será necesario crear nuevos valores de una variable condicional a los valores existentes de las mismas u otras variables, por ejemplo:
+ cambiar una variable continua por un conjunto de categorías
+ Reemplazar valores mal codificados en valores correctos
+ Crear o completar unos valores teniendo en cuenta unas reglas
Para ello podemos utilizar uno o más operadores lógicos
| __Operación__ | __Descripción__ |
|----------------|-----------------------------------------------------------------------|
| ```x == y``` | Igualidad |
| ```x & y``` | Operador lógico "and" |
| ```x | y``` | Operador lógico "or" |
| ```x > y```| Operador lógico mayor |
| ```x > y``` | Operador lógico menor |
| ```x >= y``` | Operador lógico mayor o igual |
| ```x <= y``` | Operador lógico menor o igual |
| ```isTRUE(x)``` | evalua si _x_ es TRUE |
Supongamos que deseamos transformar una variable cuantitiva de edad a una variable categorica compuesta por los siguientes valores ```Young, Middle Aged, Elder)```
Explore el siguiente data.frame que corresponde a la administración que realizan las mujeres y los hombres en las empresas, con el fin de evaluar el desempeño de ambos géneros se propone un conjunto de datos base la aplicación de la analítica de datos, ¿encuentra alguna particularidad?
__Ejemplo 2__
Representemos el valor como una anomalía en los datos de registros
```{r example2}
leadership
leadership$age[leadership$age == 99] <- NA
leadership
```
La sentencia ```variable[condición] <- expresión``` permite asignar los valores de la expresión si y solo si la condición es TRUE
Ahora vamos a crear una nueva variable categorice que corresponde a los rangos para los valores de la edad
__Ejemplo 3__
```{r example3}
leadership$agecat[leadership$age > 75] <- "Elder"
leadership$agecat[leadership$age >= 55 &
leadership$age <= 75] <- "Middle Aged"
leadership$agecat[leadership$age < 55] <- "Young"
leadership
```
__Ejercicio 1__
Cree una nueva variable con las capitales de cada país del dataset leadership
```{r exercise1}
leadership$capital[leadership$country == "US"] <- "Washintong"
leadership$capital[leadership$country == "UK"] <- "Londres"
leadership
```
### Renombrando variables
De la misma forma que podemos cambiar los datos manualmente, podemos realizar cambios sobre las columnas de la siguiente manera:
__Ejemplo 4__
```{r example4}
# a través del editor de RStudio
fix(leadership)
# podemos utilizar la función rename() del paquete reshape y pasarle un vector de caracteres que correspondan a todas las columnas del data.frame
install.packages("reshape")
library(reshape)
leadership <- rename(leadership, c(manager="managerID", date="testDate", country="country", gender= "gender", age="age", q1= "q1", q2="q2",q3="q3",q4="q4",q5="q5",agecat="agecat", capital="Capi"))
leadership
colnames(leadership)
# tambien podemos utilizar la función colnames
colnames(leadership) <- c(manager="ID", date="testDate", country="country", gender= "gender", age="age", q1= "q1", q2="q2",q3="q3",q4="q4",q5="q5",agecat="agecat")
colnames(leadership)
leadership
```
### Tratamiento de valores faltantes
En R los valores faltantes son representados como ```NA``` (not avaiable). Los valores que son atipicos (por ejemplo, los números dividos por 0) son representados con el simbolo ```NaN```(Not a Number).
La función ```is.na() ``` nos permitirá testear la presencia de NA
__Ejemplo 5__
```{r example5}
y <- c(1, NA, 3, NaN)
is.na(y)
```
Note que la función ```is.na()``` retorna un vector con el tamaño del vector analizado y los valores en FALSE donde no hay valores NaN y NAN.
__Ejercicio 2__
Aplique la función ```is.na()``` sobre la sexta hasta la décima columna del data.frame leadership.
```{r exercise2}
leadership
is.na(leadership[4,6:10])
# 1 linea de código
```
### Excluyendo valores faltantes para análisis
Una vez identificados los valores faltantes, ya es deber del científico de datos si los elimina, los almacena en otra estructura o los cambia por un valor. Es importante aplicar este proceso ya que si trabajamos con algunas operaciones (por ejemplo, las aritméticas) podría ocasionar errores en los resultados.
__Ejemplo 6__
Observe el resultado al operar con vectores que integran valores faltantes
```{r example6}
x <- c(1, 2, NA, 3)
y <- x[1] + x[2] + x[3] + x[4]
z <- sum(x)
x
y
z
```
__Ejemplo 7__
Gran parte de las funciones numéricas traen consigo un parámetro que permite expresarles que omita los valores faltantes
```{r example7}
x <- c(1, 2, NA, 3)
x
y <- sum(x, na.rm=TRUE)
y
```
Podemos remover todas las observaciones que contengan valores faltantes a través de la función ```na.omit```. ¿Esta es una buena práctica?
R/
__Ejemplo 8__
```{r example8}
# mantenga la persistencia de su data.frame y cree uno nuevo donde va a realizar los cambios
newdata <- na.omit(leadership)
newdata
```
### Fechas
Las fechas son típicamente tratadas como cadenas de caracteres que pueden ser transformadas a variables fecha que son almacenadas como numéricas en R. La función para la transformación ```as.Date```. La sintaxis es ```as.Date(x, "input_format")```, donde ```x``` es la fecha en carácter y ```input_format``` es el formato apropiado para la fecha.
| __Simbolo__ | __Significado__ | __Ejemplo__ |
|----------------|-----------------------------------------------------------------------|
| ```%d``` | Día como número (0-31) | 01-31 |
| ```a``` | Abreviación del día de la semana | Mon |
| ```A``` | Día no abreviado | Monday |
| ```%m```| Mes (00-12) | 00-12 |
| ```%b``` | Abreviación del mes| Jan |
| ```%B``` | Mes no abeviado | January |
| ```y``` | año en dos digítos | 07 |
| ```Y``` | año en cuatro digítos | 2007 |
El formato por defecto de las fechas es yyyy-mm-dd.
__Ejemplo 9__
```{r example9}
# ejemplo de vector con fechas (Date)
mydates <- as.Date(c("2007-06-22", "2004-02-13"))
mydates
```
__Ejemplo 10__
Ahora si tenemos en otro formato las fechas en los caracteres, al transformarlas veremos que el formato por defecto prevalece
```{r example10}
# convertir a otro formato de fecha
strDates <- c("01/05/1965", "08/16/1975")
dates <- as.Date(strDates, "%m/%d/%Y")
dates
```
__ Ejercicio 3__
Implemente el código necesario que permita cambiar la variable carácter de age del data.frame leadership a un tipo Date
```{r exercise3}
leadership
leadership$testDate <- as.Date(leadership$testDate, "%m/%d/%y")
leadership
# 1 linea de código
# -----------------------------------
```
__Ejemplo 11__
Podemos usar la función ```format(X, format="output_format")``` para obtener una fecha en un formato especifico, también, nos sirve para extraer porciones de este.
```{r example11}
today <- Sys.Date() # obtenemos la fecha del sistema
format(today, format="%B %d %Y")
format(today, format="%A")
```
Para el anterior ejemplo la función `format recibió` como parámetro un objeto Date en R.
R almacena internamente una representación del número de días desde Enero 1 de 1970, con valores negativos para fechas menores a este punto. Esto significa que podemos realizar operaciones matemáticas entre fechas, por ejemplo:
__Ejemplo 12__
```{r example12}
startdate <- as.Date("2004-02-13")
enddate <- as.Date("2011-01-22")
days <- enddate - startdate
days
```
También podemos utilizar la función `difftime()` para calcular el intervalo de tiempo expresado como segundos, horas, días o semanas.
__Ejercicio 4__
Utilice difftime y calcule el tiempo transcurrido desde su nacimiento hasta hoy y despliéguelo en unidad de semanas.
```{r exercise4}
startdate <- as.Date("1975-05-06")
today <- Sys.Date() # obtenemos la fecha del sistema
tt <- today - startdate
tt
dates <- difftime(today, startdate, units = c("days"))
dates
```
__Ejemplo 13__
Para convertir un Date a un carácter podemos cambiarla de la siguiente forma
```{r example13}
strDates <- as.character(dates)
strDates
```
### Tipos de conversiones
En la sección previa vimos cómo convertir un dato carácter a un objeto Date y vice versa. R provee una serie de funciones que permiten convertir una variable a otro tipo de dato.
|convertir |
|----------------|
| ```as.numeric()```|
| ```as.character()``` |
| ```as.vector``` |
| ```as.matrix```|
| ```as.data.frame()```|
| ```as.factor()``` |
| ```as.logical()``` |
_Ejemplo 14_
```{r example14}
a <- c(1,2,3)
a
is.numeric(a)
is.vector(a)
print("")
a <- as.character(a)
is.numeric(a)
is.vector(a)
is.character(a)
a
```
### Organizando datos
Para organizar un data.frame en R podemos utilizar la función `order` que por defecto organiza los datos de forma ascendente, si pretendemos organizar la variable de manera descendente tenemos que indicarle por parámetro con el signo menos.
_Ejemplo 15_
Crea un nuevo conjunto de datos que contiene filas ordenadas desde el administrador más joven al administrador más antiguo
```{r example15}
newdata <- leadership[order(leadership$q2),]
newdata
leadership[order(-leadership$q2),]$q2[1:3]
```
_Ejemplo 16_
Creemos un nuevo dataset que contiene las filas ordenadas por el género y la edad, es decir, el orden del abecedario (primero va la letra F para femenino y luego M para masculino) y la edad del administrador desde el más viejo al más joven
```{r example16}
attach(leadership)
newdata <- leadership[order(gender, -age),]
newdata
detach(leadership)
```
### Unión de datasets
Para unir dos data frames (datasets) horizontalmente podemos hacer uso de la función `merge()`, en la mayoría de casos dos conjuntos de datos se encuentran unidas a través de uno o más variables clave (proceso conocido como `inner join`) . Un ejemplo de una unión de dos dataframe A y B a través de la variable ID se puede presentar de la siguiente forma:
```total <- merge(dataframeA, dataframeB, by="ID")```
De manera similar podemos juntar los dos elementos por la cantidad de variables en un vector
```total <- merge(dataframeA, dataframeB, by=c("ID","Country"))```
Si no necesitamos alguna llave que asocie dos data.frames podemos simplemente usar la función `cbind()` para unirlos horizontalmente.
```total <- cbind(A, B)```
```{r }
x1 <- c(1,2,3)
x2 <- c(1,5,6)
id <- c(1,1,2)
x3 <- c(2,3,5)
dataframeA <- data.frame(x1,x2,id)
View(dataframeA)
id <- c(1,1,3)
dataframeB <- data.frame(id,x3)
View(dataframeB)
total <- merge(dataframeA, dataframeB, by="id")
View(total)
```
#### Adicionando filas
Para unir dos datasets de forma verticial podemos utilizar la función `rbind()`
`total <- rbind(dataframeA, dataframeB)`
¡Es importante que ambos conjuntos de datos tengan las mismas variables!
## Subconjunto de conjuntos de datos
### Seleccionado un conjunto de datos (variables)
Es una práctica común crear nuevos datasets con un número limitado de variables de otro conjunto más grande con la finalidad de conservar los datos en bruto para los estudios.
Recordemos que una de las formas para acceder a los elementos de un dataset es indicando los índices de las columnas y filas `dataframe[row indices, column indices]`
__Ejercicio 5__
Imprima las variables desde la 6 hasta la 10 del dataframe leadership
```{r exercise5}
```
__Ejemplo 17__
Podemos también realizar la selección indicando los nombres de las columnas a través de un vector
```{r example17}
myvars <- c("q1", "q2", "q3", "q4", "q5")
newdata <-leadership[myvars]
newdata
```
### Excluyendo (borrando) variables
Existen varias razones por las cuales podríamos excluir variables, un ejemplo seria la cantidad de datos faltantes. Veamos las distintas formas que nos permitan excluir las variables.
__Ejemplo 18__
Podemos excluir las variables q3 y q4 con el siguiente ejemplo
```{r example18}
myvars <- names(leadership) %in% c("q3", "q4")
newdata <- leadership[!myvars]
names(newdata)
```
__Ejemplo 19__
Si conocemos los índices de las columnas también podemos utilizarlas para la exclusión
```{r example19}
newdata <- leadership[c(-8,-9)]
names(newdata)
```
__Ejemplo 20__
También podemos asignar NULL a la columna y así excluirla del dataframe
```{r example20}
newdata <- leadership
newdata
newdata$q3 <- newdata$q4 <- NULL
names(newdata)
```
### Selección de registros
La selección o la exclusión de observaciones es actividad típica y clave para un análisis éxito en los datos, observemos algunos ejemplos
__Ejemplo 21__
```{r example21}
newdata <- leadership[1:3,]
newdata
# which nos retorna los índices donde la operación lógica es TRUE
newdata <- leadership[which(leadership$gender =="M" & leadership$age > 30),]
newdata
attach(leadership)
newdata <- leadership[which(gender=='M' & age > 30),]
newdata
detach(leadership)
```
### La función subset()
La función subset nos facilita la forma para seleccionar un subconjunto de un dataframe, en este debemos indicar los datos, el operador lógico y la selección de las columnas.
__Ejemplo 22__
```{r example22}
newdata <- subset(leadership, age >= 35 | age < 24, select=c(q1, q2, q3, q4))
newdata
newdata <- subset(leadership, gender=="M" & age > 25, select=gender:q4)
newdata
```
### Ejemplos aleatoríos
En algunas ocasiones será necesario realizar muestras aleatorias para análisis predictivos, para ello R nos facilita la función sample()
__Ejemplo 23__
```{r example23}
muestra <- sample(1:10, 3, replace=TRUE) #genero 3 numeros aleatorios del 1 al 10
muestra
mysample <- leadership[sample(1:nrow(leadership), 3, replace=FALSE),]
mysample
```
###Base de datos
Debido a la amplia gama de tecnologías de base de datos y a la importancia de procesar la mayor cantidad de información; es importante conocer los mecanismos (interfaces) con los cuales podamos integrar los distintos sistemas de información con R, ya que será el medio con el que podremos consultar y procesar los datos que serán luego utilizados en las actividades de la ciencia de datos.
####MySQL
![](../../../Utilities/mysql.jpg)
MYSQL es un sistema de gestión de base de datos relacional. Una de las tecnologías de mayor acogida en el soluciones web (por ejemplo, Joomla, Wordpress y Drupal).
Existen diversas interfaces de programación de aplicaciones que permiten el acceso a MySQL a distintos lenguajes de programación de programación, por ejemplo, C, C++, Python, Java y R.
Para la interacción de R y MySQL es necesario contar el paquete RMySQL en nuestro entorno de trabajo de R.
Es importante tener previamente instalado el sistema de base de datos MySQL en nuestro equipo (por ejemplo, MySQL WorkBench).
https://dev.mysql.com/downloads
A continuación, se enuncian algunos comandos a tener en cuenta para la configuración y acceso de un usuario a través del paquete RMySQL.
Existen distintas formas para crear un usuario en el MySQL workbench, para nuestro caso dejaremos un ejemplo de un script en SQL para la creación de un usuario con privilegios sobre un SCHEMA
```
CREATE USER 'username'@'localhost' IDENTIFIED BY 'SomethingDifficult';
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE, SHOW VIEW ON database_name.* TO 'username'@'localhost';
```
Es importante que el tipo de autenticación sea tipo "Standard", para lograr esto se puede digitar el siguiente script en SQL
```
ALTER USER 'username'@'localhost' IDENTIFIED WITH mysql_native_password BY 'SomethingDifficult';
```
### Paquetes para MySQL
Instalación de paquetes necesarios para el desarrollo de las sesiones
```{r paquetes, echo=FALSE}
#install.packages("RMySQL")
```
Cargar los paquetes
```{r cargarPaquetes}
library(RMySQL)
```
Vamos a conectarnos a través de R a la base de datos MySQL, para ello será necesario utilizar los métodos de RMySQL para definir los datos de nuestra cuenta y contraseña.
```{r conexion}
# definición de la variable para el password
# dbname es el nombre de la base de datos creada en el sistema de base de datos MySQL
# host es el parámetro que define la dirección donde se encuentra hospedada la base de datos, para nuestro caso será en nuestro equipo local "localhost"
localuserpassword <- "SomethingDifficult"
#dbConnect es el método que nos permite conectarnos a la base de datos MySQL
#?dbConnect
storiesDb <- dbConnect(MySQL(), user='username', password=localuserpassword, dbname='sakila', host='localhost')
# La siguiente linea despliega las tablas de la base de datos cargada
dbListTables(storiesDb)
# Vamos ahora a pasar la base de datos cargada a un data.frame,< el parámetro name define el nombre de la tabla a procesar
actor_df <- dbReadTable(conn = storiesDb, name = 'actor')
head(actor_df)
# dbDisconnect es el método que nos permite terminar la conexión con la base de datos
#?dbDisconnect
dbDisconnect(storiesDb )
```
## Referencias
+ Murrel, p. (2005). R in Action.