Archivo de la categoría: Formación

Datos agrupados en R con dplyr

Entrada rápida para ilustrar como crear un campo autonumérico por un factor, es una duda que me plantean, tienen datos de clientes y fechas y necesitan crear un autonumérico en R que les diga el número de orden de los eventos de una fecha. Algo parecido a lo que hacemos con el retain de R. Vamos a ilustrar la tarea con un ejemplo:

clientes = 100
id_cliente = rpois(clientes,10)
fecha = rpois(clientes, today()-rpois(clientes,5) )

eventos <- cbind.data.frame(id_cliente,fecha)

eventos$fecha <- as.Date(eventos$fecha, origin="1970-01-01")
eventos <- eventos %>% arrange(id_cliente,fecha) 

100 clientes que aparecen una o n veces con fechas asociadas, el primer paso que sugiero hacer es eliminar duplicados con dplyr:

eventos <- eventos %>% group_by(id_cliente, fecha) %>% 
  filter(row_number()==1) %>% as_tibble()

Agrupamos por cliente y fecha y nos quedamos con el primer registro, en este caso da igual quedarse con el primero que con el último. Ahora que no tenemos duplicados la agrupación ya no es por cliente y por fecha, como vamos a crear un valor agrupado por cliente haremos el group_by solo por cliente:

eventos <- eventos %>% group_by(id_cliente) %>% 
  mutate(evento=row_number()) %>% as_tibble()

Cada evento irá numerado de 1 a n gracias a row_number(), el mismo se reinicia a 1 cada vez que cambia el valor del group_by.

Transformar todos los factores a carácter de mi data frame de R

En muchas ocasiones no quiero factores en mi dataframe cuando trabajo con R. Y estoy en mi derecho de poner una entrada sobre una de las tareas que más realizo y que siempre se me olvida el como la realizo, tardo menos en buscarlo en www.analisisydecision.es que entre mis programas:

df<- data.frame(lapply(df, as.character), stringsAsFactors=FALSE)

Todos los elementos factor ahora son character.

 

Mapa del COVID-19 por Comunidades Autónomas con R (más #rstats)

Estoy muy activo en twitter con el #covid-19 estos días y eso está dando lugar a algunas entradas en el blog. Sin embargo, he parado esa actividad porque el número de casos no me parece el indicador adecuado para medir la verdadera incidencia de la pandemia. Empiezo a tener posibles casos entre personas conocidas y no se realiza ningún test, permanecen en casa y son casos no informados. Sin embargo, quería que esta entrada sirviera de homenaje a la gente de Datadista que está recogiendo datos y realizan un seguimiento del número de camas ocupadas, uno de los mejores indicadores. Además sigo mi labor formativa con Rstats, hoy toca:

  • Mapa rápido y guarro de España con GADM
  • Homogeneización de textos con dplyr y tm
  • Complicar el web scraping con rvest

Esta entrada surge aquí:

Datadista pone a nuestra disposición datos actualizados por Comunidad Autónoma y con ellos podemos construir los mapas.

Mapa por Comunidad Autónoma con datos de Datadista

#Situación por Comunidad Autónoma
library(gganimate)
library(maptools)
library(raster)
library(maps)
library(tidyverse)

datadista = "https://raw.githubusercontent.com/datadista/datasets/master/COVID%2019/ccaa_covid19_casos.csv"

tabla_ccaa <- read.csv2(datadista, sep=',',encoding = 'UTF-8', check.names=FALSE)

Espania <- getData('GADM', country='Spain', level=1)
Espania$name = Espania$NAME_1
ccaa <- map_data(Espania)

pinta <- tabla_ccaa[,c(2,length(tabla_ccaa))]
names(pinta)=c("region","casos")

unique(ccaa$region)
unique(pinta$region)

ccaa <- ccaa %>% mutate(region=case_when(
  region == "Región de Murcia" ~ "Murcia",
  region == "Principado de Asturias" ~ "Asturias",
  region == "Comunidad de Madrid" ~ "Madrid",
  region == "Comunidad Foral de Navarra" ~ "Navarra",
  region == "Comunidad Valenciana" ~ "C. Valenciana",
  region == "Islas Canarias" ~ "Canarias",
  region == "Islas Baleares" ~ "Baleares",
  TRUE ~ region))

ccaa <- left_join(ccaa,pinta)

ggplot(data = ccaa, aes(x = long, y = lat, group = group)) +
  geom_polygon(aes(fill = casos)) +
  scale_fill_continuous(low="white",high="red") +
  labs(title = "Mapa del COVID-19 por Comunidad Autónoma") + 
  theme(panel.background =   
          element_rect(fill='#838596',colour='#838596'),
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank()) + 
  theme(axis.line=element_blank(),axis.text.x=element_blank(),
        axis.text.y=element_blank(),axis.ticks=element_blank(),
        axis.title.x=element_blank(),
        axis.title.y=element_blank())

Este código da lugar al mapa con el que se incia esta entrada. Como aspectos interesantes tiene descargar directamente el mapa con R de gadm o la lectura de cabeceras con formato fecha, algo que no conocía, nunca había usado check.names=FALSE. Por lo demás no es un código especialmente complicado. Pero me gustaría escribir sobre la relativización de los datos, no podemos decir que Madrid tiene 5 veces más casos que otra provincia si Madrid tiene 5 veces más habitantes que otra provincia, es necesario relativizar el número de casos y en este caso vamos a emplear el número de habitantes y además nos va a servir para hacer web scraping sobre una tabla de una página web.

Scraping sobre datosmacro. Mapa de casos por número de habitantes

El código empieza del siguiente modo:

library(rvest)
library(xml2)
library(tm)
numerea <- function(x) {as.numeric(sub(",",".",x)) }

url = 'https://datosmacro.expansion.com/demografia/poblacion/espana-comunidades-autonomas'

Si vais a la url indicada tenemos que extraer la tabla específica con el número de habitantes y para eso necesitamos saber en que lugar del código HTML se encuentra. En mi caso empleo Google Chrome, imagino que será análogo con otros navegadores. Hacemos lo siguiente:

Nos ubicamos sobre la tabla que deseamos scrapear (verbo regular de la primera conjugación) damos a inspeccionar y nos aparece la codificación, dentro de la codificación si pulsamos se marcará la tabla y Coppy + Copy XPath y con ello ya podemos crear un data frame con la tabla HTML:

poblacion <- url %>%
  html() %>%
  html_nodes(xpath='//*[@id="tb1"]') %>%
  html_table()
poblacion <- poblacion[[1]]

poblacion <- poblacion [,-4] %>% mutate(CCAA = removePunctuation(CCAA),
                                        CCAA = substr(CCAA,1,nchar(CCAA)-1),
                                        habitantes=numerea(removePunctuation(Población))) %>%
  rename(region=CCAA) %>%
  select(region, habitantes) %>% mutate(region=case_when(
    region == "Comunidad Valenciana" ~ "C. Valenciana",
    region == "Castilla La Mancha" ~ "Castilla-La Mancha",
    region == "Islas Baleares" ~ "Baleares",
    TRUE ~ region
  ))

en html_nodes hemos puesto el XPath y ya sabe que parte tiene que leer, como se genera una lista nos quedamos con el primer elemento de la lista y posteriormente se realiza la homogeneización de los nombres de las comunidades, eliminación de signos de puntuación con removePunctuation (que ha cambiado mi vida porque odio regex). Esta tabla puede ser cruzada con los datos de Datadista y crear un número de casos entre habitantes x 1000:

unique(poblacion$region)
unique(ccaa$region)

ccaa <- left_join(ccaa,poblacion)
ccaa$tasa_COVID <- (ccaa$casos/ccaa$habitantes)*1000


ggplot(data = ccaa, aes(x = long, y = lat, group = group)) +
  geom_polygon(aes(fill = tasa_COVID)) +
  scale_fill_continuous(low="white",high="red") +
  labs(title = "Mapa del COVID-19 por Comunidad Autónoma") + 
  theme(panel.background =   
          element_rect(fill='#838596',colour='#838596'),
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank()) + 
  theme(axis.line=element_blank(),axis.text.x=element_blank(),
        axis.text.y=element_blank(),axis.ticks=element_blank(),
        axis.title.x=element_blank(),
        axis.title.y=element_blank())

Y el resultado sigue siendo alarmante en Madrid pero la tonalidad del rojo cambia mucho en otras zonas de España, la importancia relativizar un dato.

Evolución del número de casos de coronavirus

Seguimos a vueltas con la (ya) pandemia y R y hoy quería traeros unos buenos ejemplos de uso de la librería dplyr para preparar datos. Se trata de ver una evolución del número de casos diarios para saber en qué punto tanto España como Italia pueden frenar el crecimiento de los casos de coronavirus, se trata de crear este gráfico:

Se observa como países como China o Korea vivieron un fuerte crecimiento que ahora se ha transformado en una caída del número de casos de coronavirus, pero parece que Irán ha estabilizado en 1000 casos diarios pero Italia y España siguen en fase de crecimiento por lo que no se espera que el comportamiento sea similar a China o Korea y es probable que el número de casos siga aumentando.

Para crear este gráfico estoy mejorando códigos que ya he venido utilizando y creo que son un buen ejemplo de uso de dplyr. El primer paso es crear el conjunto de datos inicial, código ya conocido:

library(lubridate)
library(ggplot2)
library(dplyr)
library(gridExtra)
datos <- read.csv2("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv",
                   sep=',')


fechas <- seq(as.Date("2020/01/22"), as.Date(today()-1), "days")
fechas <- substr(as.character.Date(fechas),6,10)
names(datos) <- c("Provincia", "Pais","Latitud", "Longitud", fechas)

Para ver los datos de China es necesaria una agregación previa ya que China tiene los datos a nivel de región y no de país:

China <- filter(datos,Pais=="China")
China <- China %>% select(fechas) 
China <- data.frame(casos=as.numeric(mapply(sum,China)))
China <- China %>% mutate(fecha=row.names(China), dias=row_number())
China2 <- China %>% mutate(dias=dias+1) %>% rename(casos_menos1=casos) %>% select(-fecha)

China <- left_join(China,China2) %>% 
  mutate(incremento = casos-casos_menos1,
         incremento = case_when(is.na(incremento) ~0,
                                TRUE ~ incremento)) %>% 
  filter(dias<=50)

Aquí es interesante el uso de mapply para sumar todas las columnas del conjunto de datos. Por otro lado se trata de crear una variable incremento en función de los días que llevamos recogiendo datos, para ello lo que se hace es cruzar con los mismos datos pero sumamos un día al número de días de pandemia, de este modo, tenemos el dato del día y el dato del día anterior por lo que podemos crear una variable incremento. Para el resto de países, como la información no está a nivel de región, hacemos una función.

select_pais <- function(pais, numdias) {
  P <- filter(datos,Pais==pais) %>% select(fechas)
  P <- P %>% mutate(fecha=row.names(P), dias=row_number())
  P <- data.frame(casos=as.numeric(t(P)))
  P <- P %>% mutate(fecha=row.names(P), dias=row_number())
  P2 <- P %>% mutate(dias=dias+1) %>% rename(casos_menos1=casos) %>% select(-fecha)
  P <- left_join(P,P2) %>% 
    mutate(incremento = casos-casos_menos1,
           incremento = case_when(is.na(incremento) ~0,
                                  TRUE ~ incremento)) %>% 
    filter(dias<=numdias)
  return(P)}

Korea <- select_pais('Korea, South', 50) 
Iran <- select_pais('Iran', 50) 
Italia <- select_pais('Italy', 50) 
Espania <- select_pais('Spain', 50) 

Ya tenemos los datos con la forma deseada. Ahora nos toca realizar un gráfico para cada país:

evolucion <- function(pais) {
  df <- pais
  df$incremento <- ifelse(df$casos<=4,0,df$incremento)
  ggplot(df, aes(x=dias, y=incremento)) +
  geom_bar(stat="identity") + 
  scale_y_continuous(limits = c(0, 3000)) +
  ggtitle(paste0('Incremento de casos en ',deparse(substitute(pais)) )) +
  theme(plot.title = element_text(hjust = 0.5)) +
  xlab("Días desde 22/01/2020")}

p1 = evolucion(China)
p2 = evolucion(Korea)
p3 = evolucion(Espania)
p4 = evolucion(Italia)
p5 = evolucion(Iran)

Una función que realiza un gráfico de barras con ggplo2 para cada país y tiene un uso interesante de la función deparse que junto con sustitute nos permite poner en la función el nombre del data frame y no los datos que contiene. Es una forma sencilla de obtener el nombre de un data frame en una función. Si leéis que me reitero en algunas frases no os asustéis, sirve para facilitar búsquedas.

Ahora empleamos una librería que cambió mi vida gridExtra y podemos realizar el gráfico que abre esta entrada:

grid.arrange(p1, p2,p3,p4,p5,ncol=1)

En este punto sólo queda ejecutar este código todos los días y esperar a que Italia y España lleguen a ese máximo. Saludos.

Seguimiento del coronavirus en España por Comunidad Autónoma. Extraer información de un PDF con R

Una entrada anterior del blog ha dado lugar a una conversación interesante en twitter:

Es necesario obtener los datos del Ministerio y estos datos se hayan en un pdf (https://www.mscbs.gob.es/profesionales/saludPublica/ccayes/alertasActual/nCov-China/documentos/Actualizacion_41_COVID-19.pdf) Bien, tendremos que leer el pdf y crear un data frame para poder trabajar con estos datos. Para leer el pdf vamos a emplear el paquete de R tabulizer y la función extract_table pero necesitamos “algo de talento”.

La función extract_tables nos permite extraer información de un archivo pdf con R pero es necesario especificar la página que deseamos leer (fácil) y el área que deseamos leer. ¿El área de la hoja del pdf que deseamos leer? ¿Eso qué es? Pues ese es el “talento” que necesitamos, con la función locale_areas vamos a encontrar ese área. Veamos el código necesario:

library(tidyverse)
library(tabulizer)

ministerio = "https://www.mscbs.gob.es/profesionales/saludPublica/ccayes/alertasActual/nCov-China/documentos/Actualizacion_41_COVID-19.pdf"

area <- locate_areas(ministerio, pages = 2)

Al ejecutar ese código podemos seleccionar a mano alzada el área que deseamos seleccionar de la página específica del pdf:

Ya estamos en disposición de ver el área a leer:

area[[1]]

Un poco complicado, pero una vez sabemos el área crear un objeto con R que contenga la información actualizada por Comunidad Autónoma de los datos del coronavirus en España con R es así de sencillo:

pdf_lista <- extract_tables(
  ministerio,
  output = "data.frame",
  pages = c(2),
  area = list(
    c(337.89431,  90.69972, 684.23597, 510.25186)
  ),
  guess = FALSE,
  encoding = "UTF-8"
)


datos <- data.frame(pdf_lista[1])

Ahora ya tenéis los datos por Comunidad Autónoma actualizados, solo queda que alguien los tabule por día y haga representaciones gráficas. Ahora a esperar que el Ministerio no cambie el pdf. Mañana haremos algo con ellos.

Seguir los datos del coronavirus en España con Rstats

No he podido evitarlo, os traigo unas líneas de código en R para seguir la evolución del coronavirus en España (podéis filtrar cualquier país). Me hubiera gustado hacer un scraping de la página https://www.worldometers.info/coronavirus/ sin embargo me ha parecido más sencillo leer directamente los datos del repositorio de la Universidad Jonh Hopkins (https://github.com/CSSEGISandData/COVID-19) creo que la actualización es diaria. También existe ya un paquete en R denominado coronavirus pero su funcionamiento deja que desear. Por mi parte os ofrezco para seguir su evolución el siguiente script:

library(lubridate)
library(ggplot2)
datos <- read.csv2("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv",
                 sep=',')

fechas <- seq(as.Date("2020/01/22"), as.Date(today()-1), "days")
fechas <- as.character.Date(fechas)
names(datos) <- c("Provincia", "Pais","Latitud", "Longitud", fechas)

espania <- datos %>% filter(Pais=="Spain") %>% select(fechas)
espania <- data.frame(t(espania))
espania$fecha <- row.names(espania)
names(espania) <- c("casos", "fecha")

p <- ggplot(espania, aes(x=fecha, y=casos, group = 1)) +
  geom_line() + 
  xlab("")
p

Tendría que mejorar los ejes y el aspecto, pero no es eso lo más importante. Estaba escribiendo sobre distribuciones tweedie, ahora me siento tentado para escribir sobre modelos exponenciales y si hacéis esto mismo para los datos de Italia hace 10 días la verdad es que el gráfico es calcado.

Cloud words con R. Trabajar con la API del Europe PMC con R

Hace años ya tuvimos nubes de palabras en el blog y ya era hora de ir actualizando algunas cosas. Y además quería aprovechar y presentaros un paquete de R que nos permite consultar la API del Europe PMC. Para quien no sepa que es el Europe PMC podemos decir que es un un buscador de documentos y artículos científicos (que ahora todo el mundo molón llama papers) y que tiene una API desde la que podemos acceder desde R mediante el paquete europepmc.

Obtener datos de la API de Europe PMC con R

El primer paso para trabajar con la librería de R europepmc sería obtener el número de artículos publicados con el topic “Autism” en su descripción, para ello podemos hacer:

#install.packages("europepmc")
library(dplyr)
library(ggplot2)
library(europepmc)

autismo <- epmc_hits_trend("Autism", period = 2000:2019, synonym = TRUE)
autismo
ggplot(autismo, aes(year,  query_hits)) + 
  geom_line() +
  xlab("Año de Publicación") + 
  ylab("Articulos publicados sobre Autismo")

La función del paquete de R europepmc epmc_hits_trend obtiene de un periodo dado el número de artículos y el número de artículos de un determinado tópico. Como vemos se está incrementando casi exponencialmente el número de artículos dedicados al Autismo en los últimos años, no es una tendencia particular, se está incrementando el número de papers (asco de término pero que tiene que aparecer para las búsquedas), estamos ante la “burbuja de los papers” ya que da mas notoriedad hacer mucho que hacer bien, ya se lo leerá una inteligencia artificial, en fin que me disperso. Pero la función que puede resultarnos más interesante es epmc_search que crea un data frame con las búsquedas de los artículos con su ISBN, fechas de referencia, autores,… nos va a servir para obtener unas nubes de palabras sobre los escritos acerca del autismo Seguir leyendo Cloud words con R. Trabajar con la API del Europe PMC con R

Gráficos de calendarios con series temporales

Cuando se realizan gráficos de series temporales se emplean gráficos de líneas donde el eje X contiene la fecha y el eje Y contiene el valor a representar. Hoy quiero traer al blog otra forma de representar series temporales, los gráficos de calendario y su realización con R. Para ilustrar el ejemplo vamos a emplear las cotizaciones históricas del índice bursatil IBEX35:

require(quantmod)
require(ggplot2)
require(reshape2)
require(dplyr)
library(lubridate)

# Obtenemos las cotizaciones del IBEX 35 desde 2010
getSymbols('^IBEX', from = '2010-01-01')

# data frame de trabajo
df<-data.frame(date=index(IBEX),IBEX)

Mediante quantmod extraemos las cotizaciones del IBEX desde 2010 y creamos un data frame de trabajo que llamamos df. Vamos a realizar dos tipos de gráficos, un mapa de calor por años, meses, semanas y días y un calendario de un año puntual.

Calendario como mapa de calor por

Este es un gráfico basado en un trabajo anterior (¡de 2012!) y es una forma imaginativa de representar el cierre del IBEX 35 desde 2010 en una sola imagen. El primer paso será crear las variables a representar en el mapa de calor, el mes, el día de la semana y la semana dentro del mes:

df <- df %>% mutate(año=year(date),
                    mes=factor(month(date),levels=(1:12),
                               labels = c("ENE","FEB","MAR","ABR","MAY","JUN","JUL",
                                              "AGO","SEP","OCT","NOV","DIC"),ordered = T),
                    dia=factor(wday(date)-1,levels=rev(1:7),
                          labels=rev(c("L","M","X","J","V","S","D"))),
                    semanames=ceiling(day(date) / 7))

Ahora sólo queda representar el gráfico mediante ggplot2 donde los paneles de facet_grid serán los años en eje X y los meses en eje Y:

# Realizamos el calendario
calendario1<- ggplot(df, aes(semanames, dia, fill = IBEX.Adjusted)) + 
  geom_tile(colour = "white") + facet_grid(año~mes) + 
  scale_fill_gradient(low = "red", high = "darkgreen", na.value = "black") +  
  labs(title="Cierre histórico del IBEX", x ="Semana del mes", y = "")
calendario1

Un gráfico que me gusta bastante y una original forma de representar series temporales muy largas, no he usado paletas de colores pero imagino que los resultados mejorarán, podéis aportar esas mejoras en los comentarios.

Calendario con openair y calendarPlot

Si deseamos representar un calendario de un año concreto tenemos la función calendarPlot de openair (que me ha costado instalar en Ubuntu) que no puede ser más sencilla:

library(openair)
calendarPlot(df, pollutant = "IBEX.Adjusted", year = 2019, cols = "Greens")

Este último calendario no lo he usado pero la sintaxis es muy sencilla y el resultado queda bastante bien. Ahora vosotros mismos podéis juzgar si hay o no hay rally de fin de año.

Obteniendo los parámetros de mi modelo GAM

Vimos como los modelos GAM iban más allá del GLM porque en el momento de obtener los parámetros asociados al modelo de un factor nos proponían, en vez de una función lineal una función de suavizado no paramétrica para aquellos factores susceptibles de transformar en variables numéricas ordinales con un sentido determinado. Se trabajó con un modelo de riesgo con una sola variable como era la edad y al sumarizar el modelo no era posible obtener los parámetros en la salida. En último término nuestra intención con este tipo de modelos es obtener esos parámetros para transformarlos en relatividades. Qué sentido tiene obtener un buen modelo para Negocio si su resultado no se puede expresar en términos de incrementos o descuentos, en términos de relatividades.

La entrada del blog que ahora os propongo nos permite extraer los parámetros de cualquier modelo GLM o GAM a partir de la función predict y una de las opciones más olvidadas por todos nosotros:

predict(modelo, newdata = datos,  type = "terms")

con type = “terms” lo que obtenemos en el momento de realizar la predicción son los parámetros del modelo que aplicamos, no es el resultado de la predicción.

Obteniendo las relatividades de nuestro modelo GAM

Partimos del ejemplo que estamos manejando en la serie de entradas:

library(dplyr)

varib <- c(edad = 2L, sexo = 1L, zona = 1L, clase_moto = 1L, antveh = 2L,
           bonus = 1L, exposicion = 8L, nsin = 4L, impsin = 8L)

varib.classes <- c("integer", rep("factor", 3), "integer",
                   "factor", "numeric", rep("integer", 2))

con <- url("https://staff.math.su.se/esbj/GLMbook/mccase.txt")
moto <- read.fwf(con, widths = varib, header = FALSE,
                 col.names = names(varib),
                 colClasses = varib.classes,
                 na.strings = NULL, comment.char = "")


library(mgcv)

moto$edad_numero <- as.numeric(moto$edad)

gam.1 <- gam(nsin ~ s(edad_numero,bs="cr",k=3) + zona, data=filter(moto,exposicion>0), 
             offset = log(exposicion), family = poisson(link='log'))
summary(gam.1)

Ejecutad este código y obtendréis un modelo GAM con la zona por la que circula el riesgo y una función de suavizado de la edad del asegurado. A la hora de sumarizar el modelo para la edad, la variable suavizada, no vemos parámetros solo una función, si queremos obtener parámetros solo aparece la zona, ¿cómo puedo obtener las relatividades que me arroja este modelo? Empleando predict como se indicó con anterioridad:

terminos <- data.frame(exp(predict(gam.1, newdata = moto, type = "terms")))
names(terminos) <- c("rela_zona","rela_edad") 
terminos <- cbind.data.frame(terminos,select(moto,zona,edad))

Se crea el data.frame terminos que tiene el exponencial del parámetro asociado a ese registro para los factores participantes en el modelo. Cabe señalar que predict no respeta el orden de las variables en el modelo, primero pone las variables que no están suavizadas y después las suavizadas. Después de obtener los parámetros registro a registro lo que hacemos es añadir al data frame los factores de los que deseamos obtener las relatividades y como os podéis imaginar la tabla de relatividades finalmente es el resultado de seleccionar los distintos elementos:

rela_zona <- distinct(select(terminos,zona,rela_zona))
rela_edad <- distinct(select(terminos,edad,rela_edad))

Ya sabéis, no subestiméis a predict...