-
Notifications
You must be signed in to change notification settings - Fork 0
/
SSDmodeling_Fullmodel_v1.r
118 lines (97 loc) · 3.46 KB
/
SSDmodeling_Fullmodel_v1.r
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# The following R and Stan program code was used for a Bayesian species sensitivity distribution (SSD) model.
# The SSD model with all the predictor variables is provided as an example.
## Necessary packages
library(rstan); library(loo); library(openxlsx)
library(bayesplot) # For illustration
# Some settings
rstan_options(auto_write = T); options(mc.cores = parallel::detectCores())
# Read the dataset
d <- read.xlsx("Data_SSDmodeling_ToMEx2022_v1.xlsx", sheet = "Data")
# Data
list.data <- list(
N = nrow(d),
Log10_tox = log10(d$NOEC_mass),
Log10_size = log10(d$Particle_Length_um),
Media_type = as.numeric(d$Environment == "Freshwater"),
Shape_Fragment = as.numeric(d$Shape == "Fragment"),
Shape_Fiber = as.numeric(d$Shape == "Fiber"),
Polymer_PS = as.numeric(d$Polymer == "Polystyrene"),
Polymer_PE = as.numeric(d$Polymer == "Polyethylene")
)
# Make “.stan” file
cat("data {
int<lower = 0> N; // number of data
real Log10_tox[N]; // log10-transformed chronic NOECs
real Log10_size[N]; // log10-transformed particle length
int<lower = 0, upper = 1> Media_type[N]; // binary-dummy variable representing type of medium (marine: 0, freshwater: 1)
int<lower = 0, upper = 1> Polymer_PS[N]; // binary-dummy variable representing polymer type (PS or not)
int<lower = 0, upper = 1> Polymer_PE[N]; // binary-dummy variable representing polymer type (PE or not)
int<lower = 0, upper = 1> Shape_Fragment[N]; // binary-dummy variable representing shape (Fragment or not)
int<lower = 0, upper = 1> Shape_Fiber[N]; // binary-dummy variable representing shape (Fiber or not)
}
parameters {
real alpha;
real beta[6];
real<lower = 0> sigma;
}
transformed parameters {
real mu[N];
for (n in 1:N) {
mu[n] = alpha +
beta[1] * Log10_size[n] +
beta[2] * Media_type[n] +
beta[3] * Shape_Fragment[n] +
beta[4] * Shape_Fiber[n]+
beta[5] * Polymer_PS[n] +
beta[6] * Polymer_PE[n];
}
}
model {
for (n in 1:N) {
Log10_tox[n] ~ normal(mu[n], sigma);
}
for (j in 1:6) {
beta[j] ~ cauchy(0, 5);
}
alpha ~ cauchy(0, 10);
sigma ~ cauchy(0, 5);
}
generated quantities {
vector[N] log_lik;
for (n in 1:N) {
log_lik[n] = normal_lpdf(Log10_tox[n] | mu[n], sigma);
} }","\n", file = "ssd_full_model_waic.stan")
# You can see "ssd_full_model_waic.stan" file is now in your directory
stanmodel <- stan_model(file = 'ssd_full_model_waic.stan')
#Start sampling
fit1 <- sampling(
stanmodel,
data = list.data,
pars = c('alpha', 'beta', 'sigma', 'log_lik'),
chains = 3,
iter = 30000,
warmup = 10000,
thin = 10,
control = list(adapt_delta = 0.9),
seed = 1010
)
## See the results of fitting
print(fit1, par = c("alpha", "beta", "sigma"), probs = c(0.025, 0.5, 0.975))
# R-hat
mcmc_rhat(rhat(fit1))
# Trace plots
stan_trace(fit1, inc_warmup = T)
# Check individually...
mcmc_combo(fit1, pars = c("alpha")) # alpha
mcmc_combo(fit1, pars = c("beta[1]")) # beta1
mcmc_combo(fit1, pars = c("sigma"))
## WAIC
tmp <- extract_log_lik(fit1, parameter_name = "log_lik", merge_chains = TRUE)
WAIC <- waic(tmp)
WAIC$estimates[3,1] # 159.3971
# Visualize Median and 95% Bayesian credible intervals for parameters
samples <- as.array(fit1)
gg1 <- mcmc_intervals(samples, regex_pars = c("alpha", "beta", "sigma"), prob = 0.95, prob_outer = 0.95, point_est = "median",
point_size = 5, inner_size = 2) +
theme_bw(base_size = 25)
gg1