run deSolve multiple times varying a time-varying parameter - r

I would like to get this code to run repeatedly, creating a single output dataset with a different column variable for each run. Right now, the code works and allows me to insert different events at varying times. However, I would like to be able to change the magnitude of the event,
IPT <- ifelse (t<210, IPT, 0.35*exp(-(t-209)/21))
varying 0.35 to 0.4, 0.5, 0.6, etc. I have tried For loops but couldn't get it to work at all. My code is below:
library(deSolve)
##Simple parameter list
params <- c(b = 0.477, bs = .4, bsv = 0.1, nets = 0.4767, betah = 0.2,
rhos = 179, Bthetas = 0.2, psi = 14,phis = 0.5, gamma =14,
thetas = 0.79,piv = 1/19, betav = 0.09122, nu = 0.2085, sigma = 12,
muv = 1/19, IPT = 0, IPT2 = 0, IPT3 = 0)
dt <- seq(0, 5000, 7)
inits <- c(Ss = 30000, Is = 0, As = 0, Rs = 0,
Sv = 29999, Ev = 0, Iv = 1)
Nh <- 30000
Nv <- 30000
## Create an SIR function
sir1 <- function(t, x, params) {
with(as.list(c(params, x)), {
IPT <- ifelse (t<210, IPT, 0.35*exp(-(t-209)/21))
dSs <- -((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss /Nh + As*(1/rhos)*(1-Bthetas) + Rs*(1/psi)
dIs <- ((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss*(1-phis)/Nh - 1/gamma * Is - Is*(IPT + IPT2 + IPT3)
dAs <- ((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss*( phis)/Nh + 1/gamma * Is*(1-thetas) - As*(1/rhos)*(1-Bthetas) - As*(2/rhos)*Bthetas - As*(IPT + IPT2 + IPT3)
dRs <- 1/gamma * Is*( thetas) + As*(2/rhos)*Bthetas + Is*(IPT2 + IPT3+ IPT) + As*(IPT + IPT2 + IPT3) - Rs*(1/psi)
dSv <- piv*Nv - Sv*betav*b*(nu*(
((bsv*(1-nets))+(bsv*nets*0.78))*As)+
((bsv*(1-nets))+(bsv*nets*0.78))*Is/Nh) - Sv*muv
dEv <- Sv*betav*b*(nu*(
((bsv*(1-nets))+(bsv*nets*0.78))*As)+
((bsv*(1-nets))+(bsv*nets*0.78))*Is/Nh) - Ev*(1/sigma + muv)
dIv <- Ev*(1/sigma)- Iv*muv
der <- c(dSs, dIs, dAs, dRs,
dSv, dEv, dIv)
list(der)
})
}
out <- as.data.frame(lsoda(inits, dt, sir1, parms = params))
out$prev <- with(out, Is+As/Nh)
I would like the final data set to have multiple prev columns, one for each run with different values of the event.
Any help would be appreciated, thanks!

A potential solution would be to have the magnitude be a parameter instead of a constant (here I call it mag).
library(deSolve)
##Simple parameter list
params <- c(b = 0.477, bs = .4, bsv = 0.1, nets = 0.4767, betah = 0.2,
rhos = 179, Bthetas = 0.2, psi = 14,phis = 0.5, gamma =14,
thetas = 0.79,piv = 1/19, betav = 0.09122, nu = 0.2085, sigma = 12,
muv = 1/19, IPT = 0, IPT2 = 0, IPT3 = 0, mag=0.35)
dt <- seq(0, 5000, 7)
inits <- c(Ss = 30000, Is = 0, As = 0, Rs = 0,
Sv = 29999, Ev = 0, Iv = 1)
Nh <- 30000
Nv <- 30000
Then we can adjust the sir1 function to take the mag parameter...
## Create an SIR function
sir1 <- function(t, x, params) {
with(as.list(c(params, x)), {
IPT <- ifelse (t<210, IPT, mag*exp(-(t-209)/21))
dSs <- -((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss /Nh + As*(1/rhos)*(1-Bthetas) + Rs*(1/psi)
dIs <- ((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss*(1-phis)/Nh - 1/gamma * Is - Is*(IPT + IPT2 + IPT3)
dAs <- ((b*bs*(1-nets))+(b*bs*nets*0.78))*betah*Iv*Ss*( phis)/Nh + 1/gamma * Is*(1-thetas) - As*(1/rhos)*(1-Bthetas) - As*(2/rhos)*Bthetas - As*(IPT + IPT2 + IPT3)
dRs <- 1/gamma * Is*( thetas) + As*(2/rhos)*Bthetas + Is*(IPT2 + IPT3+ IPT) + As*(IPT + IPT2 + IPT3) - Rs*(1/psi)
dSv <- piv*Nv - Sv*betav*b*(nu*(
((bsv*(1-nets))+(bsv*nets*0.78))*As)+
((bsv*(1-nets))+(bsv*nets*0.78))*Is/Nh) - Sv*muv
dEv <- Sv*betav*b*(nu*(
((bsv*(1-nets))+(bsv*nets*0.78))*As)+
((bsv*(1-nets))+(bsv*nets*0.78))*Is/Nh) - Ev*(1/sigma + muv)
dIv <- Ev*(1/sigma)- Iv*muv
der <- c(dSs, dIs, dAs, dRs,
dSv, dEv, dIv)
list(der)
})
}
... and we can modify the params vector in a loop that also runs the model, gets the output, calculates prev, and stores it in the out data.frame.
out <- as.data.frame(lsoda(inits, dt, sir1, parms = params))
magz <- seq(0.2, 0.5, length.out=10)
for(i in 1:length(magz)){
params['mag'] <- magz[i]
tmp <- as.data.frame(lsoda(inits, dt, sir1, parms = params))
nm <- paste('prev', round(params['mag'],2), sep='')
out[,nm] <- with(tmp, Is+As/Nh)
}
There are likely better ways to do what you want to do, but this is a potential solution.

Related

I run the MCMC for SIR model code on my R software but there is no output until now

I tried to run code from https://cran.r-project.org/web/packages/MultiBD/vignettes/SIR-MCMC.pdf on my R software - they are still running but no output until now but I can run the following code on an online R compiler. This is the codes:
library(MultiBD)
data(Eyam)
Eyam
loglik_sir <- function(param, data) {
alpha <- exp(param[1]) # Rates must be non-negative
beta <- exp(param[2])
# Set-up SIR model
drates1 <- function(a, b) { 0 }
brates2 <- function(a, b) { 0 }
drates2 <- function(a, b) { alpha * b }
trans12 <- function(a, b) { beta * a * b }
sum(sapply(1:(nrow(data) - 1), # Sum across all time steps k
function(k) {
log(
dbd_prob( # Compute the transition probability matrix
t = data$time[k + 1] - data$time[k], # Time increment
a0 = data$S[k], b0 = data$I[k], # From: S(t_k), I(t_k)
drates1, brates2, drates2, trans12,
a = data$S[k + 1], B = data$S[k] + data$I[k] - data$S[k + 1],
computeMode = 4, nblocks = 80 # Compute using 4 threads
)[1, data$I[k + 1] + 1] # To: S(t_(k+1)), I(t_(k+1))
)
}))
}
logprior <- function(param) {
log_alpha <- param[1]
log_beta <- param[2]
dnorm(log_alpha, mean = 0, sd = 100, log = TRUE) +
dnorm(log_beta, mean = 0, sd = 100, log = TRUE)
}
library(MCMCpack)
alpha0 <- 3.39
beta0 <- 0.0212
post_sample <- MCMCmetrop1R(fun = function(param) { loglik_sir(param, Eyam) + logprior(param)
}, theta.init = log(c(alpha0, beta0)), mcmc = 500, burnin = 100)
plot(as.vector(post_sample[,1]), type = "l", xlab = "Iteration", ylab =
expression(log(alpha)))
plot(as.vector(post_sample[,2]), type = "l", xlab = "Iteration", ylab = expression(log(beta)))
library(ggplot2)
x = as.vector(post_sample[,1])
y = as.vector(post_sample[,2])
df <- data.frame(x, y)
ggplot(df,aes(x = x,y = y)) +
stat_density2d(aes(fill = ..level..), geom = "polygon", h = 0.26) +
scale_fill_gradient(low = "grey85", high = "grey35", guide = FALSE) +
xlab(expression(log(alpha))) +
ylab(expression(log(beta)))
quantile(exp(post_sample[,1]), probs = c(0.025,0.975))
quantile(exp(post_sample[,2]), probs = c(0.025,0.975))
I realize that this is the part of the codes that took long time to run but produce no output :
post_sample <- MCMCmetrop1R(fun = function(param) { loglik_sir(param, Eyam) + logprior(param)},
theta.init = log(c(alpha0, beta0)), mcmc = 500, burnin = 100)
I think my R software is the problem but what is it?

avoid negative values when resolving a ODE

I am trying to model the behavior of a made-up networks of 5 genes, but I have the problem that I get negative values, which it has not sense biologically speaking.
Is there a way to limit the values to zero?
I managed to do it when I represent the graph, but I don't know how to use the ifelse in the main equation.
Thank you very much-1
###################################################
###preliminaries
###################################################
library(deSolve)
library(ggplot2)
library(reshape2)
###################################################
### Initial values
###################################################
values <- c(A = 1,
B = 1,
D = 1,
E = 20,
R = 1)
###################################################
### Set of constants
###################################################
constants <- c(a = 1.2,
b = 0.5,
c = 1.2,
d = 1.5,
e = 0.3,
f = 0.5,
g = 1.5,
h = 0.9,
i = 1.3,
j = 1.3,
m = 0.8,
n = 0.6,
q = 1,
t = 0.0075,
u = 0.0009,
Pa = 100,
Pb = 0.05,
Pd = 0.1,
Pe = 10)
###################################################
### differential equations
###################################################
Dynamic_Model<-function(t, values, constants) {
with(as.list(c(values, constants)),{
dA <- Pa + a*D - j*A - R
dB <- Pb + b*A + e*E - m*B
dD <- Pd + d*B + f*E - g*A - n*D
dE <- Pe - h*B + i*E - q*E
dR <- t*A*B - u*D*E
list(c(dA, dB, dD, dE, dR))
})
}
###################################################
### time
###################################################
times <- seq(0, 200, by = 0.01)
###################################################
### print ## Ploting
###################################################
out <- ode(y = values, times = times, func = Dynamic_Model, parms = constants)
out2 <- ifelse(out<0, 0, out)
out.df = as.data.frame(out2)
out.m = melt(out.df, id.vars='time')
p <- ggplot(out.m, aes(time, value, color = variable)) + geom_point(size=0.5) + ggtitle("Dynamic Model")
I agree completely with #Lutz Lehmann, that the negative values are a result of the structure of the model.
The system of equations allows that derivatives still become negative, even if the states are already below zero, i.e. the states can further decrease. We don't have information about what the states are, so the following is only a technical demonstration. Here a dimensionless Monod-type feedback function fb is implemented as a safeguard. It is normally close to one. The km value should be small enough to act only for state values close to zero, and it should not be too small to avoid numerical errors. It can be formulated individually for each state. Other function types are also possible.
library(deSolve)
library(ggplot2)
library(reshape2)
values <- c(A = 1,
B = 1,
D = 1,
E = 20,
R = 1)
constants <- c(a = 1.2,
b = 0.5,
c = 1.2,
d = 1.5,
e = 0.3,
f = 0.5,
g = 1.5,
h = 0.9,
i = 1.3,
j = 1.3,
m = 0.8,
n = 0.6,
q = 1,
t = 0.0075,
u = 0.0009,
Pa = 100,
Pb = 0.05,
Pd = 0.1,
Pe = 10,
km = 0.001)
Dynamic_Model<-function(t, values, constants) {
with(as.list(c(values, constants)),{
fb <- function(x) x / (x+km) # feedback
dA <- (Pa + a*D - j*A - R) * fb(A)
dB <- (Pb + b*A + e*E - m*B) * fb(B)
dD <- (Pd + d*B + f*E - g*A - n*D) * fb(D)
dE <- (Pe - h*B + i*E - q*E) * fb(E)
dR <- (t*A*B - u*D*E) * fb(R)
list(c(dA, dB, dD, dE, dR))
})
}
times <- seq(0, 200, by = 0.1)
out <- ode(y = values, times = times, func = Dynamic_Model, parms = constants)
plot(out)
Additional hints:
Removal of negative values afterwards (out2 <- ifelse(out<0, 0, out)) is just wrong.
Removal of negative values in the model function, i.e.
use the ifelse in the main
would also be wrong as it can lead to a severe violation of mass balance.
the time steps don't need to be very small. They are automatically adapted anyway by the solver. Too small time steps make your model slow and you get more outputs as needed.
some of your parameters are quite large, so that the model becomes very stiff.

R code for simulating stochastic asset price path

Consider the following model for the evolution of an asset's price:
This what I have done (in R). I could not find a function that randomly outputs +1 or -1, so I decided to adapt the inbuilt rbinom function.
## This code is in R
rm(list = ls())
library(dplyr)
library(dint)
library(magrittr)
library(stats)
path =
function(T, mu, sigma, p, x0) {
x = rep(NA, T)
x[1] = x0
for(i in 2:T){
z = if_else(rbinom(1,1,p) == 0, -1, 1)
x[i] = x[i-1] * exp(mu + sigma*z)
}
return(x)
}
## Just some testing
x_sim = path(T = 4, mu = 0, sigma = 0.01, p = 0.5, x0 = 100)
## Actual answer
Np = 10000
mc = matrix(nrow = 17, ncol = Np)
for(j in 1:Np){
mc[,j] = path(T = 17, mu = 0, sigma = 0.01, p = 0.5, x0 = 100)
}
test = mc[2:nrow(mc), ] >= 100
sum_test = colSums(test)
comp = sum(sum_test >= 1)/length(sum_test)
prob = 1 - comp
Does this make sense? Any help/tips/advice would be much appreciated. Thanks!
Staying close to your code, I came up with this. Intuitively, if you think about it, the probability should be rather low due to the parameters and I get a probability of about 6.7% which is roughly what I get if I run your code with the parameters from the assignment.
simpath <- function(t, mu, sigma, p, x0, seed){
# set seed
if(!missing(seed)){
set.seed(seed)
}
# set up matrix for storing the results
res <- matrix(c(1:t, rep(NA, t*2)), ncol = 3)
colnames(res) <- c('t', 'z_t', 'x_t')
res[, 'z_t'] <- sample(c(1, -1), size = t, prob = c(p, 1-p), replace = TRUE)
res[1, 3] <- x0
for(i in 2:t){
res[i, 3] <- res[i-1, 3] * exp(mu+sigma*res[i, 2])
}
return(res)
}
x_sim <- simpath(t = 4, mu = 0, sigma = 0.01, p = 0.5, x0 = 100, seed = 123)
x_sim2 <- simpath(t = 36, mu = 0, sigma = 0.03, p = 0.5, x0 = 100, seed = 123)
## Actual answer
Np <- 100000
mc <- matrix(nrow = 36, ncol = Np)
for (j in 1:Np){
mc[, j] <- simpath(t = 36, mu = 0, sigma = 0.03, p = 0.5, x0 = 100)[, 3]
}
test <- mc > 100
sum_test <- colSums(test)
comp = sum(sum_test == 0)/length(sum_test)
prob = comp
> prob
[1] 0.06759

Extracting Results from odeModel?

I was unsuccessful in trying to get a df object as my output (so that I would be able to subset/ customize each graph). I also read that it is possible to extract the results using the function "out", but I haven't gotten it to work. Could someone please help me with this?
'''
library(simecol)
library(latticeExtra)
Figure_7B <- odeModel(
main = function(time, init, parms) {
with(as.list(c(init, parms)),{
# Computing derivatives
dm <- -k1*eT*m
dmP <- k1*eT*m
dE <- -k2*E*mP
dEP <- k2*mP*E + (k3*EP)*(dE - TE - S) + k3r*TE
dDE <- +k3*EP*DE - k3r*TE
dTE <- (k3*EP)*(DE - TE - S) - k3r*TE - k7*TE*A
dME <- k4*TE - d1*ME
dDA <- +k5*EP*DA - k5r*TA
dTA <- k5*EP*DA - k5r*TA
dMA <- (k6*EP)/(EP + k5) - d2*MA
dA <- k8*MA + k7*TE*A + d3*A
dS <- k7*TE*A
return(list(c(dm, dmP, dE, dEP, dDE, dTE, dME, dDA, dTA, dMA, dA, dS)))
})
},
# Set parameters or constants
parms = c(k1 = 8.3e-3,
eT = 100,
k2 = 1.28e5,
k3 = 1e5,
k3r = 5e-2,
k4 = 6.89e-15,
k5 = 0.5e-6,
k5r = 5e-2,
k6 = 1.03e-15,
k7 = 1e5,
k8 = 0.25,
d1 = 8.89e-4,
d2 = 2.36e-4,
d3 = 2.36e-4),
# Set integrations times
times = c(from=0, to=10, by = 0.25),
# Set initial state
init = c(
m = 130e-7,
mP = 0,
E = 130e-7,
EP = 0,
DE = 3.32e-11,
TE = 0,
ME = 1e-12,
DA = 3.32e-11,
TA = 0,
MA = 0,
A = 0,
S = 0),
solver = "lsoda"
)
'''
'''
library(deSolve)
Figure_7B <- sim(Figure_7B)
plot(Figure_7B)
'''
Try the following:
Figure_7B <- sim(Figure_7B)
plot(Figure_7B)
df <- out(Figure_7B)
head(df)
Explanation: The object returned by sim() contains all the inputs (the complete Figure_7B model) plus the output. Parts of the model can be extracted with slot accessor functions, e.g.:
times(Figure_7B)
main(Figure_7B)
out(Figure_7B)
Hope it helps.

GLM code/logistic regression is taking too long to run

I am trying to run the following code. My computer keeps getting frozen when I try to run it. Therefore, I can see the correlation matrices, I am unable to view the results of the GLM/data arrays.
# running the assay
#which_p_value = "x1"
which_p_value = "groupcategory"
#which_p_value = "x1:groupcategory"
run_anova = FALSE
simulate_mixed_effect = TRUE
mixed_effect_sd = 3.094069
mixed_effect_sd_slope = 3.098661
library(tidyverse)
n_people <- c(2,5,10,15,20)
coef1 <- 1.61
coef2 <- -0.01
#coef3 <- 5
#coef4 <- 0
g1 = 0
g2 = 1
g3 = 2
distances <- c(60,90,135,202.5,303.75,455.625)/100
n_trials <- 35
oneto1000 <- 25
n_track_lengths <- length(distances)
groupcategory = c(rep(g1, n_track_lengths), rep(g2, n_track_lengths),rep(g3,n_track_lengths))
z = c(n_people)
emptydataframeforpowerplots = NULL
coef3s <- c(-5, -4, -3, -2,-1, 0, 1, 2, 3, 4, 5)
coef4s <- c(-1, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1)
Datarray <- array(dim=c(length(coef3s), length(coef4s),length(n_people)))
coef3_counter =1
for (coef3 in coef3s) {
coef4_counter =1
for (coef4 in coef4s) {
z1_g2 <- coef1 + coef2*distances + coef3*g2 + coef4*g2*distances
z1_g3 <- coef1 + coef2*distances + coef3*g3 + coef4*g3*distances
d = NULL
pr1 = 1/(1+exp(-z1_g2))
pr2 = 1/(1+exp(-z1_g3))
counter=1
for (i in n_people) {
for (j in 1:oneto1000){
df <- c()
for (k in 1:i){
# random effect from drawing a random intercept with sd = x
if (simulate_mixed_effect){
coef1_r = rnorm(1, mean=coef1, sd=mixed_effect_sd)
coef2_r = rnorm(1, mean=coef1, sd=mixed_effect_sd_slope)
} else {
coef1_r = coef1
coef2_r = coef2
}
z_g1 <- coef1_r + coef2*distances + coef3*g1 + coef4*g1*distances
pr = 1/(1+exp(-z_g1))
z1_g2 <- coef1_r + coef2*distances + coef3*g2 + coef4*g2*distances
pr1 = 1/(1+exp(-z1_g2))
if (run_anova) {
df <- rbind(df, data.frame(x1 = c(rep(distances, 3)),
y = c(rbinom(n_track_lengths,n_trials,pr), rbinom(n_track_lengths,n_trials,pr1),rbinom(n_track_lengths,n_trials,pr2)),
groupcategory = groupcategory, id = c(rep(k,18))))
} else { # this is for glmer data organisation
for (m in 1:n_trials) {
df <- rbind(df, data.frame(x1 = c(rep(distances, 3)),
y = c(rbinom(n_track_lengths,1,pr),rbinom(n_track_lengths,1,pr1),rbinom(n_track_lengths,1,pr2)),groupcategory = groupcategory,id = c(rep(k,18))))
}
}
}
if (run_anova) {
#df_aov <- aov(y~x1*groupcategory+Error(id/(x1*groupcategory)),data=df)
#df_aov_sum <- summary(df_aov)
#pvalue <- df_aov_sum[[5]][[1]][which_p_value,"Pr(>F)"]
df_aov <- aov(y~x1*groupcategory+Error(id),data=df)
df_aov_sum <- summary(df_aov)
pvalue <- df_aov_sum[[2]][[1]][which_p_value, "Pr(>F)"]
}
checkme <- df %>% group_by(groupcategory,id) %>% summarise(miny=min(y),maxy=max(y)) %>% mutate(expectfail = miny==maxy)
else {
mod_group_glmer <- glmer(y ~ x1 + groupcategory + (1+x1|id), data = df, family = "binomial")
sum <- summary(mod_group_glmer)
pvalue <- sum$coefficients[which_p_value, "Pr(>|z|)"]
}
d = rbind(d,data.frame(pvalue))
}
count <- plyr::ldply(d,function(c) sum(c<=0.05))
Datarray[coef3_counter,coef4_counter,counter] <- count$V1/oneto1000
counter = counter +1
d = NULL
}
coef4_counter = coef4_counter + 1
}
coef3_counter = coef3_counter + 1
}
Does anybody have any advice on how I can overcome this issue? I have tried different things such as lowering the range of sample sizes (n_people) but I have still been unsuccessful. My computer starts making a whirring noise and eventually I am forced to have to 'force quit' the program?

Resources