Métodos determinísticos
Análisis espacial con R
Preparar datos para interpolación
library(tidyverse)
library(sf)
library(tmap)
region <- read_rds('data/regs_utm_sf.rds')
data_temp <- read_rds('data/data_temp_enero.rds')[c('ema','temp_enero')]
set.seed(432)
data_temp_mod <- data_temp |> sample_frac(0.8)
data_temp_val <- data_temp |> filter(!(ema %in% data_temp_mod$ema))
calc_met <- function(ras,object_sf,var = 'temp_enero') {
df_val <- terra::extract(ras,terra::vect(object_sf)) |>
cbind(object_sf[,var])
rmse <- function(obs,pred) sqrt(sum((obs-pred)^2)/length(obs))
rmse_v <- rmse(df_val[,3],df_val[,2])
r2 <- cor(df_val[,3],df_val[,2])^2
c('rmse' = rmse_v,'rsq' = r2)
}
tm_shape(region) +
tm_borders() +
tm_shape(data_temp) +
tm_dots(col='temp_enero')
Preparar datos para interpolación
Grilla
En R, espacializar temperatura promedio del mes de enero 2023.
library(stars)
library(terra)
bb <- st_bbox(region)
grilla <- rast(xmin = bb$xmin,xmax = bb$xmax,
ymin = bb$ymin,ymax = bb$ymax,
res=10000,crs="EPSG:32719")
grilla_st <- grilla |> st_as_stars() #como clase stars
grilla |> as.polygons() |> plot()
Voronoi (Polígonos de Thiessen)
Zonas de influencia más cercana a cada punto. Caso particular de vecino más próximo con k=1.
temp_vor <- voronoi(vect(data_temp_mod)) |>
terra::rasterize(grilla,'temp_enero') |>
mask(vect(region))
(met_vor <- calc_met(temp_vor,data_temp_val))
rmse rsq
2.1243421 0.3790889
Vecino más próximo
Vecino más póximo con k=1.
kNN Interactivo
library(gstat)
temp_nn <- idw(temp_enero~1, data_temp_mod, grilla_st,nmax=1)
[inverse distance weighted interpolation]
temp_nn <- temp_nn |> rast() |> mask(vect(region)) |> trim()
(met_nn1 <- calc_met(temp_nn[[1]],data_temp_val))
rmse rsq
2.1243421 0.3790889
Vecino más próximo
Vecino más póximo con k=5.
library(gstat)
temp_nn5 <- idw(temp_enero~1, data_temp_mod, grilla_st,nmax=5)
[inverse distance weighted interpolation]
temp_nn5 <- temp_nn5 |> rast() |> mask(vect(region)) |> trim()
(met_nn5 <- calc_met(temp_nn5[[1]],data_temp_val))
rmse rsq
1.620426 0.516043
Vecino más próximo
Vecino más póximo con k=10.
library(gstat)
temp_nn10 <- idw(temp_enero~1, data_temp_mod, grilla_st,nmax=10)
[inverse distance weighted interpolation]
temp_nn10 <- temp_nn10 |> rast() |> mask(vect(region)) |> trim()
(met_nn10 <- calc_met(temp_nn10[[1]],data_temp_val))
rmse rsq
1.5513405 0.5455748
Inverso de la Distancia
- Quizas uno de los métodos más antiguos de predicción espacial.
\[\hat z(s_0) = \sum_{i=1}^n \lambda_i(s_0)\cdot z(s_i)\]
Notación de matriz
\[\hat z(s_0) = \lambda_0^T \cdot z\]
Los pesos se determinan por el inverso de la distancia
\[\lambda(s_0) = \frac{\frac{1}{d^\beta (s_0,S_i)}}{\sum_{i=1}^n \frac{1}{d^\beta (s_0,s_i)}}\] \(\beta >0\)
Inverso de la Distancia
Inverso de la Distancia
En R, espacializar temperatura promedio del mes de enero 2023.
temp_idw <- idw(temp_enero~1, data_temp_mod, grilla_st)
[inverse distance weighted interpolation]
temp_idw <- temp_idw |> rast() |> mask(vect(region)) |> trim()
met_idw <- calc_met(temp_idw[[1]],data_temp_val)
tm_shape(temp_idw[[1]]) +
tm_raster(style = 'cont',palette = viridis::viridis(20)) +
tm_shape(region) +
tm_borders() +
tm_shape(data_temp) +
tm_dots(col='temp_enero',title = "Temperatura (°C)",style = 'jenks',palette = viridis::viridis(10))
Trend surface / regresión en coordenadas
Asumimos que los valores de la variable objetivo (geográficamente ubicada) es función de sus coordenadas.
Podemos determinar sus valores encontrando una función a través de los puntos observados.
Se basa en el siguiente modelo:
\[Z(s) = f(x,y) + \epsilon\]
Trend surface / regresión en coordenadas
En R
\[Temp=\beta_0+\beta_1\cdot x+\beta_2\cdot y\]
data_temp_mod <- cbind(data_temp_mod,st_coordinates(data_temp_mod))
mod.lm1 <- lm(temp_enero ~ X + Y, data=data_temp_mod)
\[Temp = \beta_0+\beta_1\cdot x + \beta_1 \cdot y + \beta_2\cdot x^2+\beta_3\cdot y^2 + \beta_4\cdot x\cdot y\]
mod.lm2 <- lm(temp_enero ~ X + Y + I(X^2) + I(Y^2) + I(X*Y), data=data_temp_mod)
Trend surface / regresión en coordenadas
\[Temp=\beta_0+\beta_1\cdot x+\beta_2\cdot y\]
summary(mod.lm1)$r.squared
\[Temp = \beta_0+\beta_1\cdot x + \beta_1 \cdot y + \beta_2\cdot x^2+\beta_3\cdot y^2 + \beta_4\cdot x\cdot y\]
summary(mod.lm2)$adj.r.squared
summary(mod.lm2)$r.squared
Trend surface / regresión en coordenadas
temp_ts <- c(grilla,grilla)
xy <- xyFromCell(grilla,1:ncell(grilla)) |>
as_tibble() |> set_names(c('X','Y'))
values(temp_ts[[1]])<- predict(mod.lm1, newdata=xy)
values(temp_ts[[2]]) <- predict(mod.lm1, newdata=xy,se.fit=TRUE,inerval='prediction')$se.fit
names(temp_ts) <- c('temperatura','error_estandar')
temp <- mask(temp_ts, vect(region))
(met_ts1 <- calc_met(temp_ts[[1]],data_temp_val))
rmse rsq
1.9647131 0.2579367
Trend surface / regresión en coordenadas
temp_ts2 <- c(grilla,grilla)
values(temp_ts2[[1]])<- predict(mod.lm2, newdata=xy)
values(temp_ts2[[2]]) <- predict(mod.lm2, newdata=xy,se.fit=TRUE,inerval='prediction')$se.fit
names(temp_ts2) <- c('temperatura','error_estandar')
temp_ts2 <- mask(temp_ts2, vect(region))
(met_ts2 <- calc_met(temp_ts2[[1]],data_temp_val))
rmse rsq
1.8479598 0.3549047
Evaluación de los modelos