-
Notifications
You must be signed in to change notification settings - Fork 0
/
17-ManipulacionDatosR.Rmd
372 lines (285 loc) · 11.3 KB
/
17-ManipulacionDatosR.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
Manipulación de datos con R
===========================
```{r , child = '_global_options.Rmd'}
```
La mayoría de los estudios estadísticos
requieren disponer de un conjunto de datos.
Lectura, importación y exportación de datos
-------------------------------------------
Además de la introducción directa, R es capaz de
importar datos externos en múltiples formatos:
- bases de datos disponibles en librerías de R
- archivos de texto en formato ASCII
- archivos en otros formatos: Excel, SPSS, ...
- bases de datos relacionales: MySQL, Oracle, ...
- formatos web: HTML, XML, JSON, ...
- ....
### Formato de datos de R
El formato de archivo en el que habitualmente se almacena objetos (datos)
R es binario y está comprimido (en formato `"gzip"` por defecto).
Para cargar un fichero de datos se emplea normalmente [`load()`](https://www.rdocumentation.org/packages/base/versions/3.6.1/topics/load):
```{r}
res <- load("datos/empleados.RData")
res
ls()
```
y para guardar [`save()`](https://www.rdocumentation.org/packages/base/versions/3.6.1/topics/save):
```{r eval=FALSE}
# Guardar
save(empleados, file = "datos/empleados_new.RData")
```
El objeto empleado normalmente en R para almacenar datos en memoria
es el [`data.frame`](https://www.rdocumentation.org/packages/base/versions/3.6.1/topics/data.frame).
### Acceso a datos en paquetes
R dispone de múltiples conjuntos de datos en distintos paquetes, especialmente en el paquete `datasets`
que se carga por defecto al abrir R.
Con el comando `data()` podemos obtener un listado de las bases de datos disponibles.
Para cargar una base de datos concreta se utiliza el comando
`data(nombre)` (aunque en algunos casos se cargan automáticamente al emplearlos).
Por ejemplo, `data(cars)` carga la base de datos llamada `cars` en el entorno de trabajo (`".GlobalEnv"`)
y `?cars` muestra la ayuda correspondiente con la descripición de la base de datos.
### Lectura de archivos de texto {#cap4-texto}
En R para leer archivos de texto se suele utilizar la función `read.table()`.
Supóngase, por ejemplo, que en el directorio actual está el fichero
*empleados.txt*. La lectura de este fichero vendría dada por el código:
```{r}
# Session > Set Working Directory > To Source...?
datos <- read.table(file = "datos/empleados.txt", header = TRUE)
# head(datos)
str(datos)
```
Si el fichero estuviese en el directorio *c:\\datos* bastaría con especificar
`file = "c:/datos/empleados.txt"`.
Nótese también que para la lectura del fichero anterior se ha
establecido el argumento `header=TRUE` para indicar que la primera línea del
fichero contiene los nombres de las variables.
Los argumentos utilizados habitualmente para esta función son:
- `header`: indica si el fichero tiene cabecera (`header=TRUE`) o no
(`header=FALSE`). Por defecto toma el valor `header=FALSE`.
- `sep`: carácter separador de columnas que por defecto es un espacio
en blanco (`sep=""`). Otras opciones serían: `sep=","` si el separador es
un ";", `sep="*"` si el separador es un "\*", etc.
- `dec`: carácter utilizado en el fichero para los números decimales.
Por defecto se establece `dec = "."`. Si los decimales vienen dados
por "," se utiliza `dec = ","`
Resumiendo, los (principales) argumentos por defecto de la función
`read.table` son los que se muestran en la siguiente línea:
```{r, eval=FALSE}
read.table(file, header = FALSE, sep = "", dec = ".")
```
Para más detalles sobre esta función véase
`help(read.table)`.
Estan disponibles otras funciones con valores por defecto de los parámetros
adecuados para otras situaciones. Por ejemplo, para ficheros separados por tabuladores
se puede utilizar `read.delim()` o `read.delim2()`:
```{r, eval=FALSE}
read.delim(file, header = TRUE, sep = "\t", dec = ".")
read.delim2(file, header = TRUE, sep = "\t", dec = ",")
```
### Alternativa `tidyverse`
Para leer archivos de texto en distintos formatos también se puede emplear el paquete [`readr`](https://readr.tidyverse.org)
(colección [`tidyverse`](https://www.tidyverse.org/)), para lo que se recomienda
consultar el [Capítulo 11](https://r4ds.had.co.nz/data-import.html) del libro [R for Data Science](http://r4ds.had.co.nz).
### Importación desde SPSS
El programa R permite
lectura de ficheros de datos en formato SPSS (extensión *.sav*) sin
necesidad de tener instalado dicho programa en el ordenador. Para ello
se necesita:
- cargar la librería `foreign`
- utilizar la función `read.spss`
Por ejemplo:
```{r, warning=FALSE}
library(foreign)
datos <- read.spss(file = "datos/Employee data.sav", to.data.frame = TRUE)
# head(datos)
str(datos)
```
**Nota**: Si hay fechas, puede ser recomendable emplear la función `spss.get()` del paquete `Hmisc`.
### Importación desde Excel
Se pueden leer fichero de
Excel (con extensión *.xlsx*) utilizando por ejemplo los paquetes [`openxlsx`](https://cran.r-project.org/web/packages/openxlsx/index.html), [`readxl`](https://readxl.tidyverse.org) (colección [`tidyverse`](https://www.tidyverse.org/)), `XLConnect` o
[`RODBC`](https://cran.r-project.org/web/packages/RODBC/index.html) (este paquete se empleará más adelante para acceder a bases de datos),
entre otros.
Sin embargo, un procedimiento sencillo consiste en exportar los datos desde Excel a un archivo
de texto separado por tabuladores (extensión *.csv*).
Por ejemplo, supongamos que queremos leer el fichero *coches.xls*:
- Desde Excel se selecciona el menú
`Archivo -> Guardar como -> Guardar como` y en `Tipo` se escoge la opción de
archivo CSV. De esta forma se guardarán los datos en el archivo
*coches.csv*.
- El fichero *coches.csv* es un fichero de texto plano (se puede
editar con Notepad), con cabecera, las columnas separadas por ";", y
siendo "," el carácter decimal.
- Por lo tanto, la lectura de este fichero se puede hacer con:
```{r, eval=FALSE}
datos <- read.table("coches.csv", header = TRUE, sep = ";", dec = ",")
```
Otra posibilidad es utilizar la función `read.csv2`, que es
una adaptación de la función general `read.table` con las siguientes
opciones:
```{r, eval=FALSE}
read.csv2(file, header = TRUE, sep = ";", dec = ",")
```
Por lo tanto, la lectura del fichero *coches.csv* se puede hacer de modo
más directo con:
```{r, eval=FALSE}
datos <- read.csv2("coches.csv")
```
### Exportación de datos
Puede ser de interés la
exportación de datos para que puedan leídos con otros programas. Para
ello, se puede emplear la función `write.table()`. Esta función es
similar, pero funcionando en sentido inverso, a `read.table()`
(Sección \@ref(cap4-texto)).
Veamos un ejemplo:
```{r}
tipo <- c("A", "B", "C")
longitud <- c(120.34, 99.45, 115.67)
datos <- data.frame(tipo, longitud)
datos
```
Para guardar el data.frame `datos` en un fichero de texto se
puede utilizar:
```{r, eval=FALSE}
write.table(datos, file = "datos.txt")
```
Otra posibilidad es utilizar la función:
```{r, eval=FALSE}
write.csv2(datos, file = "datos.csv")
```
que dará lugar al fichero *datos.csv* importable directamente desde Excel.
Manipulación de datos
---------------------
Una vez cargada una (o varias) bases
de datos hay una series de operaciones que serán de interés para el
tratamiento de datos:
- Operaciones con variables:
- crear
- recodificar (e.g. categorizar)
- ...
- Operaciones con casos:
- ordenar
- filtrar
- ...
A continuación se tratan algunas operaciones *básicas*.
### Operaciones con variables
#### Creación (y eliminación) de variables
Consideremos de nuevo la
base de datos `cars` incluida en el paquete `datasets`:
```{r}
data(cars)
# str(cars)
head(cars)
```
Utilizando el comando `help(cars)`
se obtiene que `cars` es un data.frame con 50 observaciones y dos
variables:
- `speed`: Velocidad (millas por hora)
- `dist`: tiempo hasta detenerse (pies)
Recordemos que, para acceder a la variable `speed` se puede
hacer directamente con su nombre o bien utilizando notación
"matricial".
```{r}
cars$speed
cars[, 1] # Equivalente
```
Supongamos ahora que queremos transformar la variable original `speed`
(millas por hora) en una nueva variable `velocidad` (kilómetros por
hora) y añadir esta nueva variable al data.frame `cars`.
La transformación que permite pasar millas a kilómetros es
`kilómetros=millas/0.62137` que en R se hace directamente con:
```{r, eval=FALSE}
cars$speed/0.62137
```
Finalmente, incluimos la nueva variable que llamaremos
`velocidad` en `cars`:
```{r}
cars[, c("velocidad")] <- cars[, 1]/0.62137
head(cars)
```
También transformaremos la variable `dist` (en pies) en una nueva
variable `distancia` (en metros). Ahora la transformación deseada es
`metros=pies/3.2808`:
```{r}
cars[, c("distancia")] <- cars[, 2]/3.2808
head(cars)
```
Ahora, eliminaremos las variables originales `speed` y
`dist`, y guardaremos el data.frame resultante con el nombre `coches`.
En primer lugar, veamos varias formas de acceder a las variables de
interés:
```{r, eval=FALSE}
cars[, c(3, 4)]
cars[, c("velocidad", "distancia")]
cars[, -c(1, 2)]
```
Utilizando alguna de las opciones anteriores se obtiene el `data.frame`
deseado:
```{r}
coches <- cars[, c("velocidad", "distancia")]
# head(coches)
str(coches)
```
Finalmente los datos anteriores podrían ser guardados en un fichero
exportable a Excel con el siguiente comando:
```{r, eval=FALSE}
write.csv2(coches, file = "coches.csv")
```
### Operaciones con casos
#### Ordenación
Continuemos con el data.frame `cars`.
Se puede comprobar que los datos disponibles están ordenados por
los valores de `speed`. A continuación haremos la ordenación utilizando
los valores de `dist`. Para ello utilizaremos el conocido como vector de
índices de ordenación.
Este vector establece el orden en que tienen que ser elegidos los
elementos para obtener la ordenación deseada.
Veamos un ejemplo sencillo:
```{r}
x <- c(2.5, 4.3, 1.2, 3.1, 5.0) # valores originales
ii <- order(x)
ii # vector de ordenación
x[ii] # valores ordenados
```
En el caso de vectores, el procedimiento anterior se podría
hacer directamente con:
```{r, eval=FALSE}
sort(x)
```
Sin embargo, para ordenar data.frames será necesario la utilización del
vector de índices de ordenación. A continuación, los datos de `cars`
ordenados por `dist`:
```{r}
ii <- order(cars$dist) # Vector de índices de ordenación
cars2 <- cars[ii, ] # Datos ordenados por dist
head(cars2)
```
#### Filtrado
El filtrado de datos consiste en
elegir una submuestra que cumpla determinadas condiciones. Para ello se
puede utilizar la función [`subset()` ](https://www.rdocumentation.org/packages/base/versions/3.6.1/topics/subset)
(que además permite seleccionar variables).
A continuación se muestran un par de ejemplos:
```{r}
subset(cars, cars$dist > 85) # datos con dis>85
subset(cars, cars$speed > 10 & cars$speed < 15 & cars$dist > 45) # speed en (10,15) y dist>45
```
También se pueden hacer el filtrado empleando directamente los
correspondientes vectores de índices:
```{r}
ii <- cars$dist > 85
cars[ii, ] # dis>85
ii <- cars$speed > 10 & cars$speed < 15 & cars$dist > 45
cars[ii, ] # speed en (10,15) y dist>45
```
En este caso puede ser de utilidad la función [`which()` ](https://www.rdocumentation.org/packages/base/versions/3.6.1/topics/which):
```{r}
it <- which(ii)
str(it)
cars[it, 1:2]
# rownames(cars[it, 1:2])
id <- which(!ii)
str(cars[id, 1:2])
# Se podría p.e. emplear cars[id, ] para predecir cars[it, ]$speed
# ?which.min
```