如何获得具有交互作用的非线性混合模型(逻辑增长曲线)的置信区间

时间:2019-04-06 18:16:55

标签: r confidence-interval non-linear-regression nlme

对于一个具有双向交互作用的非线性模型(逻辑增长曲线),我想使用增量法或自举法来计算置信区间,但是不确定如何编码。这篇文章与此类似 https://stats.stackexchange.com/questions/231074/confidence-intervals-on-predictions-for-a-non-linear-mixed-model-nlme。但是,我不知道如何修改它以处理交互项。我正在使用ChickWeight数据框,但是我已经对其进行了修改,以使曲线更像S形/外观类似于我正在使用的数据框。

到目前为止,我尝试自举没有成功。

library(tidyverse)
library(broom)
library(nlme)

# Modify df so that there are more subjects (Chicks) per treatment (Diet) 
Chicks.df <- ChickWeight
Chicks.df$Chick <- factor(Chicks.df$Chick, ordered=F)
Chicks.df <- Chicks.df %>% mutate(Diet = ifelse(Diet == 3 | Diet == 4, 2, 1),
                              Diet = as.factor(Diet))

# Create df with an additional time point (25th) to make curves more sigmoidal
t.25_diet1 <- rnorm(30, mean=178, sd=1) # new observations for Diet1
t.25_diet2 <- rnorm(20, mean=215, sd=1) # new observations for Diet2
weight <- c(t.23_diet1, t.23_diet2) # bind vectors together
Diet <- c(rep(1,30), rep(2,20)) # Create remaining variables for df
Chick <- c(seq(1:30), seq(31, 50)) 
Time <- rep(25, 50)

# Bind variables together to make new df, and then combine with original df (i.e. Chicks.df) 
newdata <- data.frame(cbind(weight, Diet, Chick, Time))
newdata$Diet <- as.factor(newdata$Diet)
newdata$Chick <- as.factor(newdata$Chick)
Chicks.df <- bind_rows(Chicks.df, data.frame(newdata))

# Using nested ifelse, assign half of the individuals in each diet to new treatment
Chicks.df <- Chicks.df %>% mutate(Drug = 
                                ifelse(Chick %in% c(1:15) & 
                                         Diet == 1, 0, 
                                       ifelse(Chick %in% c(16:30) & 
                                              Diet == 1, 1, 
                                              ifelse(Chick %in% 
                                                       c(31:40) & Diet
                                                     == 2, 0, 1))))
# Check Curves
Chicks.df$Drug <- as.factor(Chicks.df$Drug)
ggplot(Chicks.df, aes(Time, weight, col=Diet, linetype=Drug)) + geom_smooth()

# Get self-starting values (use broom pkg)
 Chicks.df %>% 
     group_by(Diet, Drug) %>% 
     do(fit = nls(weight ~ SSlogis(Time, Asym, xmid, scal), data = .)) %>% 
     tidy(fit) %>% 
     select(Diet, Drug, term, estimate) %>% 
     spread(term, estimate) 

     # Run model 
      mod <-nlme(weight ~ SSlogis(Time, Asym, xmid, scal),
      fixed=list(Asym + xmid + scal ~ Diet*Drug),
      random = Asym ~ 1 | Chick,
      start=list(fixed=c(Asym=c(209, 215, 209, 249), 
                            xmid=c(10.2, 10.5, 10.7, 9.7), 
                            scal=c(6.3, 6.3, 5.1, 5.5))),
         data=Chicks.df)

   summary(mod)

   # Build prediction df and attempt bootstrapping 
   pframe <- data.frame(Time = Chicks.df$Time, 
                    Diet = Chicks.df$Diet,
                    Drug = Chicks.df$Drug,
                    Chick = Chicks.df$Chick[1])
   pframe$weight <- predict(mod, pframe, re.form=~0) 

   myfun <- function(data, x){
            fBoot <- nlme(weight ~ SSlogis(Time, Asym, xmid, scal),
      fixed=list(Asym + xmid + scal ~ Diet*Drug),
      random = Asym ~ 1 | Chick,
      start=list(fixed=c(Asym=c(209, 215, 209, 249), 
                            xmid=c(10.2, 10.5, 10.7, 9.7), 
                            scal=c(6.3, 6.3, 5.1, 5.5))),
         data=Chicks.df)
            return((predict(fBoot, newdata=pframe)))
          }

     myboot <- boot::boot(pframe, myfun, R=100)
     myboot # no values predicted

0 个答案:

没有答案