En este ejercicio vamos a trabajar con la estructura de datos ‘dataframe’.

A partir de un fichero con datos de las estaciones automáticas obtenido del Banco Nacional de Datos Climatológicos (BNDC) de AEMET, vamos a crear un dataframe y realizar distintas operaciones para mostrar cómo se manipulan objetos de esta clase, seleccionando aquellas filas o columnas que nos interesen. Veremos también el tipo factor con más detalle y el paquete ‘dplyr’ para manipular dataframes. Por último, guardaremos los resultados en un fichero.

1.Obtenemos los datos del fichero de estaciones


rm(list = ls())
ls()



getwd()



dirProyecto <- getwd()
fichero_estaciones <- paste0(dirProyecto, "/data/estaciones.csv")
est <- read.table(fichero_estaciones, header=T, sep=';', dec='.', fileEncoding = 'UTF-8')
class(est)
est



summary(est)



str(est)      # estructura del objeto 'est'
typeof(est)   # tipo de almacenamiento interno del objeto
dim(est)      # dimensión 


2.Extraemos la información que deseamos del dataframe


est_ind <- est$INDICATIVO # extraemos todos los indicativos
class(est_ind)
str(est_ind)


est[which(est$INDICATIVO == "1103X"),]


Ahora, por ejemplo, vamos a seleccionar los nombres de las estaciones cuya altitud es superior a 1500 metros:


est_1500 <- est[(est$ALTITUD > 1500),"NOMBRE"]
est_1500


3.Factores

En este apartado vamos a trabajar un poco con el tipo ‘factor’.


est_factor <- read.table(fichero_estaciones, header=T, sep=';', dec='.', stringsAsFactors = TRUE)
str(est_factor)



est$NOM_PROV <- as.factor(est$NOM_PROV)
class(est$NOM_PROV)
est$NOM_PROV
str(est)


Podemos incluso definir los niveles al hacer la conversión:


est$DATUM <- factor(est$DATUM, levels = c("ETRS89", "WGS84"))
est$DATUM
class(est$DATUM)



est_factor2 <- as.data.frame(unclass(est), stringsAsFactors = TRUE)
str(est_factor2)



est_SO_VA <- est[est$NOM_PROV %in% c("SORIA","VALLADOLID"), ]
est_SO_VA2 <- droplevels(est[est$NOM_PROV %in% c("SORIA","VALLADOLID"), ]) # eliminamos los niveles del factor
str(est_SO_VA)
str(est_SO_VA2)



est_SORIA_1_3 <- est[est$NOM_PROV %in% c("SORIA"), 1:3]        # sólo extraigo las 3 primeras columnas
est_SORIA_1_5_6 <- est[est$NOM_PROV %in% c("SORIA"), c(1,5,6)]   # sólo extraigo las columnas 1, 5 y 6
est_SORIA_1_3
est_SORIA_1_5_6


4.El paquete ‘dplyr’ para manipular dataframes

Para simplificar la notación a la hora de manipular objetos de la clase ‘dataframe’, podemos usar el paquete ‘dplyr’:


library(dplyr)
# browseVignettes(package = "dplyr")
# http://127.0.0.1:18579/library/dplyr/doc/dplyr.html


Si queremos extraer filas en función de condiciones a las columnas, tenemos el método filter():


tbl_est <- as_tibble(est)
tbl_est %>% filter(ALTITUD > 1200, NOM_PROV %in% c("SORIA","CANTABRIA"))


Para reordenar filas, usamos el método arrange():


tbl_est %>% arrange(NOM_PROV, ALTITUD)
tbl_est %>% arrange(desc(ALTITUD)) %>% arrange(desc(NOM_PROV))


Para seleccionar filas usando su posición con slice():


tbl_est %>% slice(c(1,3,5))
tbl_est %>% slice_head(n=8)
tbl_est %>% slice_tail(n=8)
tbl_est %>% slice_sample(n=8)
tbl_est %>% filter(!is.na(ALTITUD)) %>% slice_max(ALTITUD, n = 3)
tbl_est %>% filter(!is.na(ALTITUD)) %>% slice_min(ALTITUD, n = 5)


Para seleccionar columnas con select():


tbl_est %>% select(INDICATIVO:ALTITUD)
tbl_est %>% select(INDICATIVO, NOMBRE, ALTITUD)
tbl_est %>% select(!(INDICATIVO:ALTITUD))


Para renombrar columnas con rename():


tbl_est %>% rename(Z = ALTITUD)


Para añadir nuevas columnas a las ya existentes con mutate():


tbl_est %>% mutate(PAIS = "ESPAÑA")
tbl_est %>% mutate(PAIS = "ESPAÑA") %>% select(PAIS, everything())


Para crear nuevas columnas y no guardar las anteriores trasmute(), creando un nuevo dataframe sólo con las nuevas columnas:


tbl_est %>% transmute(ALTITUD_km = ALTITUD / 1000)


Para cambiar el orden de las columnas con relocate():


tbl_est %>% relocate(LATITUD:ALTITUD, .before = NOMBRE)


Para resumir el dataframe summarise():


tbl_est %>% summarise(ALTITUD = mean(ALTITUD, na.rm = TRUE), COORDENADA_X = max(COORDENADA_X, na.rm = TRUE) )


Para agrupar con group_by():


est_by_nomprov <-group_by(tbl_est, NOM_PROV)
est_by_nomprov


No cambia el dataframe, pero al efectuar otras operaciones lo hace en base a los grupos:


est_by_nomprov %>% summarise(ALTITUD = mean(ALTITUD),  COORDENADA_X = max(COORDENADA_X, na.rm = TRUE))
est_by_nomprov %>% filter(ALTITUD == max(ALTITUD))


Podemos concatenar los métodos:


tbl_est_new <- tbl_est %>%
  group_by(NOM_PROV) %>%
  select(NOMBRE, INDICATIVO, ALTITUD, COORDENADA_X) %>%
  summarise(
    ALTITUD = mean(ALTITUD, na.rm = TRUE),
    COORDENADA_X = max(COORDENADA_X, na.rm = TRUE)
  )

tbl_est_new


5. Guardando los resultados en un fichero


fichero_salida_RData = paste0(getwd(),"/data/ejercicio1out.RData")
save(tbl_est, tbl_est_new, file=fichero_salida_RData)


Si las queremos usar en otra sesión de R sólo hay que usar el método load():


rm(list=ls())
fichero_RData = paste0(getwd(),"/data/ejercicio1out.RData")
load(fichero_RData)



fichero_salida_csv = paste0(getwd(), "/data/ejercicio1out.csv")
write.table(tbl_est_new, file=fichero_salida_csv, row.names = FALSE, quote = FALSE, sep = ";")