Maestría en Hidrología
Universidad de Cuenca
http://www.ucuenca.edu.ec/maestria-ecohidrologia/

Johanna Orellana-Alvear (MSc)
johanna.orellana@ucuenca.edu.ec

Curso completo en: http://rpubs.com/Johanna_Orellana_Alvear/MHidro_indice_2018



En esta lección aprenderás a:
- Usar el comando cut para categorizar
- Usar la librería sqldf para interfaz SQL
- Usar la librería data.table para optimización de consultas

Temario

A- Comandos útiles - cut
B- SQLdf
C- Data.table

Comandos útiles - cut

Descripción

El comando cut divide el rango de x en intervalos y codifica los valores en x de acuerdo al intervalo al que pertenecen. El intervalo inferior corresponde al nivel uno, el siguiente al nivel dos y así sucesivamente.

Estructura del comando

  • x: un vector numérico el cual va a ser convertido a factor a través del “cutting”.
  • breaks: un vector numérico de dos o más puntos de “corte”, límites de intervalo o un escalar numérico (mayor o igual a 2) que indique el número de intervalos en los cuales se debe fragmentar el vector x.
  • labels: etiquetas para los niveles de las categorías resultantes. Por defecto las etiquetas se construyen usando la notación “(a,b]”. Si labels = FALSE, códigos de enteros simples se retornan en lugar de factores.
Z <- stats::rnorm(10000)
summary(Z)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## -3.698000 -0.667100  0.021860  0.008912  0.683800  3.732000
z <- cut(Z, breaks = -6:6)
head(z)
## [1] (-1,0] (-1,0] (-1,0] (-1,0] (-1,0] (-1,0]
## 12 Levels: (-6,-5] (-5,-4] (-4,-3] (-3,-2] (-2,-1] (-1,0] (0,1] ... (5,6]
z <- cut(Z, breaks = -6:6, labels = FALSE)
head(z)
## [1] 6 6 6 6 6 6
zz <- table(z)
zz
## z
##    3    4    5    6    7    8    9   10 
##   13  226 1375 3310 3485 1361  221    9

SQL

Para utilizar esta librería, la estructura original sobre la cual se va a trabajar es un data frame. Esta librería permite simular la estructura de un data frame como una tabla de una base de datos, haciendo uso de la indexación (implícita) para mejorar los tiempos de consulta. Primero instalemos el paquete correspondiente.

Instalar la librería “sqldf”

install.packages("sqldf")

Ahora cargamos la librería y leemos el archivo “df_events_results.txt” para cargar un data frame sobre el cual ejecutaremos las consultas (filtros).

library(sqldf)
## Loading required package: gsubfn
## Loading required package: proto
## Loading required package: RSQLite
setwd("~/Documents/R_WORKSPACE/Maestria_Hidrologia_2018")
df_events_results <- read.table("df_events_results.txt", sep = "\t")

Estructura

Select {nombres de campos} from {nombre de data frame} where {condiciones de filtro} group by {criterio de agrupacion}

El comando group by y where no son obligatorios.

available_events_group <- sqldf("Select  year, month, count(*) as eventNumber from df_events_results group by year,month")
## Loading required package: tcltk
## Warning: Quoted identifiers should have class SQL, use DBI::SQL() if the
## caller performs the quoting.
available_events_group
##    year month eventNumber
## 1  2012   Dec          69
## 2  2012   Nov          57
## 3  2013   Apr          60
## 4  2013   Aug          71
## 5  2013   Dec          79
## 6  2013   Feb          76
## 7  2013   Jan          64
## 8  2013   Jul          93
## 9  2013   Jun          75
## 10 2013   Mar          81
## 11 2013   May         116
## 12 2013   Nov          31
## 13 2013   Oct          71
## 14 2013   Sep          65
## 15 2014   Apr          93
## 16 2014   Aug           8
## 17 2014   Feb          64
## 18 2014   Jan          73
## 19 2014   Jul          75
## 20 2014   Jun          75
## 21 2014   Mar          94
## 22 2014   May         102
filter_minutes_group <- sqldf("Select  year, month, sum(duration) as filterEventMinutes from df_events_results Group by year,month") 
filter_minutes_group
##    year month filterEventMinutes
## 1  2012   Dec               9825
## 2  2012   Nov               7220
## 3  2013   Apr               8245
## 4  2013   Aug              13645
## 5  2013   Dec              10345
## 6  2013   Feb              12980
## 7  2013   Jan              17610
## 8  2013   Jul              17065
## 9  2013   Jun              16615
## 10 2013   Mar              12025
## 11 2013   May              16340
## 12 2013   Nov               2730
## 13 2013   Oct               8985
## 14 2013   Sep               9705
## 15 2014   Apr              14350
## 16 2014   Aug                570
## 17 2014   Feb               8015
## 18 2014   Jan              13380
## 19 2014   Jul              14280
## 20 2014   Jun              12960
## 21 2014   Mar              18695
## 22 2014   May              14735

Práctica

Sobre el archivo de precipitación del Trabajo I, donde la serie de tiempo está incompleta; haga uso de sentencias SQL para calcular el porcentaje de datos NA en cada año-mes. Nota: Al usar comandos SQL no es posible consultar por NA (ejm. campo==NA), en su defecto la referencia es null (ejm. campo is null)

data.table

El paquete para utilizar esta librería

install.packages("data.table")
library(data.table)

Para trabajar con esta librería el objeto debe ser de la clase data.table. Dos maneras de obtener la información en este formato.

  1. Convertir el data frame en un data.table:
df_events_results <- as.data.table(df_events_results)
  1. Leer el archivo de texto usando el comando fread. Normalmente la lectura de los encabezados usando este comando es automático al leer archivos con extensión .DAT (.dat).

Estructura

El comando DT[i,j,by] tiene 3 partes: i, j y by. Si pensamos en una analogía a la terminología de SQL, la i corresponde a WHERE, j a SELECT y by a GROUP BY.

df_events_results[, mean(duration), by = year]
##    year       V1
## 1: 2012 135.2778
## 2: 2013 165.8617
## 3: 2014 166.0702

El campo se ha creado con un valor por defecto. Para asignar un nombre al campo nuevo donde se almacenará la media de la duración usamos el símbolo :=

df_events_results[, medDur := mean(duration), by = month]

Ahora vamos a modificar este cálculo para obtener la media de la duración de los eventos en cada mes, pero considerando únicamente aquellos menores a 100 minutos.

df_events_results[duration<=100, medDur := mean(duration), by = month]

La asignación de una clave en el data.table permite optimizar los tiempos de búsqueda para ordenar, filtrar y buscar elementos en el objeto data.table. Esta indexación es similar a la que se utiliza en bases de datos formales. Pruebe la diferencia de tiempos cuando se designa una clave de tabla y cuando se omite este comando. Actividad: ¿Cómo se designa una clave combinada (Ejm. fecha inicio y fecha fin)?

setkey(df_events_results, id)

Trabajo –/julio/2015

Resolver el siguiente problema usando tres métodos:

  • Library data.table
  • Library sqldf
  • Métodos conocidos de agregación

Efectuar pruebas de control de tiempo y visualizar los resultados de manera gráfica.

PROBLEMA: Dado el archivo "TOA5_2833.ts_data.dat" descargar aquí con una frecuencia de 5 centisegundos, genere la agregación de estos datos a 5,15 y 30 minutos. Como resultado de esta agregación 3 campos adicionales deben calcularse:

  • Media de los campos:
  1. Air_Temp_Avg (m.T)
  2. Uz (m.Uz)
  • Además calcular el campo 3. i.T = Air_Temp_Avg - m.T

  • Finalmente asignar el valor de NA a los registros de i.T cuyo valor absoluto sea mayor que 2.

  • Guardar los resultados de cada caso en archivos de texto.

Nota: Recuerde que su solución debe ser generalizada, es decir para este caso particular la agregación es 5,15 y 30 minutos; sin embargo que tal si mañana debe modificar su código para 10 minutos. Idealmente solo debería modificar el valor de una variable.