Replies: 4 comments 21 replies
-
If you precompute the "distance to road" at the grid locations and add them as
The |
Beta Was this translation helpful? Give feedback.
-
library(inlabru)
library(terra)
library(fmesher)
library(INLA)
library(ggplot2)
mexdolphin <- mexdolphin_sf
mesh <- mexdolphin$mesh
mxcrs <- sf::st_crs(mexdolphin$points)$proj4string I create rasters for dolphin encounters and the distance to transects # aggregate the data
flat_rast <- rast(terra::ext(mexdolphin$depth), crs = crs(mxcrs), resolution=20)
mexdolphin_rast <- rasterize(vect(mexdolphin$points), flat_rast, fun = sum, background = 0) |>
mask(vect(mexdolphin$ppoly))
plot(mexdolphin_rast) # raster for distance to transects
dist_rast <- rasterize(vect(mexdolphin$samplers), flat_rast, fun=sum) |> terra::distance()
dist_rast |> plot() Here's the aggregated count raster on the background of the original data # plot the new data
ggplot() +
gg(mexdolphin_rast) +
gg(mexdolphin$ppoly, fill = NA) +
gg(mexdolphin$samplers, color = "grey") +
gg(mexdolphin$points, size = 0.2, alpha = 1, color = "firebrick") +
theme(legend.key.width = unit(x = 0.2, "cm"), legend.key.height = unit(x = 0.3, "cm")) +
theme(legend.text = element_text(size = 6)) I extract the coordinates for the cells and cast them to # coordinates data
mexdolphin_pxdf <- crds(mexdolphin_rast, df = TRUE, na.rm = TRUE) |>
cbind(values(mexdolphin_rast, na.rm = TRUE)) |>
dplyr::rename(count = sum) |>
sf::st_as_sf(coords = c("x", "y"), crs = crs(mxcrs)) Here's a new (regularly spaced) mesh # make new (regular) mesh
mexdolphin_pxmesh <- INLA::inla.mesh.2d(
loc = sf::as_Spatial(mexdolphin_pxdf),
boundary = sf::as_Spatial(mexdolphin$ppoly) |> inla.sp2segment(),
max.edge = c(100, 200), crs = crs(mxcrs)
)
# make new prior
pxmatern <- inla.spde2.pcmatern(mexdolphin_pxmesh,
prior.sigma = c(2, 0.01),
prior.range = c(50, 0.01)
)
ggplot() + gg(mexdolphin_pxmesh) The components and the formula # distance sampling
hn <- function(distance, sigma) {
exp(-0.5 * (distance / sigma)^2)
}
cmp <- count ~ mySPDE(main = geometry, model = pxmatern) +
# to transform the prior of sigma to be exponentially distributed
sigma(1, prec.linear = 1, marginal = bru_mapper_marginal(qexp, pexp, dexp, rate = 1 / 100)) +
# distance to transect cells
distroad(dist_rast$layer, model = "linear") +
Intercept(1)
frm <- count ~ mySPDE + log(hn(distroad, sigma)) + Intercept + log(2) I want to use these in the poisson model. Perhaps my grid is too coarse, but the model would not fit. # commented away because it would not run
# fit <- bru(
# cmp,
# like(
# data = mexdolphin_pxdf, family = "poisson",
# formula = frm,
# options = list(safe=TRUE, inla.mode="experimental" )
# )
# ) Created on 2023-09-14 with reprex v2.0.2 |
Beta Was this translation helpful? Give feedback.
-
Another issue that I have is that I want a bounded detection function. My distance is on |
Beta Was this translation helpful? Give feedback.
-
I am still not certain what is happening with the distance sampling when distance is provided via the raster library(tidyverse)
library(sf)
#> Linking to GEOS 3.10.2, GDAL 3.4.1, PROJ 8.2.1; sf_use_s2() is TRUE
library(inlabru)
library(terra)
#> terra 1.7.46
# detection function
hn <- function(distance, sigma) {
exp(-0.5 * (distance / sigma)^2)
}
# detection function
hzrt <- function(distance, sigma, bt=2) {
1 - exp(-(distance / sigma)^(-bt))
}
counts_df <- read_csv("obs_df.csv") |>
st_as_sf(coords=c("x", "y"), crs=4326)
#> Rows: 163 Columns: 4
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> dbl (4): count, present, x, y
#>
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
This is a very simple dataset with the count and coordinates. The dist2road_rstr <- rast("dist_road.tiff")
dist2road_rstr |> plot() My "distance to road" raster px_mesh <- fm_mesh_2d_inla(
loc=st_as_sfc(counts_df),
boundary = st_convex_hull(st_union(counts_df)),
max.edge = c(2, 4),
crs=st_crs(counts_df)
)
px_matern <- INLA::inla.spde2.pcmatern(
px_mesh,
prior.sigma = c(0.1, 0.01),
prior.range = c(0.1, 0.01)
)
ggplot() +
geom_fm(data = px_mesh) +
# geom_sf(data=counts_df, aes(color=count), size=1, pch=4)+
theme_minimal() Here I am plotting all the counts including those I suppressed (made into zero or NA) comps <- ~ dist(dist2road_rstr$max, model="linear") +
sigma(1, prec.linear = 1, marginal=bru_mapper_marginal(qexp, pexp, dexp, rate=1/1e3)) +
field(geometry, model = px_matern) + Intercept(1)
fit_poi <- bru(
comps,
like(
family = "poisson", data = counts_df,
formula = count ~ field + Intercept +
log(hn(dist, sigma))+ log(2)
)
)
summary(fit_poi)
#> inlabru version: 2.9.0.9011
#> INLA version: 23.10.19-1
#> Components:
#> dist: main = linear(dist2road_rstr$max), group = exchangeable(1L), replicate = iid(1L)
#> sigma: main = linear(1), group = exchangeable(1L), replicate = iid(1L)
#> field: main = spde(geometry), group = exchangeable(1L), replicate = iid(1L)
#> Intercept: main = linear(1), group = exchangeable(1L), replicate = iid(1L)
#> Likelihoods:
#> Family: 'poisson'
#> Data class: 'sf', 'tbl_df', 'tbl', 'data.frame'
#> Predictor: count ~ field + Intercept + log(hn(dist, sigma)) + log(2)
#> Time used:
#> Pre = 0.705, Running = 0.956, Post = 0.497, Total = 2.16
#> Fixed effects:
#> mean sd 0.025quant 0.5quant 0.975quant mode kld
#> dist 0.00 0.00 0.000 0.00 0.001 0.00 0
#> sigma 0.00 1.00 -1.961 0.00 1.961 0.00 0
#> Intercept 0.93 0.04 0.851 0.93 1.009 0.93 0
#>
#> Random effects:
#> Name Model
#> field SPDE2 model
#>
#> Model hyperparameters:
#> mean sd 0.025quant 0.5quant 0.975quant mode
#> Range for field 0.962 1.445 0.083 0.54 4.50 0.206
#> Stdev for field 0.031 0.038 0.003 0.02 0.13 0.007
#>
#> Deviance Information Criterion (DIC) ...............: 725.78
#> Deviance Information Criterion (DIC, saturated) ....: 179.26
#> Effective number of parameters .....................: 2.28
#>
#> Watanabe-Akaike information criterion (WAIC) ...: 727.61
#> Effective number of parameters .................: 3.71
#>
#> Marginal log-Likelihood: -380.03
#> is computed
#> Posterior summaries for the linear predictor and the fitted values are computed
#> (Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
I am concerned by the zero coefficient by the distance and the 0,1 posterior on the scale (sigma). Something is wrong and it is not getting any better under a different model. comps_zap <- ~ dist(dist2road_rstr$max, model="linear") +
sigma(1, prec.linear = 1, marginal=bru_mapper_marginal(qexp, pexp, dexp, rate=1/1e3)) +
field_count(geometry, model = px_matern) + Intercept_count(1)+
field_present(geometry, model = px_matern) + Intercept_present(1)
fit_zap <- bru(
comps_zap,
like(
family = "binomial", data = counts_df,
formula = present ~ field_present + Intercept_present +
log(hn(dist, sigma))+ log(2)
),
like(
family="nzpoisson", data = counts_df[counts_df$present>0,],
formula = count ~ field_count + Intercept_count
)
)
summary(fit_zap)
#> inlabru version: 2.9.0.9011
#> INLA version: 23.10.19-1
#> Components:
#> dist: main = linear(dist2road_rstr$max), group = exchangeable(1L), replicate = iid(1L)
#> sigma: main = linear(1), group = exchangeable(1L), replicate = iid(1L)
#> field_count: main = spde(geometry), group = exchangeable(1L), replicate = iid(1L)
#> Intercept_count: main = linear(1), group = exchangeable(1L), replicate = iid(1L)
#> field_present: main = spde(geometry), group = exchangeable(1L), replicate = iid(1L)
#> Intercept_present: main = linear(1), group = exchangeable(1L), replicate = iid(1L)
#> Likelihoods:
#> Family: 'binomial'
#> Data class: 'sf', 'tbl_df', 'tbl', 'data.frame'
#> Predictor:
#> present ~ field_present + Intercept_present + log(hn(dist, sigma)) +
#> log(2)
#> Family: 'nzpoisson'
#> Data class: 'sf', 'tbl_df', 'tbl', 'data.frame'
#> Predictor: count ~ field_count + Intercept_count
#> Time used:
#> Pre = 0.981, Running = 1.28, Post = 0.282, Total = 2.54
#> Fixed effects:
#> mean sd 0.025quant 0.5quant 0.975quant mode kld
#> dist 0.001 0.002 -0.003 0.001 0.004 0.001 0
#> sigma 0.000 1.000 -1.961 0.000 1.961 0.000 0
#> Intercept_present 4.674 1.138 2.443 4.674 6.905 4.674 0
#> Intercept_count 1.604 0.036 1.533 1.604 1.674 1.604 0
#>
#> Random effects:
#> Name Model
#> field_present SPDE2 model
#> field_count SPDE2 model
#>
#> Model hyperparameters:
#> mean sd 0.025quant 0.5quant 0.975quant mode
#> Range for field_present 1.103 1.784 0.099 0.596 5.342 0.237
#> Stdev for field_present 0.025 0.028 0.002 0.016 0.098 0.005
#> Range for field_count 0.967 1.457 0.084 0.542 4.529 0.208
#> Stdev for field_count 0.031 0.037 0.003 0.020 0.128 0.007
#>
#> Deviance Information Criterion (DIC) ...............: 732.49
#> Deviance Information Criterion (DIC, saturated) ....: NA
#> Effective number of parameters .....................: 5.32
#>
#> Watanabe-Akaike information criterion (WAIC) ...: 736.66
#> Effective number of parameters .................: 6.75
#>
#> Marginal log-Likelihood: -381.82
#> is computed
#> Posterior summaries for the linear predictor and the fitted values are computed
#> (Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)') Created on 2023-11-06 with reprex v2.0.2 The files are attached here |
Beta Was this translation helpful? Give feedback.
-
I am trying to implement the model, where I have the aggregated counts on a grid. Some counts are low (or even missing) because they are undersampled. I wanted to implement a distance sampling algorithm, but then I discovered that
samplers
argument is only defined forfamily="cp"
.Literature:
How do I adjust for "distance to road" if I have total counts per pixel?
Here's an example of implementation in INLA
Beta Was this translation helpful? Give feedback.
All reactions