I have the data below:
Kd1Par<-as.matrix(c(1,2,3))
Kd2Par<-as.matrix(c(1,2,3))
and the algorithm which uses nested for loops:
for (i in 1:length(Kd1Par)){
for (j in 1:length(Kd2Par)){
Kd1 <- Kd1Par[i]
Kd2 <- Kd2Par[j]
print(c(Kd1 = Kd1Par[i], Kd2 = Kd2Par[j]))
myDose[i, j] <- 10
print(c(Dose = myDose[i,j]))
}}
in order to give me this output :
Kd1 Kd2
1 1
Dose
10
Kd1 Kd2
1 2
Dose
10
Kd1 Kd2
1 3
Dose
10
Kd1 Kd2
2 1
Dose
10
Kd1 Kd2
2 2
Dose
10
Kd1 Kd2
2 3
Dose
10
Kd1 Kd2
3 1
Dose
10
Kd1 Kd2
3 2
Dose
10
Kd1 Kd2
3 3
Dose
10
The problem is that my real dataset is too big and the for loops is an efficient method but very slow so I would like to replace it with a method that gives me exactly the same result as above. Note that myDose[i, j] <- 10 is not always 10 in my real project but comes from another calculation that gives every time another result but here I set is as 10 in order to simplify the problem.
# my app in case it makes more sense to understand the issue
library(deSolve)
library(caTools)
library(shiny)
library(ggplot2)
library(ggpubr)
library(minpack.lm)
library(reshape2)
library(pracma)
ui <- fluidPage(
# fluidRow(title='Schematic of Two Memb Bound Target ',
# img(src='twoMemBound.png',width='100%')),
plotOutput('PKPlot'),
actionButton(inputId = "click",
label = "Run"),
fluidRow(
column(4,
h6("Dosing regimen Parameters",style = "color:red",align="center"),
sliderInput("nIter", label = h6("Contour Smoothness"),
min = 2, max = 15, value = 3),
sliderInput("reqMinInh", label = h6("Minimum Inhibition"),
min = 10, max = 100, value = 90),
sliderInput("nd", label = h6("Number of Doses"),
min = 3, max = 100, value = 4),
# sliderInput("endTime", label = h6("Simulation time in Days"),
# min = 0, max = 500, value = 77),
sliderInput("tau", label = h6("Dosing interval in Days"),
min = 0.1, max = 50, value = 7),
sliderInput("BW", label = h6("Bodyweight in Kg"),
min = 60, max = 100, value = 70)
),
column(4,
h6("Drug Parameters",style = "color:red",align="center"),
sliderInput("CL", label = h6("Drug Clearance (L/day)"),
min = 0.1, max = 0.3, value = 0.24),
sliderInput("Vp", label = h6("Volume of Plasma Comp (L)"),
min = 0.1, max = 3, value = 3),
sliderInput("Kon1", label = h6("Drug Affinity for Target 1 (1/(nmol/L)/day)"),
min = 0.1, max = 2, value = 1.3824),
sliderInput("Kon2", label = h6("Drug Affinity for Target 2 (1/(nmol/L)/day)"),
min = 0.1, max = 2, value = 1.3824),
sliderInput("MW", label = h6("Molecular Weight in da"),
min = 50e3, max = 200e3, value = 150e3)
# sliderInput("Vph", label = h6("Volume of Peripheral Comp (L)"),
# min = 0.1, max = 5, value = 3.1),
# sliderInput("Vt", label = h6("Volume of Tissue Comp (L)"),
# min = 0.1, max = 0.2, value = 0.192),
# sliderInput("k_01", label = h6("First Order Absorption Rate (1/day)"),
# min = 0.1, max = 2, value = 1),
),
column(4,
h6("Target Parameters",style = "color:red",align="center"),
sliderInput("R01", label = h6("Baseline Conc of Target 1 (nmol/L)"),
min = 0.01, max = 10, value = 0.1),
sliderInput("R02", label = h6("Baseline Conc of Target 2 (nmol/L)"),
min = 0.01, max = 10, value = 0.1),
sliderInput("HL1", label = h6("Half-life of Target 1 (min)"),
min = 0.01, max = 100, value = 100),
sliderInput("HL2", label = h6("Half-life of Target 2 (min)"),
min = 0.01, max = 100, value = 100)
)
)
)
server <- function(input, output) {
v <- reactiveValues(doPlot = FALSE)
observeEvent(input$click, {
v$doPlot <- input$click
})
output$PKPlot <- renderPlot({
if (v$doPlot == FALSE) return()
isolate({
reqMinInh <- input$reqMinInh # (%) Min inhibition of Target
nd <- input$nd # Number of doses
tau <- input$tau
endTime <- (nd+1)*tau
BW <- input$BW
MW <- input$MW
nIter <- input$nIter
Kd1Par <- logspace(-1.98,1.698,n = nIter)
Kd2Par <- logspace(-1.98,1.698,n = nIter)
myDose <- matrix(c(0), nrow= length(Kd1Par), ncol = length(Kd2Par))
Kon_m1 <- input$Kon1 # (1/(nmol/L)/day)
Kon_m2 <- input$Kon2 # (1/(nmol/L)/day)
Base1 <- input$R01
Base2 <- input$R02
HL1 <- input$HL1
HL2 <- input$HL2
Kint_m1 <- 0.693*60*24/HL1 # (1/day)
Kint_m2 <- 0.693*60*24/HL2 # (1/day)
Kdeg_m1 <- Kint_m1 # (1/day)
Kdeg_m2 <- Kint_m2 # (1/day)
Ksyn_m1 <- Base1*Kdeg_m1 # (nmol/L/day)
Ksyn_m2 <- Base2*Kdeg_m2 # (nmol/L/day)
Vp <- input$Vp # (L) Ref: Vaishali et al. 2015
Vph <- 3.1 # (L) Ref: Tiwari et al. 2016
Vt <- 0.192 # (L) Spleen, Ref: Davis et al. 1993
k_01 <- 1 # (1/day) Ref: Leonid Gibiansky
CL <- input$CL # (L/day) Ref: Leonid Gibiansky
K_el <- CL/Vp # (1/day)
k_pph <- 0.186 # (1/day) Ref: Tiwari et al. 2016
k_php <- 0.184 # (1/day) Ref: Tiwari et al. 2016
Ktp <- 0.26 # (1/day)
Kpt <- 0.004992 # (1/day)
times <- seq(from = 0, to = endTime, by =0.1)
yInit <- c(Ap = 0.0, Dp = 0.0, Dt = 0.0,
M1 = Base1, M2 = Base2,
DtM1 = 0.0, DtM2 = 0.0, DtM1M2 = 0.0, Dph = 0.0)
derivs_pk1 <- function(t, y, parms) {
with(as.list(c(y,parms)),{
dAp_dt <- -k_01*Ap
dDp_dt <- k_01*Ap/Vp -K_el*Dp +Vt/Vp*Ktp*Dt -Kpt*Dp +Vph/Vp*k_php*Dph -k_pph*Dp
dDt_dt <- Vp/Vt*Kpt*Dp -Ktp*Dt -Kon_m1*Dt*M1 +Koff_m1*DtM1 -Kon_m2*Dt*M2 +Koff_m2*DtM2
dM1_dt <- Ksyn_m1 -Kdeg_m1*M1 -Kon_m1*Dt*M1 +Koff_m1*DtM1 -Kon_m1*DtM2*M1 +Koff_m1*DtM1M2
dM2_dt <- Ksyn_m2 -Kdeg_m2*M2 -Kon_m2*Dt*M2 +Koff_m2*DtM2 -Kon_m2*DtM1*M2 +Koff_m2*DtM1M2
dDtM1_dt <- -Kint_m1*DtM1 -Koff_m1*DtM1 +Kon_m1*Dt*M1 -Kon_m2*DtM1*M2 +Koff_m2*DtM1M2
dDtM2_dt <- -Kint_m2*DtM2 -Koff_m2*DtM2 +Kon_m2*Dt*M2 -Kon_m1*DtM2*M1 +Koff_m1*DtM1M2
dDtM1M2_dt <- Kon_m2*DtM1*M2 -Koff_m2*DtM1M2 +Kon_m1*DtM2*M1 -Koff_m1*DtM1M2 -Kint_m1*DtM1M2 -Kint_m2*DtM1M2
dDph_dt <- Vp/Vph*k_pph*Dp - k_php*Dph
list(c(dAp_dt,dDp_dt,dDt_dt,dM1_dt,dM2_dt,dDtM1_dt,dDtM2_dt,dDtM1M2_dt,dDph_dt))
})
}
ssq <- function(parmsToOptm){
Dose <- parmsToOptm[1]
injectEvents <- data.frame(var = "Ap",
time = seq(0,tau*(nd-1),tau),
value = Dose*1e6*BW/MW, # (nmol)
method = "add")
pars_pk1 <- c()
qss_pk10<-ode(times = times, y = yInit, func =derivs_pk1, parms = pars_pk1,events = list(data = injectEvents))
qss_pk1<- data.frame(qss_pk10)
temp <- qss_pk1[qss_pk1$time>tau*(nd-2)&qss_pk1$time<tau*(nd-1),]
inh1 <- (1-temp$M1/Base1)*100
inh2 <- (1-temp$M2/Base2)*100
if(min(inh1,inh2) %in% inh1) {
currMinInh <- inh1
} else {currMinInh <-inh2}
ssqres = currMinInh - reqMinInh
return(ssqres)
}
for (i in 1:length(Kd1Par)){
for (j in 1:length(Kd2Par)){
Kd1 <- Kd1Par[i]
Kd2 <- Kd2Par[j]
print(c(Kd1 = Kd1Par[i], Kd2 = Kd2Par[j]))
Koff_m1 <- Kon_m1*Kd1 # (1/day)
Koff_m2 = Kon_m2*Kd2 # (1/day)
# Initial guess
parmsToOptm <- c(10)
fitval<-nls.lm(par=parmsToOptm,fn=ssq,control = nls.lm.control(ftol = sqrt(.Machine$double.eps),
ptol = sqrt(.Machine$double.eps), gtol = 0, diag = list(), epsfcn = parmsToOptm[1]/100,
factor = 100, maxfev = integer(), maxiter = 50, nprint = 0))
myDose[i, j] <- c(coef(fitval))
print(c(Dose = myDose[i,j]))
}
}
KdMat <- expand.grid(Kd1Par,Kd2Par)
temp1 <- melt(myDose)
myDoseFormat <- data.frame(Kd1=KdMat$Var1, Kd2 = KdMat$Var2, Dose = temp1$value)
minDose <- myDoseFormat[myDoseFormat$Dose == min(myDoseFormat$Dose),]
Kd1 <- minDose$Kd1
Kd2 <- minDose$Kd2
Koff_m1 <- Kon_m1*Kd1 # (1/day)
Koff_m2 = Kon_m2*Kd2 # (1/day)
Dose <- minDose$Dose
injectEvents <- data.frame(var = "Ap",
time = seq(0,tau*(nd-1),tau),
value = Dose*1e6*BW/MW, # (nmol)
method = "add")
pars_pk1 <- c()
qss_pk10<-ode(times = times, y = yInit, func =derivs_pk1, parms = pars_pk1,events = list(data = injectEvents))
qss_pk1<- data.frame(qss_pk10)
mytheme_grey <- theme_grey(base_size=18)+theme(plot.caption=element_text(size=8, colour="grey60"))
p1 <- ggplot(myDoseFormat, aes(x = Kd1, y = Kd2, z = Dose)) +
geom_raster(aes(fill = Dose), interpolate=T) +
scale_x_log10() + scale_y_log10() +
labs(title = "Contours of dose (mg/kg)", x="Target-1 Kd (nM)",y="Target-2 Kd (nM)") +
guides(fill = guide_colorbar(title = "Dose (mg/kg)")) +
theme(legend.position=c(0.9, 0.75))
p2 <- ggplot(qss_pk1,aes(x=time/7)) +
geom_line(aes(y=Dp)) +
labs(x="Time (weeks)",y="Drug Conc (nmol/L)") +
mytheme_grey
cols <- c("Target 1" ="red", "Target 2" = "blue")
p3 <- ggplot(qss_pk1,aes(x=time/7)) +
geom_line(aes(y=M1, colour = "Target 1"), size = 1.5, linetype = 1) +
geom_line(aes(y=M2, colour = "Target 2"), size = 1.5, linetype = 2) +
labs(x="Time (weeks)",y="Target Conc (nmol/L)") +
scale_colour_manual(name = "Targets", values = cols)+
mytheme_grey
p4 <- ggplot(qss_pk1,aes(x=time/7)) +
geom_line(aes(y= (1-M1/Base1)*100, colour = "Target 1"), size = 1.5, linetype = 1) +
geom_line(aes(y= (1-M2/Base2)*100, colour = "Target 2"), size = 1.5, linetype = 2) +
labs(x="Time (weeks)",y="Target Occupancy (%)") +
scale_colour_manual(name = "Targets", values = cols)+
mytheme_grey
ggarrange(p1,p2,p3,p4,labels=c("A","B","C","D"), ncol=4,nrow=1)
})
})
}
shinyApp(ui = ui, server = server)
Do you need a loop?
# Create a data frame of all combinations
df <- expand.grid(Kd1Par = c(1,2,3), Kd2Par = c(1,2,3))
# Load libraries
library(dplyr)
library(purrr)
# If function is vectorised
df %>%
mutate(Dose = MyFunction(Kd1Par, Kd2Par))
# If function is not vectorised
df %>%
mutate(Dose = map2_dbl(Kd1Par, Kd2Par, MyFunction))
Here, I create all possible combinations of Kd1Par and Kd2Par and then run the dose function, which I called MyFunction.
For example,
# Example dose function
MyFunction <- function(x, y)x + y
would give something like
# Kd1Par Kd2Par Dose
# 1 1 1 2
# 2 2 1 3
# 3 3 1 4
# 4 1 2 3
# 5 2 2 4
# 6 3 2 5
# 7 1 3 4
# 8 2 3 5
# 9 3 3 6
Related
The composition of my data has 4 parts, all_data <- rbind(data1,data2,data3,data4)
In shiny,I want to when I slider sliderinput 1,only data1 changed in this dataframe.
When I change slider 2,only data2 changed in this dataframe.
But when I changed every slider,all data will change ,maybe I should use observeEvent like this,but I am faild.
observeEvent(ignoreInit = TRUE,
c(input$Mean1,input$SD1), {
mean1 <- input$Mea1
sd1 <- input$SD1
n_sample <- 5
x1 <- 1:5
y1 <- rnorm(n_sample,mean1, sd1)
z1 <- rep("Distribution 1",length(x1) )
mean_1 <- rep(mean(y1),length(x1))
data1 <-data.frame(x = x1,y = y1,z = z1,my_mean =mean_1)
})
There is all my code, could you please tell me how to modify it. Thanks!
rm(list = ls())
library(shiny)
library(shinythemes)
library(ggplot2)
library(plotly)
ui_chart <- sidebarPanel(width =3,position = "right",
sliderInput("Mean1", "Mean of the distrubution1", -30, 30, value = -10),
sliderInput("Mean2", "Mean of the distrubution2", -30, 30, value = 0),
sliderInput("Mean3", "Mean of the distrubution3", -30, 30, value = 10),
sliderInput("Mean4", "Mean of the distrubution4", -30, 30, value = 20),
sliderInput("SD1", "Within group sd", 0.1, 20, value =6)
)
ui <- navbarPage("Distrubution for each group", theme = shinytheme("flatly"),
tabPanel("Distrubution simulation",
titlePanel("Within group and between group variance"),
mainPanel(width = 9
,plotlyOutput("chart2")
)
,ui_chart
)
)
server <- function(input, output) {
output$chart2 <- renderPlotly({
mean1 <- input$Mean1
mean2 <- input$Mean2
mean3 <- input$Mean3
mean4 <- input$Mean4
sd1 <- input$SD1
n_sample <- 5
x1 <- 1:5
y1 <- rnorm(n_sample,mean1, sd1)
z1 <- rep("Distribution 1",length(x1) )
mean_1 <- rep(mean(y1),length(x1))
data1 <-data.frame(x = x1,y = y1,z = z1,my_mean =mean_1 )
x2 <- 6:10
y2 <- rnorm(n_sample,mean2, sd1)
z2 <- rep("Distribution 2",length(x2) )
mean_2 <- rep(mean(y2),length(x2))
data2 <-data.frame(x = x2,y = y2,z = z2,my_mean =mean_2)
x3 <- 11:15
y3 <- rnorm(n_sample,mean3, sd1)
z3 <- rep("Distribution 3",length(x3) )
mean_3 <- rep(mean(y3),length(x3))
data3 <-data.frame(x = x3,y = y3,z = z3,my_mean =mean_3)
x4 <- 16:20
y4 <- rnorm(n_sample,mean4, sd1)
z4 <- rep("Distribution 4",length(x4) )
mean_4 <- rep(mean(y4),length(x4))
data4 <-data.frame(x = x4,y = y4,z = z4,my_mean =mean_4)
all_data <- rbind(data1,data2,data3,data4)
all_data$mean_all <- mean(all_data$y)
p2 <- ggplot(data = all_data)+
geom_point(aes(x = x ,y = y,color = z))+
geom_line(aes(x = x ,y = my_mean ,color = z))+
geom_line(aes(x = x ,y = mean_all ),color = "black")+
scale_x_continuous(breaks = c(1:20),
labels = paste0("Obs",1:20))+
ggtitle("Observed sampale data")+
theme_bw()+
labs(color = "Distribution")+
theme(plot.title = element_text(hjust = 0.5))
ggplotly(p2)
})
}
shinyApp(ui, server)
Well since you are using rnorm, you are getting new random values every-time an input changes. If you want to isolate those changes, you might want to make separate reactive data objects for each of the studies. Here's one way to do that
server <- function(input, output) {
generate_data <- function(dist, ids, n_sample, sample_mean, sample_sd) {
x <- 1:5
y <- rnorm(n_sample,sample_mean, sample_sd)
z <- rep(paste("Distribution", dist),length(x) )
mean <- rep(mean(y),length(x))
data.frame(x = ids, y = y, z = z, my_mean =mean)
}
n_sample <- 5
data1 <- reactive(generate_data("1", 1:5, n_sample, input$Mean1, input$SD1))
data2 <- reactive(generate_data("2", 6:10, n_sample, input$Mean2, input$SD1))
data3 <- reactive(generate_data("3", 11:15, n_sample, input$Mean3, input$SD1))
data4 <- reactive(generate_data("4", 16:20, n_sample, input$Mean4, input$SD1))
output$chart2 <- renderPlotly({
all_data <- rbind(data1(),data2(),data3(),data4())
all_data$mean_all <- mean(all_data$y)
p2 <- ggplot(data = all_data)+
geom_point(aes(x = x ,y = y,color = z))+
geom_line(aes(x = x ,y = my_mean ,color = z))+
geom_line(aes(x = x ,y = mean_all ),color = "black")+
scale_x_continuous(breaks = c(1:20),
labels = paste0("Obs",1:20))+
ggtitle("Observed sampale data")+
theme_bw()+
labs(color = "Distribution")+
theme(plot.title = element_text(hjust = 0.5))
ggplotly(p2)
})
}
Here we make a helper function to generate the data for each of the groups. We store the data in a reactive object that only depends on the group mean. Therefore they won't change when other inputs change
I am trying to estimate a Mixed-mixed multinomial logit model using the gmnl package. It works perfectly when not including Alternative Specific Constants (ASC), but it produces a weird error when incorporating them. The code below was taken (and adapted) from the original article published of the package.
Data preparation
options(digits = 3)
library("gmnl")
library("mlogit")
data("Electricity", package = "mlogit")
Electr <- mlogit.data(Electricity,
id.var = "id",
choice = "choice",
varying = 3:26,
shape = "wide",
sep = "")
####Alternative Specific Constants
Electr$asc2 <- as.numeric(Electr$alt == 2)
Electr$asc3 <- as.numeric(Electr$alt == 3)
Electr$asc4 <- as.numeric(Electr$alt == 4)
Latent Class Models (with ASC)
The code below works perfectly, even including the ASC in the second part of the formula (LC_ASC_in_formula) or explicitly with the regressors (LC_ASC_in_variables).
LC_ASC_in_formula <- gmnl(choice ~ pf + cl + loc + wk + tod + seas | 1 | 0 | 0 | 1,
data = Electr,
subset = 1:3000,
model = "lc",
panel = TRUE,
Q = 2)
summary(LC_ASC_in_formula)
LC_ASC_in_variables <- gmnl( choice ~ pf + cl + loc + wk + tod + seas +asc2 +asc3 +asc4 | 0 | 0 | 0 | 1,
data = Electr,
subset = 1:3000,
model = "lc",
panel = TRUE,
Q = 2)
summary(LC_ASC_in_variables)
## Are they the same?
logLik(LC_ASC_in_variables) == logLik(LC_ASC_in_formula)
## [1] TRUE
Mixed-mixed MNL model
This model is basically a Latent Class model, but inside each class, the parameters are random (follow a previously specified parametric distribution).
Mixed-mixed MNL model WITHOUT ASC
The model works just fine when the ASCs are omitted.
MM_no_ASC <- gmnl(choice ~ pf + cl + loc + wk + tod + seas | 0 | 0 | 0 | 1,
data = Electr,
subset = 1:3000,
model = "mm",
R = 5,
panel = TRUE,
ranp = c(pf = "n",cl = "n",loc = "n",wk = "n", tod = "n",seas= "n"),
Q = 2,
iterlim = 500)
However, it fails to estimate the model when including the ASC:
As part of the variables in the model.
MM_ASC_in_variables <- gmnl( choice ~ pf + cl + loc + wk + tod + seas +
asc2 +asc3 +asc4 | 0 | 0 | 0 | 1 ,
data = Electr,
subset = 1:3000,
model = "mm",
R = 5,
panel = TRUE,
ranp = c(pf = "n",cl = "n",loc = "n",wk = "n", tod = "n",seas= "n"),
Q = 2,
iterlim = 500)
> Error in if (distr == "n") { : missing value where TRUE/FALSE needed
and when including them in the third part of the formula.
MM_ASC_in_formula <- gmnl( choice ~ pf + cl + loc + wk + tod + seas | 1 | 0 | 0 | 1 ,
data = Electr,
subset = 1:3000,
model = "mm",
R = 5,
panel = TRUE,
ranp = c(pf = "n",cl = "n",loc = "n",wk = "n", tod = "n",seas= "n"),
Q = 2,
iterlim = 500)
> Error in if (distr == "n") { : missing value where TRUE/FALSE needed
Howeve, both ways to include the ASC parameters fail to initialize the model estimation. Hopefully, someone could help me to solve this issue. Thank you in advance.
Bonus1: Traceback of the error.
I reduced the number of observations included in the estimation (subset = 1:20) to see better the traceback() of the error shown below. But I couldn't spot the error myself.
MM_ASC_in_formula <- gmnl( choice ~ pf + cl + loc + wk + tod + seas | 1 | 0 | 0 | 1 ,
data = Electr,
subset = 1:20,
model = "mm",
R = 5,
panel = TRUE,
ranp = c(pf = "n",cl = "n",loc = "n",wk = "n", tod = "n",seas= "n"),
Q = 2,
iterlim = 500)
# Error in if (distr == "n") { : missing value where TRUE/FALSE needed
traceback()
# Estimating MM-MNL model
# Error in if (distr == "n") { : missing value where TRUE/FALSE needed
# > traceback()
# 14: Makeh.rcoef(beta[, q], stds[, q], ranp, Omega[, ((i - 1) * R +
# 1):(i * R), drop = FALSE], correlation, Pi = NULL, Slist = NULL,
# mvar = NULL)
# 13: fnOrig(theta, ...)
# 12: logLikFunc(theta, fnOrig = function (theta, y, X, H, Q, id = NULL,
# ranp, R, correlation, weights = NULL, haltons = NULL, seed = 12345,
# gradient = TRUE, get.bi = FALSE)
# {
# K <- ncol(X[[1]])
# J <- length(X)
# N <- nrow(X[[1]])
# panel <- !is.null(id)
# if (panel) {
# n <- length(unique(id))
# if (length(weights) == 1)
# weights <- rep(weights, N)
# }
# beta <- matrix(theta[1L:(K * Q)], nrow = K, ncol = Q)
# nstds <- if (!correlation)
# K * Q
# else (0.5 * K * (K + 1)) * Q
# stds <- matrix(theta[(K * Q + 1):(K * Q + nstds)], ncol = Q)
# rownames(beta) <- colnames(X[[1]])
# colnames(beta) <- colnames(stds) <- paste("class", 1:Q, sep = ":")
# gamma <- theta[-c(1L:(K * Q + nstds))]
# ew <- lapply(H, function(x) exp(crossprod(t(x), gamma)))
# sew <- suml(ew)
# Wnq <- lapply(ew, function(x) {
# v <- x/sew
# v[is.na(v)] <- 0
# as.vector(v)
# })
# Wnq <- Reduce(cbind, Wnq)
# set.seed(seed)
# Omega <- make.draws(R * ifelse(panel, n, N), K, haltons)
# XBr <- vector(mode = "list", length = J)
# for (j in 1:J) XBr[[j]] <- array(NA, dim = c(N, R, Q))
# nind <- ifelse(panel, n, N)
# if (panel)
# theIds <- unique(id)
# if (get.bi)
# bi <- array(NA, dim = c(nind, R, Q, K), dimnames = list(NULL,
# NULL, NULL, colnames(X[[1]])))
# for (i in 1:nind) {
# if (panel) {
# anid <- theIds[i]
# theRows <- which(id == anid)
# }
# else theRows <- i
# for (q in 1:Q) {
# bq <- Makeh.rcoef(beta[, q], stds[, q], ranp, Omega[,
# ((i - 1) * R + 1):(i * R), drop = FALSE], correlation,
# Pi = NULL, Slist = NULL, mvar = NULL)
# for (j in 1:J) {
# XBr[[j]][theRows, , q] <- crossprod(t(X[[j]][theRows,
# , drop = FALSE]), bq$br)
# }
# if (get.bi)
# bi[i, , q, ] <- t(bq$br)
# }
# }
# EXB <- lapply(XBr, function(x) exp(x))
# SEXB <- suml.array(EXB)
# Pntirq <- lapply(EXB, function(x) x/SEXB)
# Pnrq <- suml.array(mapply("*", Pntirq, y, SIMPLIFY = FALSE))
# if (panel)
# Pnrq <- apply(Pnrq, c(2, 3), tapply, id, prod)
# Pnq <- apply(Pnrq, c(1, 3), mean)
# WPnq <- Wnq * Pnq
# Ln <- apply(WPnq, 1, sum)
# if (get.bi)
# Qir <- list(wnq = Wnq, Ln = Ln, Pnrq = Pnrq)
# lnL <- if (panel)
# sum(log(Ln) * weights[!duplicated(id)])
# else sum(log(Ln) * weights)
# if (gradient) {
# lambda <- mapply(function(y, p) y - p, y, Pntirq, SIMPLIFY = FALSE)
# Wnq.mod <- aperm(repmat(Wnq/Ln, dimen = c(1, 1, R)),
# c(1, 3, 2))
# Qnq.mod <- Wnq.mod * Pnrq
# if (panel)
# Qnq.mod <- Qnq.mod[id, , ]
# eta <- lapply(lambda, function(x) x * Qnq.mod)
# dUdb <- dUds <- vector(mode = "list", length = J)
# for (j in 1:J) {
# dUdb[[j]] <- array(NA, dim = c(N, K, Q))
# dUds[[j]] <- array(NA, dim = c(N, nrow(stds), Q))
# }
# for (i in 1:nind) {
# if (panel) {
# anid <- theIds[i]
# theRows <- which(id == anid)
# }
# else theRows <- i
# for (q in 1:Q) {
# bq <- Makeh.rcoef(beta[, q], stds[, q], ranp,
# Omega[, ((i - 1) * R + 1):(i * R), drop = FALSE],
# correlation, Pi = NULL, Slist = NULL, mvar = NULL)
# for (j in 1:J) {
# dUdb[[j]][theRows, , q] <- tcrossprod(eta[[j]][theRows,
# , q, drop = TRUE], bq$d.mu)
# dUds[[j]][theRows, , q] <- tcrossprod(eta[[j]][theRows,
# , q, drop = TRUE], bq$d.sigma)
# }
# }
# }
# if (correlation) {
# vecX <- c()
# for (i in 1:K) {
# vecX <- c(vecX, i:K)
# }
# Xac <- lapply(X, function(x) x[, vecX])
# }
# else {
# Xac <- X
# }
# Xr <- lapply(X, function(x) x[, rep(1:K, Q)])
# Xacr <- lapply(Xac, function(x) x[, rep(1:ncol(Xac[[1]]),
# Q)])
# dUdb <- lapply(dUdb, function(x) matrix(x, nrow = N))
# dUds <- lapply(dUds, function(x) matrix(x, nrow = N))
# grad.beta <- suml(mapply("*", Xr, dUdb, SIMPLIFY = FALSE))/R
# grad.stds <- suml(mapply("*", Xacr, dUds, SIMPLIFY = FALSE))/R
# Qnq <- WPnq/Ln
# if (panel) {
# Wnq <- Wnq[id, ]
# H <- lapply(H, function(x) x[id, ])
# Qnq <- Qnq[id, ]
# }
# Wg <- vector(mode = "list", length = Q)
# IQ <- diag(Q)
# for (q in 1:Q) Wg[[q]] <- rowSums(Qnq * (repRows(IQ[q,
# ], N) - repCols(Wnq[, q], Q)))
# grad.gamma <- suml(mapply("*", H, Wg, SIMPLIFY = FALSE))
# gari <- cbind(grad.beta, grad.stds, grad.gamma)
# colnames(gari) <- names(theta)
# attr(lnL, "gradient") <- gari * weights
# }
# if (get.bi) {
# Pnjq <- lapply(Pntirq, function(x) apply(x, c(1, 3),
# mean))
# if (panel)
# Wnq <- Wnq[id, ]
# Pw <- lapply(Pnjq, function(x) x * Wnq)
# attr(lnL, "prob.alt") <- sapply(Pw, function(x) apply(x,
# 1, sum))
# attr(lnL, "prob.ind") <- Ln
# attr(lnL, "bi") <- bi
# attr(lnL, "Qir") <- Qir
# attr(lnL, "Wnq") <- Wnq
# }
# lnL
# },# weights = 1, R = 5, seed = 12345, ranp = c(pf = "n", cl = "n",
# loc = "n", wk = "n", tod = "n", seas = "n"), id = structure(c(1L,
# 1L, 1L, 1L, 1L), .Label = "1", class = "factor"), H = list(
# `1` = structure(0, .Dim = c(1L, 1L), .Dimnames = list(
# "1", "(class)2")), `2` = structure(1, .Dim = c(1L,
# 1L), .Dimnames = list("2", "(class)2"))), correlation = FALSE,
# haltons = NA, Q = 2)
# 11: eval(f, sys.frame(sys.parent()))
# 10: eval(f, sys.frame(sys.parent()))
# 9: callWithoutArgs(theta, fName = fName, args = names(formals(sumt)),
# ...)
# 8: (function (theta, fName, ...)
#
# 7: do.call(callWithoutSumt, argList)
# 6: maxOptim(fn = fn, grad = grad, hess = hess, start = start, method = "BFGS",
# fixed = fixed, constraints = constraints, finalHessian = finalHessian,
# parscale = parscale, control = mControl, ...)
# 5: maxRoutine(fn = logLik, grad = grad, hess = hess, start = start,
# constraints = constraints, ...)
# 4: maxLik(method = "bfgs", iterlim = 500, start = c(`class.1.2:(intercept)` = -4.85114128700713,
# `class.1.3:(intercept)` = -7.69322200825539, `class.1.4:(intercept)` = 5.01582959989182,
# class.1.pf = -1.60963678008691, class.1.cl = 0.109892050051351,
# class.1.loc = 18.3461318629584, class.1.wk = 5.01552145983325,
# class.1.tod = 6.12905713997904, class.1.seas = -4.37562129235275,
# `class.2.2:(intercept)` = -4.81114128700713, `class.2.3:(intercept)` = -7.6532220082554,
# `class.2.4:(intercept)` = 5.05582959989182, class.2.pf = -1.56963678008691,
# class.2.cl = 0.149892050051351, class.2.loc = 18.3861318629584,
# class.2.wk = 5.05552145983325, class.2.tod = 6.16905713997903,
# class.2.seas = -4.33562129235275, class.1.sd.pf = 0.08, class.1.sd.cl = 0.08,
# class.1.sd.loc = 0.08, class.1.sd.wk = 0.08, class.1.sd.tod = 0.08,
# class.1.sd.seas = 0.08, class.2.sd.pf = 0.12, class.2.sd.cl = 0.12,
# class.2.sd.loc = 0.12, class.2.sd.wk = 0.12, class.2.sd.tod = 0.12,
# class.2.sd.seas = 0.12, `(class)2` = 0), X = Xl, y = yl, gradient = gradient,
# weights = weights, logLik = ll.mnlogit, R = R, seed = seed,
# ranp = ranp, id = id, H = Hl, correlation = correlation,
# haltons = haltons, Q = Q)
# 3: eval(opt, sys.frame(which = nframe))
# 2: eval(opt, sys.frame(which = nframe))
# 1: gmnl(choice ~ pf + cl + loc + wk + tod + seas | 1 | 0 | 0 | 1,
# data = Electr, subset = 1:20, model = "mm", R = 5, panel = TRUE,
# ranp = c(pf = "n", cl = "n", loc = "n", wk = "n", tod = "n",
# seas = "n"), Q = 2, iterlim = 500)
Bonus2 :sessionInfo()
R version 4.1.2 (2021-11-01)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19044)
Matrix products: default
attached base packages:
[1] grid stats graphics grDevices utils datasets
[7] methods base
other attached packages:
[1] here_1.0.1 strucchange_1.5-2 sandwich_3.0-1
[4] zoo_1.8-9 partykit_1.2-15 mvtnorm_1.1-3
[7] libcoin_1.0-9 mlogit_1.1-1 dfidx_0.0-4
[10] gmnl_1.1-3.2 Formula_1.2-4 maxLik_1.5-2
[13] miscTools_0.6-26 dplyr_1.0.7 nnet_7.3-17
Thank you in advance.
My list (lt):
df_1 <- data.frame(
x = replicate(
n = 2,
expr = runif(n = 30, min = 20, max = 100)
),
y = sample(
x = 1:3, size = 30, replace = TRUE
)
)
lt <- split(
x = df_1,
f = df_1[['y']]
)
vars <- names(df_1)[1:2]
I try:
for (i in vars) {
for (i in i) {
print(pairwise.t.test(x = lt[, i], g = lt[['y']], p.adj = 'bonferroni'))
}
}
But, the error message is:
Error in lista[, i] : incorrect number of dimensions
What's problem?
We don't need to split
pairwise.t.test(unlist(df_1[1:2]), g = rep(df_1$y, 2), p.adj = 'bonferroni')
#Pairwise comparisons using t tests with pooled SD
#data: unlist(df_1[1:2]) and rep(df_1$y, 2)
# 1 2
#2 1.00 -
#3 0.91 1.00
I am working on a model with 8 ODEs, and want to fit some of the parameters (not all) based on observed data I have on just 3 of the 8 state variables.
This is my code:
library("FME")
library("deSolve")
library("lattice")
# Model construction and definition of derivatives
model.sal <- function(time, y, param)
{
N <- y[1]
NH4 <- y[2]
Ps <- y[3]
Pl <- y[4]
Z <- y[5]
B <- y[6]
DON <- y[7]
D <- y[8]
with(as.list(param), {
dNdt <- nit*NH4*B - us*(N/(N+kns))*Ps - ul*(N/(N+knl))*Pl
dNH4dt <- fraz*Z + exb*B - us*(NH4/(NH4+kas))*Ps - ul*(NH4/(NH4+kal))*Pl - ub*(NH4/(NH4+kb))*B
dPsdt <- Ps*(us*((N/N+kns)*(NH4/NH4+kas)*(exp(-((S-Sop)^2)/ts^2))*(tanh(alfa*Im/Pm))) - exs - ms*(Ps/kms+Ps) - g*(pfs*Ps^2/Ps*pfs*kg+pfs*Ps^2)*Z)
dPldt <- Pl*(ul*((N/N+knl)*(NH4/NH4+kal)*(exp(-((S-Sop)^2)/tl^2))*(tanh(alfa*Im/Pm))) - exl - ml*(Pl/kml+Pl) - g*(pfl*Pl^2/Pl*pfl*kg+pfl*Pl^2)*Z)
dZdt <- Z*(ge*(g*(pfs*Ps^2/Ps*pfs*kg+pfs*Ps^2) + (pfl*Pl^2/Pl*pfl*kg+pfl*Pl^2) + (pfb*B^2/B*pfb*kg+pfb*B^2)) - frdz
- fraz - mz*(Z/kmz+Z))
dBdt <- B*(ub*(NH4/(NH4+kb))*(DON/(DON+kb)) - exb - g*(pfb*B^2/B*pfb*kg+pfb*B^2)*Z)
dDONdt <- frdz*Z + exs*Ps + exl*Pl + bd*D - ub*(DON/(DON+kb))
dDdt <- (1-ge)*(g*(pfs*Ps^2/Ps*pfs*kg+pfs*Ps^2) + (pfl*Pl^2/Pl*pfl*kg+pfl*Pl^2) + (pfb*B^2/B*pfb*kg+pfb*B^2))
+ ms*(Ps/kms+Ps) + ml*(Pl/kml+Pl) + mz*(Z/kmz+Z) - bd*D
return(list(c(dNdt, dNH4dt, dPsdt, dPldt, dZdt, dBdt, dDONdt, dDdt)))
})
}
# Observed data on 3 of the 8 state variables
dat <- data.frame(
time = seq(0, 8, 1),
N = c(11.54, 16.6, 7.86, 6.73, 5.6, 5.2, 4.81, 4.18, 3.55),
Pl = c(3.85, 6.25, 3.41, 6.16, 8.92, 12.79, 16.26, 19.21, 22.36),
Ps = c(0.09, 0.33, 0.18, 0.06, 0.12, 0.4, 0.84, 0.7, 0.48))
# Parameters
param.gotm <- c(nit=0.1, us=0.7, kns=0.5, kas=0.5, exs=0.05, ms=0.05,
kms=0.2, ul=0.7, knl=0.5, kal=0.5, exl=0.02, ml=0.05,
kml=0.2, ge=0.625, g=0.35, kg=1, pfs=0.55, pfl=0.3, pfb=0.1,
pfd=0.05, frdz=0.1, fraz=0.7, mz=0.2, kmz=0.2, ub=0.24,
kb=0.05, exb=0.03, bd=0.33, alfa=0.1, Im=100, Pm=0.04,
Sop=34, S=34, ts=2, tl=1)
# Time options, initial values and ODE solution
times <- seq(0, 10, length=200)
y0 <- c(N=7, NH4=0.01, Ps=0.17, Pl=0.77, Z=0.012, B=0.001, DON= 0.001, D=0.01)
out1 <- ode(y0, times, model.sal, param.gotm)
plot(out1, obs = dat)
# Definition of the cost function
cost <- function(p)
{
out <- ode(y0, times, model.sal, p)
modCost(out, dat, weight = "none")
}
fit <- modFit(f = cost, p = param.gotm, method = "Marq")
After running this code I get the following warning message:
Warning message:
In nls.lm(par = Pars, fn = Fun, control = Contr, ...) :
lmdif: info = 0. Improper input parameters.
And summary(fit)gives me this error:
Error in cov2cor(x$cov.unscaled) : 'V' is not a square numeric matrix
In addition: Warning message:
In summary.modFit(fit) : Cannot estimate covariance; system is singular
I just want to fit these parameters: us, ul, ms, ml, g, mz and ub. I am quite confident with the rest of the parameters. Any help or hint on how to do this would be much appreciated.
A bit late maybe but one never knows.
Regarding your code, this is not recommended to try to fit so many parameters at the same time. You will see in my code below that I use the sensFun() function in order to select the parameters that have the biggest impact for that simulation. This enables me to select 5 parameters, instead of your whole list. I would also add a part on the Collin() function, that can help you to decide whether a given parameter is identifiable or not, how many parameters you can simultaneously estimate... With the code below, I manage to get a correct fit.
library("FME")
library("deSolve")
library("lattice")
# # # # # # # # # # # # # # # # #
#
# 1) Preliminary functions
#
# # # # # # # # # # # # # # # # #
# Parameters
pars <- c(
nit=0.1, us=0.7, kns=0.5, kas=0.5, exs=0.05, ms=0.05,
kms=0.2, ul=0.7, knl=0.5, kal=0.5, exl=0.02, ml=0.05,
kml=0.2, ge=0.625, g=0.35, kg=1, pfs=0.55, pfl=0.3, pfb=0.1,
pfd=0.05, frdz=0.1, fraz=0.7, mz=0.2, kmz=0.2, ub=0.24,
kb=0.05, exb=0.03, bd=0.33, alfa=0.1, Im=100, Pm=0.04,
Sop=34, S=34, ts=2, tl=1
)
# Model construction and definition of derivatives
model.sal <- function(t, state, pars){
with(as.list(c(state, pars)), {
dNdt <- nit*NH4*B - us*(N/(N+kns))*Ps - ul*(N/(N+knl))*Pl
dNH4dt <- fraz*Z + exb*B - us*(NH4/(NH4+kas))*Ps - ul*(NH4/(NH4+kal))*Pl - ub*(NH4/(NH4+kb))*B
dPsdt <- Ps*(us*((N/N+kns)*(NH4/NH4+kas)*(exp(-((S-Sop)^2)/ts^2))*(tanh(alfa*Im/Pm))) - exs - ms*(Ps/kms+Ps) - g*(pfs*Ps^2/Ps*pfs*kg+pfs*Ps^2)*Z)
dPldt <- Pl*(ul*((N/N+knl)*(NH4/NH4+kal)*(exp(-((S-Sop)^2)/tl^2))*(tanh(alfa*Im/Pm))) - exl - ml*(Pl/kml+Pl) - g*(pfl*Pl^2/Pl*pfl*kg+pfl*Pl^2)*Z)
dZdt <- Z*(ge*(g*(pfs*Ps^2/Ps*pfs*kg+pfs*Ps^2) + (pfl*Pl^2/Pl*pfl*kg+pfl*Pl^2) + (pfb*B^2/B*pfb*kg+pfb*B^2)) - frdz
- fraz - mz*(Z/kmz+Z))
dBdt <- B*(ub*(NH4/(NH4+kb))*(DON/(DON+kb)) - exb - g*(pfb*B^2/B*pfb*kg+pfb*B^2)*Z)
dDONdt <- frdz*Z + exs*Ps + exl*Pl + bd*D - ub*(DON/(DON+kb))
dDdt <- (1-ge)*(g*(pfs*Ps^2/Ps*pfs*kg+pfs*Ps^2) + (pfl*Pl^2/Pl*pfl*kg+pfl*Pl^2) + (pfb*B^2/B*pfb*kg+pfb*B^2))
+ ms*(Ps/kms+Ps) + ml*(Pl/kml+Pl) + mz*(Z/kmz+Z) - bd*D
return(list(c(dNdt, dNH4dt, dPsdt, dPldt, dZdt, dBdt, dDONdt, dDdt)))
})
}
# wrapper
solve_model <- function(pars, times = seq(0, 10, length=200)) {
# initial values
state <- c(N=7, NH4=0.01, Ps=0.17, Pl=0.77, Z=0.012, B=0.001, DON= 0.001, D=0.01)
out <- ode(y = state, times = times, func = model.sal, parms = pars)
return(out)
}
# Definition of the cost function
Objective <- function(x, parset = names(x)) {
pars[parset] <- x
tout <- seq(0, 10, length=200)
out <- solve_model(pars, tout)
modCost(out, dat, weight = "none")
}
# # # # # # # # # # # # # # # # #
#
# 2) Preliminary data
#
# # # # # # # # # # # # # # # # #
# Observed data on 3 of the 8 state variables
dat <- data.frame(
time = seq(0, 8, 1),
N = c(11.54, 16.6, 7.86, 6.73, 5.6, 5.2, 4.81, 4.18, 3.55),
Pl = c(3.85, 6.25, 3.41, 6.16, 8.92, 12.79, 16.26, 19.21, 22.36),
Ps = c(0.09, 0.33, 0.18, 0.06, 0.12, 0.4, 0.84, 0.7, 0.48))
# # # # # # # # # # # # # # # # # # # # #
#
# 3) Select the good parameters to fit
#
# # # # # # # # # # # # # # # # # # # # #
# Determine what are the best parameters to fit
Sfun <- sensFun(Objective, pars)
plot(summary(Sfun))
# from the mean plot, I see that ul, us, pfl, ge and knl have the most influence for the simulation
# I will do the optimization on them so.
# # # # # # # # # # # # #
#
# 4) Optimization
#
# # # # # # # # # # # # #
# set up the subset of parameters
parToFit <- c(ul = 0.7, us = 0.7, pfl = 0.3, ge = 0.625, knl = 0.5)
# run the beast
Fit <- modFit(
f = Objective,
p = parToFit,
lower = 0,
upper = Inf,
method = "Marq",
jac = NULL,
control = list(
#maxiter = 100,
ftol = 1e-06,
ptol = 1e-06,
gtol = 1e-06,
nprint = 1
),
hessian = TRUE
)
# # # # # # # # # # # # #
#
# 5) Rerun simulations and plot
#
# # # # # # # # # # # # #
# recover the optimized parameters and plot the results
# You could also plot the non optimized curves to compare
pars[names(parToFit)] <- Fit$par
optim <- solve_model(pars, times = seq(0, 10, length=200))
par(mfrow = c(2, 2))
plot(optim[, "time"], optim[, "N"], xlab = "Time (min)", ylab = "N", lwd = 2, type = "l", col = "red")
points(dat[, "time"], dat[, "N"], cex = 2, pch = 18)
plot(optim[, "time"], optim[, "Pl"], xlab = "Time (min)", ylab = "Pl", lwd = 2, type = "l", col = "red")
points(dat[, "time"], dat[, "Pl"], cex = 2, pch = 18)
plot(optim[, "time"], optim[, "Ps"], xlab = "Time (min)", ylab = "Ps", lwd = 2, type = "l", col = "red")
points(dat[, "time"], dat[, "Ps"], cex = 2, pch = 18)
If anyone can help me how to incorporate step in input parameter with respect to time. Please see the code below:
library(ReacTran)
N <- 10 # No of grids
L = 0.10 # thickness, m
l = L/2 # Half of thickness, m
k= 0.412 # thermal conductivity, W/m-K
cp = 3530 # thermal conductivity, J/kg-K
rho = 1100 # density, kg/m3
T_int = 57.2 # Initial temperature , degC
T_air = 19 # air temperature, degC
h_air = 20 # Convective heat transfer coeff of air, W/m2-K
xgrid <- setup.grid.1D(x.up = 0, x.down = l, N = N)
x <- xgrid$x.mid
alpha.coeff <- (k*3600)/(rho*cp)
Diffusion <- function (t, Y, parms){
tran <- tran.1D(C=Y, flux.down = 0, C.up = T_air, a.bl.up = h_air,
D = alpha.coeff, dx = xgrid)
list(dY = tran$dC, flux.up = tran$flux.up,
flux.down = tran$flux.down)
}
# Initial condition
Yini <- rep(T_int, N)
times <- seq(from = 0, to = 2, by = 0.2)
print(system.time(
out <- ode.1D(y = Yini, times = times, func = Diffusion,
parms = NULL, dimens = N)))
plot(times, out[,(N+1)], type = "l", lwd = 2, xlab = "time, hr", ylab = "Temperature")
I want the T_air to be constant for the 1st hour and it changes to another value for remaining 1 hr. This would be a step changein the parameter. How can I do it?
Any help would be appreciated.
Thanks,