Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct way to implement broom for nlmixr #68

Closed
mattfidler opened this issue Apr 15, 2019 · 22 comments
Closed

Correct way to implement broom for nlmixr #68

mattfidler opened this issue Apr 15, 2019 · 22 comments

Comments

@mattfidler
Copy link

Hi,

What is the correct way to implement broom for nlmixr?

My biggest question is that I don't want to re-export the tidy methods because it would introduce a new dependency to nlmixr; So, what is the correct way to specify this dependency?

@mattfidler
Copy link
Author

Also is there extra information that the mixed models tidiers are outputting?

@mattfidler
Copy link
Author

It seems that this may be the requested format:

model <- mixed_model(...)
tidy(model, effects = "fixed")
tidy(model, effects = "random")

@mattfidler
Copy link
Author

I figured out what to do for the imports/suggest/etc. I'm unsure if there is anything in specific you wish to remain consistent with mixed models.

@bbolker
Copy link
Owner

bbolker commented Apr 15, 2019

Good questions. I'm not sure there's a formal description, but there should be. There is some discussion here. In general for the existing tidiers effects can take the value fixed, ran_pars (top-level random effects parameters, i.e. variance/covariance or std dev/cor), ran_vals (conditional modes/BLUPs/groupwise parameter estimates). The list of expected column names is here.

@mattfidler
Copy link
Author

The expected column names do not match lm expected column names. Will there be some sort of alignment for these names?

@mattfidler
Copy link
Author

mattfidler commented Apr 15, 2019

Also since the broom documentation reads "random", should this be accepted and return (most likely) ran_pars

@mattfidler
Copy link
Author

I was wrong about the "lm" column names. They seem aligned. I'm unsure why I thought the names were different.

@mattfidler
Copy link
Author

nlmixr currently also has some information that is useful for pharmacometricians that is not output in this table. My thought is to keep it, is there any reason why it should be excluded?

@mattfidler
Copy link
Author

For a nlme object,

> tidy(as.nlme(fit),effects="ran_pars")
Error in match.arg(effects, c("random", "fixed")) : 
  'arg' should be one of "random", "fixed"

@bbolker
Copy link
Owner

bbolker commented Apr 15, 2019

Also since the broom documentation reads "random", should this be accepted and return (most likely) ran_pars

Maybe. Eventually I think/hope that the mixed-model tidiers will be removed from broom altogether ... if there's a useful error message (I haven't checked), I might prefer to leave it as is rather than multiply synonyms.

@bbolker
Copy link
Owner

bbolker commented Apr 16, 2019

oops. I've updated many of the tidiers, but hadn't gotten around to nlme I guess. I agree it should allow "random" for back-compatibility ...

@bbolker
Copy link
Owner

bbolker commented Apr 16, 2019

Double hmmm. The GitHub version of broom.mixed, and I think the CRAN version as well, don't use "random". Can you show me a reproducible example with the results of sessionInfo()?

@mattfidler
Copy link
Author

Sure; Its in broom not broom.mixed. There seems to be some incompatability in how they extract the "random" information.

Below is a reprex:

library(nlme)
library(broom)
fm1 <- nlme(height ~ SSasymp(age, Asym, R0, lrc),
            data = Loblolly,
            fixed = Asym + R0 + lrc ~ 1,
            random = Asym ~ 1,
            start = c(Asym = 103, R0 = -8.5, lrc = -3.3))

tidy(fm1)
#>    group level term   estimate
#> 1   Seed   329 Asym  95.884132
#> 2   Seed   327 Asym  96.432780
#> 3   Seed   325 Asym  99.757521
#> 4   Seed   307 Asym  99.090820
#> 5   Seed   331 Asym  98.468135
#> 6   Seed   311 Asym 100.047745
#> 7   Seed   315 Asym 101.339541
#> 8   Seed   321 Asym  99.088285
#> 9   Seed   319 Asym 102.644389
#> 10  Seed   301 Asym 103.461512
#> 11  Seed   323 Asym 104.435835
#> 12  Seed   309 Asym 105.038646
#> 13  Seed   303 Asym 106.059078
#> 14  Seed   305 Asym 108.545981
#> 15  Seed   329   R0  -8.627331
#> 16  Seed   327   R0  -8.627331
#> 17  Seed   325   R0  -8.627331
#> 18  Seed   307   R0  -8.627331
#> 19  Seed   331   R0  -8.627331
#> 20  Seed   311   R0  -8.627331
#> 21  Seed   315   R0  -8.627331
#> 22  Seed   321   R0  -8.627331
#> 23  Seed   319   R0  -8.627331
#> 24  Seed   301   R0  -8.627331
#> 25  Seed   323   R0  -8.627331
#> 26  Seed   309   R0  -8.627331
#> 27  Seed   303   R0  -8.627331
#> 28  Seed   305   R0  -8.627331
#> 29  Seed   329  lrc  -3.233751
#> 30  Seed   327  lrc  -3.233751
#> 31  Seed   325  lrc  -3.233751
#> 32  Seed   307  lrc  -3.233751
#> 33  Seed   331  lrc  -3.233751
#> 34  Seed   311  lrc  -3.233751
#> 35  Seed   315  lrc  -3.233751
#> 36  Seed   321  lrc  -3.233751
#> 37  Seed   319  lrc  -3.233751
#> 38  Seed   301  lrc  -3.233751
#> 39  Seed   323  lrc  -3.233751
#> 40  Seed   309  lrc  -3.233751
#> 41  Seed   303  lrc  -3.233751
#> 42  Seed   305  lrc  -3.233751
tidy(fm1, effects="ran_pars")
#> Error in match.arg(effects, c("random", "fixed")): 'arg' should be one of "random", "fixed"

tidy(fm1, effects="random")
#>    group level term   estimate
#> 1   Seed   329 Asym  95.884132
#> 2   Seed   327 Asym  96.432780
#> 3   Seed   325 Asym  99.757521
#> 4   Seed   307 Asym  99.090820
#> 5   Seed   331 Asym  98.468135
#> 6   Seed   311 Asym 100.047745
#> 7   Seed   315 Asym 101.339541
#> 8   Seed   321 Asym  99.088285
#> 9   Seed   319 Asym 102.644389
#> 10  Seed   301 Asym 103.461512
#> 11  Seed   323 Asym 104.435835
#> 12  Seed   309 Asym 105.038646
#> 13  Seed   303 Asym 106.059078
#> 14  Seed   305 Asym 108.545981
#> 15  Seed   329   R0  -8.627331
#> 16  Seed   327   R0  -8.627331
#> 17  Seed   325   R0  -8.627331
#> 18  Seed   307   R0  -8.627331
#> 19  Seed   331   R0  -8.627331
#> 20  Seed   311   R0  -8.627331
#> 21  Seed   315   R0  -8.627331
#> 22  Seed   321   R0  -8.627331
#> 23  Seed   319   R0  -8.627331
#> 24  Seed   301   R0  -8.627331
#> 25  Seed   323   R0  -8.627331
#> 26  Seed   309   R0  -8.627331
#> 27  Seed   303   R0  -8.627331
#> 28  Seed   305   R0  -8.627331
#> 29  Seed   329  lrc  -3.233751
#> 30  Seed   327  lrc  -3.233751
#> 31  Seed   325  lrc  -3.233751
#> 32  Seed   307  lrc  -3.233751
#> 33  Seed   331  lrc  -3.233751
#> 34  Seed   311  lrc  -3.233751
#> 35  Seed   315  lrc  -3.233751
#> 36  Seed   321  lrc  -3.233751
#> 37  Seed   319  lrc  -3.233751
#> 38  Seed   301  lrc  -3.233751
#> 39  Seed   323  lrc  -3.233751
#> 40  Seed   309  lrc  -3.233751
#> 41  Seed   303  lrc  -3.233751
#> 42  Seed   305  lrc  -3.233751

tidy(fm1, effects="fixed")
#> # A tibble: 3 x 5
#>   term  estimate std.error statistic  p.value
#>   <chr>    <dbl>     <dbl>     <dbl>    <dbl>
#> 1 Asym    101.      2.46        41.2 7.89e-50
#> 2 R0       -8.63    0.318      -27.1 3.35e-38
#> 3 lrc      -3.23    0.0343     -94.4 7.81e-74

library(broom.mixed)
#> 
#> Attaching package: 'broom.mixed'
#> The following object is masked from 'package:broom':
#> 
#>     tidyMCMC

tidy(fm1, effects="ran_pars")
#> Warning in tidy.lme(fm1, effects = "ran_pars"): ran_pars not yet
#> implemented for nonlinear models
#> # A tibble: 0 x 0

tidy(fm1, effects="random")
#> Error in tidy.lme(fm1, effects = "random"): unknown effect type random

tidy(fm1, effects="fixed")
#> # A tibble: 3 x 6
#>   term  estimate std.error    df statistic  p.value
#>   <chr>    <dbl>     <dbl> <dbl>     <dbl>    <dbl>
#> 1 Asym    101.      2.46      68      41.2 7.89e-50
#> 2 R0       -8.63    0.318     68     -27.1 3.35e-38
#> 3 lrc      -3.23    0.0343    68     -94.4 7.81e-74

sessionInfo()
#> R version 3.5.3 (2019-03-11)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 16299)
#> 
#> Matrix products: default
#> 
#> locale:
#> [1] LC_COLLATE=English_United States.1252 
#> [2] LC_CTYPE=English_United States.1252   
#> [3] LC_MONETARY=English_United States.1252
#> [4] LC_NUMERIC=C                          
#> [5] LC_TIME=English_United States.1252    
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#> [1] broom.mixed_0.2.4.9000 broom_0.5.2            nlme_3.1-137          
#> 
#> loaded via a namespace (and not attached):
#>  [1] Rcpp_1.0.1       pillar_1.3.1     compiler_3.5.3   highr_0.8       
#>  [5] plyr_1.8.4       TMB_1.7.15       tools_3.5.3      digest_0.6.18   
#>  [9] evaluate_0.13    tibble_2.1.1     lattice_0.20-38  pkgconfig_2.0.2 
#> [13] rlang_0.3.4      Matrix_1.2-17    cli_1.1.0        yaml_2.2.0      
#> [17] xfun_0.6         coda_0.19-2      dplyr_0.8.0.1    stringr_1.4.0   
#> [21] knitr_1.22       generics_0.0.2   grid_3.5.3       tidyselect_0.2.5
#> [25] glue_1.3.1       R6_2.4.0         fansi_0.4.0      rmarkdown_1.12  
#> [29] reshape2_1.4.3   purrr_0.3.2      tidyr_0.8.3      magrittr_1.5    
#> [33] backports_1.1.4  htmltools_0.3.6  assertthat_0.2.1 utf8_1.1.4      
#> [37] stringi_1.4.3    crayon_1.3.4

Created on 2019-04-15 by the reprex package (v0.2.1)

@mattfidler
Copy link
Author

It also seems counter-intuitive to me that the default is not "fixed"

@mattfidler
Copy link
Author

I don't believe the broom version actually returns a tibble for the random effects parameter either.

@mattfidler
Copy link
Author

More questions:

  • What is the difference between "ran_vals" and "ran_coefs"
  • Should the tidy output have an "effect" column?
  • It seems that lmer uses sd/cor for "ran_pars"; Is var/cov possible with an option?

@mattfidler
Copy link
Author

I just saw the default for lmer is fixed + ran_pars that makes more sense than the "random" from broom.

@mattfidler
Copy link
Author

I have updated the tidiers, they seem to be similar to the lmer tidiers except:

  • I have used SD(par_name) or R(par_name1, par_name2). Does this need to be standardized?
  • I do not know what ran_coefs is supposed to give, so it is not supported right now.
  • glance returns a NONMEM-compatible objective function value OBJF and condition number conditionNumber, which isn't quite aligned with what you provide.

I consider this complete, unless you have any objections to the interface.

library(nlmixr)
one.cmt <- function() {
    ini({
        tka <- .5   # log Ka
        tcl <- -3.2 # log Cl
        tv <- -1    # log V
        eta.ka ~ 1
        eta.cl ~ 2
        eta.v ~ 1
        add.err <- 0.1
    })
    model({
        ka <- exp(tka + eta.ka)
        cl <- exp(tcl + eta.cl)
        v <- exp(tv + eta.v)
        linCmt() ~ add(add.err)
    })
}

fit <- nlmixr(one.cmt, theo_sd, est="nlme")
#> Warning in nlmixrUI.nlme.var(obj): Initial condition for additive error
#> ignored with nlme
#> 
#> **Iteration 1
#> LME step: Loglik: -182.2318, nlminb iterations: 1
#> reStruct  parameters:
#>       ID1       ID2       ID3 
#> 0.2783009 1.0022617 2.0758984 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.1492 
#>  fixed effects: 0.4479981  -3.211935  -0.7859319  
#>  iterations: 7 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>     fixed  reStruct 
#> 0.2723749 3.2673500 
#> 
#> **Iteration 2
#> LME step: Loglik: -179.291, nlminb iterations: 9
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.08333469 0.96385386 1.63552496 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.28224 
#>  fixed effects: 0.4441499  -3.211529  -0.7863391  
#>  iterations: 7 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>       fixed    reStruct 
#> 0.008664073 0.172140456 
#> 
#> **Iteration 3
#> LME step: Loglik: -179.337, nlminb iterations: 8
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.07085101 0.96127445 1.63887834 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.21956 
#>  fixed effects: 0.445849  -3.211695  -0.7861748  
#>  iterations: 7 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>       fixed    reStruct 
#> 0.003810966 0.083040769 
#> 
#> **Iteration 4
#> LME step: Loglik: -179.3201, nlminb iterations: 7
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.07619041 0.96243387 1.63736919 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.24586 
#>  fixed effects: 0.4451181  -3.211622  -0.7862475  
#>  iterations: 7 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>       fixed    reStruct 
#> 0.001641979 0.034519243 
#> 
#> **Iteration 5
#> LME step: Loglik: -179.328, nlminb iterations: 6
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.07381939 0.96192229 1.63801880 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.23423 
#>  fixed effects: 0.4454379  -3.211654  -0.7862161  
#>  iterations: 7 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>        fixed     reStruct 
#> 0.0007179333 0.0153297894 
#> 
#> **Iteration 6
#> LME step: Loglik: -179.3247, nlminb iterations: 5
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.07486971 0.96215578 1.63772962 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.24087 
#>  fixed effects: 0.4454379  -3.211654  -0.7862161  
#>  iterations: 1 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>       fixed    reStruct 
#> 0.000000000 0.008689492 
#> 
#> **Iteration 7
#> LME step: Loglik: -179.3247, nlminb iterations: 1
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.07485046 0.96214641 1.63773356 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.24087 
#>  fixed effects: 0.4454379  -3.211654  -0.7862161  
#>  iterations: 1 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>       fixed    reStruct 
#> 0.00000e+00 1.29286e-11
#> Calculating residuals/tables
#> done.

tidy(fit)
#> # A tibble: 7 x 5
#>   effect   group         term       estimate std.error
#>   <chr>    <chr>         <chr>         <dbl>     <dbl>
#> 1 fixed    <NA>          tka          1.56     0.309  
#> 2 fixed    <NA>          tcl          0.0403   0.00340
#> 3 fixed    <NA>          tv           0.456    0.0211 
#> 4 ran_pars ID            SD(eta.ka)   0.642   NA      
#> 5 ran_pars ID            SD(eta.cl)   0.264   NA      
#> 6 ran_pars ID            SD(eta.v)    0.135   NA      
#> 7 ran_pars Residual(add) add.err      0.692   NA
tidy(fit,effects="fixed")
#> # A tibble: 3 x 4
#>   effect term  estimate std.error
#>   <chr>  <chr>    <dbl>     <dbl>
#> 1 fixed  tka     1.56     0.309  
#> 2 fixed  tcl     0.0403   0.00340
#> 3 fixed  tv      0.456    0.0211
tidy(fit,effects="random")
#> # A tibble: 36 x 5
#>    effect   group level term   estimate
#>    <chr>    <fct> <int> <fct>     <dbl>
#>  1 ran_vals ID        1 eta.ka   0.124 
#>  2 ran_vals ID        2 eta.ka   0.224 
#>  3 ran_vals ID        3 eta.ka   0.390 
#>  4 ran_vals ID        4 eta.ka  -0.255 
#>  5 ran_vals ID        5 eta.ka  -0.0728
#>  6 ran_vals ID        6 eta.ka  -0.311 
#>  7 ran_vals ID        7 eta.ka  -0.805 
#>  8 ran_vals ID        8 eta.ka  -0.152 
#>  9 ran_vals ID        9 eta.ka   1.43  
#> 10 ran_vals ID       10 eta.ka  -0.771 
#> # … with 26 more rows
tidy(fit, effects="ran_pars")
#> # A tibble: 4 x 4
#>   effect   group         term       estimate
#>   <chr>    <chr>         <chr>         <dbl>
#> 1 ran_pars ID            SD(eta.ka)    0.642
#> 2 ran_pars ID            SD(eta.cl)    0.264
#> 3 ran_pars ID            SD(eta.v)     0.135
#> 4 ran_pars Residual(add) add.err       0.692
tidy(fit, effects="ran_vals")
#> # A tibble: 36 x 5
#>    effect   group level term   estimate
#>    <chr>    <fct> <int> <fct>     <dbl>
#>  1 ran_vals ID        1 eta.ka   0.124 
#>  2 ran_vals ID        2 eta.ka   0.224 
#>  3 ran_vals ID        3 eta.ka   0.390 
#>  4 ran_vals ID        4 eta.ka  -0.255 
#>  5 ran_vals ID        5 eta.ka  -0.0728
#>  6 ran_vals ID        6 eta.ka  -0.311 
#>  7 ran_vals ID        7 eta.ka  -0.805 
#>  8 ran_vals ID        8 eta.ka  -0.152 
#>  9 ran_vals ID        9 eta.ka   1.43  
#> 10 ran_vals ID       10 eta.ka  -0.771 
#> # … with 26 more rows
## Still not sure what ran_coefs means/should be.
glance(fit)
#> # A tibble: 1 x 5
#>    OBJF   AIC   BIC logLik conditionNumber
#>   <dbl> <dbl> <dbl>  <dbl>           <dbl>
#> 1  116.  373.  393.  -179.            18.2

library(ggplot2)
library(dotwhisker)

tidy(fit) %>% dwplot

Created on 2019-04-22 by the reprex package (v0.2.1)

@bbolker
Copy link
Owner

bbolker commented Apr 22, 2019

  • I would actually prefer that the names be standardized. This is mentioned (but not discussed) in term naming #8 : I will add some discussion there.
  • ran_coefs() gives the predicted value of the parameter for each level, similar to what nlme::coef().[n]lme() and lme4::coef.merMod() do (as opposed to the deviation of the parameters for each level from the population mean, which is what ran_pars returns).
  • I have fewer/weaker opinions about glance().

mattfidler added a commit to nlmixrdevelopment/nlmixr that referenced this issue Apr 22, 2019
mattfidler added a commit to nlmixrdevelopment/nlmixr that referenced this issue Apr 22, 2019
@mattfidler
Copy link
Author

mattfidler commented Apr 22, 2019

For ran_coef do you do anything for exponentiate? I know nlme doesn't but I'm unsure if what you do does or not. I have the exponentiation state parsed/recorded for each parameter. For me, it would be helpful to have these on the correct scale.

@bbolker
Copy link
Owner

bbolker commented Apr 22, 2019

No, at present it's silently (!!) ignored. It should do something sensible for GLMMs, though (hard to see a use case for LMMs).

mattfidler added a commit to nlmixrdevelopment/nlmixr that referenced this issue Apr 22, 2019
@mattfidler
Copy link
Author

mattfidler commented Apr 22, 2019

Thank you for the explanation about the ran_coef it is now supported in nlmixr. Like nlme the parameter names are the population parameter names instead of the random effect parameter names for ran_coef. I also support the exponentiate parameter, by default it only applies exponentials on parameters that were exponentiated in the original model.

library(nlmixr)
one.cmt <- function() {
    ini({
        tka <- .5   # log Ka
        tcl <- -3.2 # log Cl
        tv <- -1    # log V
        eta.ka ~ 1
        eta.cl ~ 2
        eta.v ~ 1
        add.err <- 0.1
    })
    model({
        ka <- exp(tka + eta.ka)
        cl <- exp(tcl + eta.cl)
        v <- exp(tv + eta.v)
        linCmt() ~ add(add.err)
    })
}

fit <- nlmixr(one.cmt, theo_sd, est="nlme")
#> Warning in nlmixrUI.nlme.var(obj): Initial condition for additive error
#> ignored with nlme
#> 
#> **Iteration 1
#> LME step: Loglik: -182.2318, nlminb iterations: 1
#> reStruct  parameters:
#>       ID1       ID2       ID3 
#> 0.2783009 1.0022617 2.0758984 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.1492 
#>  fixed effects: 0.4479981  -3.211935  -0.7859319  
#>  iterations: 7 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>     fixed  reStruct 
#> 0.2723749 3.2673500 
#> 
#> **Iteration 2
#> LME step: Loglik: -179.291, nlminb iterations: 9
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.08333469 0.96385386 1.63552496 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.28224 
#>  fixed effects: 0.4441499  -3.211529  -0.7863391  
#>  iterations: 7 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>       fixed    reStruct 
#> 0.008664073 0.172140456 
#> 
#> **Iteration 3
#> LME step: Loglik: -179.337, nlminb iterations: 8
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.07085101 0.96127445 1.63887834 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.21956 
#>  fixed effects: 0.445849  -3.211695  -0.7861748  
#>  iterations: 7 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>       fixed    reStruct 
#> 0.003810966 0.083040769 
#> 
#> **Iteration 4
#> LME step: Loglik: -179.3201, nlminb iterations: 7
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.07619041 0.96243387 1.63736919 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.24586 
#>  fixed effects: 0.4451181  -3.211622  -0.7862475  
#>  iterations: 7 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>       fixed    reStruct 
#> 0.001641979 0.034519243 
#> 
#> **Iteration 5
#> LME step: Loglik: -179.328, nlminb iterations: 6
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.07381939 0.96192229 1.63801880 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.23423 
#>  fixed effects: 0.4454379  -3.211654  -0.7862161  
#>  iterations: 7 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>        fixed     reStruct 
#> 0.0007179333 0.0153297894 
#> 
#> **Iteration 6
#> LME step: Loglik: -179.3247, nlminb iterations: 5
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.07486971 0.96215578 1.63772962 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.24087 
#>  fixed effects: 0.4454379  -3.211654  -0.7862161  
#>  iterations: 1 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>       fixed    reStruct 
#> 0.000000000 0.008689492 
#> 
#> **Iteration 7
#> LME step: Loglik: -179.3247, nlminb iterations: 1
#> reStruct  parameters:
#>        ID1        ID2        ID3 
#> 0.07485046 0.96214641 1.63773356 
#>  Beginning PNLS step: ..  completed fit_nlme() step.
#> PNLS step: RSS =  63.24087 
#>  fixed effects: 0.4454379  -3.211654  -0.7862161  
#>  iterations: 1 
#> Convergence crit. (must all become <= tolerance = 1e-05):
#>       fixed    reStruct 
#> 0.00000e+00 1.29286e-11
#> Calculating residuals/tables
#> done.

tidy(fit)
#> # A tibble: 7 x 5
#>   effect   group         term       estimate std.error
#>   <chr>    <chr>         <chr>         <dbl>     <dbl>
#> 1 fixed    <NA>          tka          1.56     0.309  
#> 2 fixed    <NA>          tcl          0.0403   0.00340
#> 3 fixed    <NA>          tv           0.456    0.0211 
#> 4 ran_pars ID            sd__eta.ka   0.642   NA      
#> 5 ran_pars ID            sd__eta.cl   0.264   NA      
#> 6 ran_pars ID            sd__eta.v    0.135   NA      
#> 7 ran_pars Residual(add) add.err      0.692   NA
tidy(fit,effects="fixed")
#> # A tibble: 3 x 4
#>   effect term  estimate std.error
#>   <chr>  <chr>    <dbl>     <dbl>
#> 1 fixed  tka     1.56     0.309  
#> 2 fixed  tcl     0.0403   0.00340
#> 3 fixed  tv      0.456    0.0211
tidy(fit,effects="random")
#> # A tibble: 36 x 5
#>    effect   group level term   estimate
#>    <chr>    <fct> <int> <fct>     <dbl>
#>  1 ran_vals ID        1 eta.ka   0.124 
#>  2 ran_vals ID        2 eta.ka   0.224 
#>  3 ran_vals ID        3 eta.ka   0.390 
#>  4 ran_vals ID        4 eta.ka  -0.255 
#>  5 ran_vals ID        5 eta.ka  -0.0728
#>  6 ran_vals ID        6 eta.ka  -0.311 
#>  7 ran_vals ID        7 eta.ka  -0.805 
#>  8 ran_vals ID        8 eta.ka  -0.152 
#>  9 ran_vals ID        9 eta.ka   1.43  
#> 10 ran_vals ID       10 eta.ka  -0.771 
#> # … with 26 more rows
tidy(fit, effects="ran_pars")
#> # A tibble: 4 x 4
#>   effect   group         term       estimate
#>   <chr>    <chr>         <chr>         <dbl>
#> 1 ran_pars ID            sd__eta.ka    0.642
#> 2 ran_pars ID            sd__eta.cl    0.264
#> 3 ran_pars ID            sd__eta.v     0.135
#> 4 ran_pars Residual(add) add.err       0.692
tidy(fit, effects="ran_vals")
#> # A tibble: 36 x 5
#>    effect   group level term   estimate
#>    <chr>    <fct> <int> <fct>     <dbl>
#>  1 ran_vals ID        1 eta.ka   0.124 
#>  2 ran_vals ID        2 eta.ka   0.224 
#>  3 ran_vals ID        3 eta.ka   0.390 
#>  4 ran_vals ID        4 eta.ka  -0.255 
#>  5 ran_vals ID        5 eta.ka  -0.0728
#>  6 ran_vals ID        6 eta.ka  -0.311 
#>  7 ran_vals ID        7 eta.ka  -0.805 
#>  8 ran_vals ID        8 eta.ka  -0.152 
#>  9 ran_vals ID        9 eta.ka   1.43  
#> 10 ran_vals ID       10 eta.ka  -0.771 
#> # … with 26 more rows

tidy(fit, effects="ran_coef")
#> # A tibble: 36 x 5
#>    effect   group level term  estimate
#>    <chr>    <fct> <int> <fct>    <dbl>
#>  1 ran_coef ID        1 tka      1.77 
#>  2 ran_coef ID        2 tka      1.95 
#>  3 ran_coef ID        3 tka      2.31 
#>  4 ran_coef ID        4 tka      1.21 
#>  5 ran_coef ID        5 tka      1.45 
#>  6 ran_coef ID        6 tka      1.14 
#>  7 ran_coef ID        7 tka      0.698
#>  8 ran_coef ID        8 tka      1.34 
#>  9 ran_coef ID        9 tka      6.49 
#> 10 ran_coef ID       10 tka      0.722
#> # … with 26 more rows
glance(fit)
#> # A tibble: 1 x 5
#>    OBJF   AIC   BIC logLik conditionNumber
#>   <dbl> <dbl> <dbl>  <dbl>           <dbl>
#> 1  116.  373.  393.  -179.            18.2

library(ggplot2)
library(dotwhisker)

tidy(fit) %>% dwplot

Created on 2019-04-22 by the reprex package (v0.2.1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants