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.
Borramos todos los objetos almacenados en nuestro entorno de trabajo
Para ver los objetos que tenemos cargados en memoria usamos ls().
Vamos a borrar todos los objetos que tengamos creados en nuestro “Global environment” antes de hacer nuestro ejercicio:
rm(list = ls())
ls()
Comprobamos nuestro directorio de trabajo
Para ver la ruta de nuestro directorio de trabajo usamos getwd().
getwd()
Leemos el fichero ‘estaciones.csv’ obtenido del BNDC
Para saber qué parámetros debemos poner en la función de lectura del fichero, primero abrimos el fichero y vemos si tiene cabecera, qué separador se usa, etc.
Usamos la función ‘read.table’ para leer el fichero.
Nos devuelve un objeto de la clase ‘dataframe’:
dirProyecto <- getwd()
fichero_estaciones <- paste0(dirProyecto, "/data/estaciones.csv")
est <- read.table(fichero_estaciones, header=T, sep=';', dec='.', fileEncoding = 'UTF-8')
class(est)
est
Resumen del contenido del objeto
Si queremos ver un resumen de todo el contenido de un objeto podemos usar la función ‘summary’:
summary(est)
str(est) # estructura del objeto 'est'
typeof(est) # tipo de almacenamiento interno del objeto
dim(est) # dimensión
De una columna determinada
Podemos extraer todos los datos de una columna determinada, por ejemplo, los indicativos de todas las estaciones:
est_ind <- est$INDICATIVO # extraemos todos los indicativos
class(est_ind)
str(est_ind)
Filas que cumplen alguna condición en alguna de las columnas
Por ejemplo, vamos a seleccionar aquella fila cuyo indicativo tiene
un determinado valor: “1103X”
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
En este apartado vamos a trabajar un poco con el tipo ‘factor’.
Leyendo los campos “character” del fichero como “factor”
Podemos leer el fichero de tal manera que nos devuelva un dataframe en el que los campos “character” del fichero los tranforme en “factor”.
est_factor <- read.table(fichero_estaciones, header=T, sep=';', dec='.', stringsAsFactors = TRUE)
str(est_factor)
Convirtiendo a factor sólo algunas columnas
Si sólo nos interesan algunas columnas, podemos convertir el tipo ‘character’ a ‘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)
Quitando la clase dataframe y asignándola de nuevo
Si queremos que sean todas las columnas de tipo factor, también podemos hacerlo quitando la clase y asignando ‘factor’:
est_factor2 <- as.data.frame(unclass(est), stringsAsFactors = TRUE)
str(est_factor2)
Filtrando filas
Podemos filtrar aquellas filas que tengan un determinado valor en la columna NOM_PROV, de tipo ‘factor’ y crear un nuevo dataframe:
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)
Seleccionando columnas
Podemos extraer las columnas que deseemos imponiendo condiciones al valor del factor:
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
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
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 = ";")