lotri 1.0.5

New features

lotri({
  iov.cl1 + iov.v1 ~ c(0.1,
                       0.01, 0.2)
  iov.cl2 + iov.v2 ~ same()
  iov.cl3 + iov.v3 ~ same()
})

This is one estimated 2x2 covariance shared by three blocks, which is how inter-occasion variability is parameterized when every occasion draws its own random effects from one shared covariance – and it is what lets those random effects be correlated.

same() repeats the immediately preceding block under new names and takes no arguments. A further same() repeats that same original block rather than the copy, the way NONMEM chains SAME. It works with a condition (iov.cl2 + iov.v2 ~ same() | occ), it inherits the fixed flags of the block it repeats, and it composes with the cnd(same = n) nesting property that lotriSep() uses.

lotri({
  tka <- 0.45
  tcl <- c(0, 1, 10)
  eta.cl + eta.v ~ c(0.1,
                     0.01, 0.2)
  prior(tka) ~ dnorm(0, 10)
  prior(tcl) ~ dlnorm(1, 0.5)
  prior(eta.cl, eta.v) ~ lkjCorr(2)
})

Because the statement names its target, prior lines may be given anywhere in the block. Priors may be put on population estimates, on individual etas, and on whole covariance blocks (with the matrix-valued distributions like lkjCorr() and invWishart()).

Every distribution has three accepted spellings: the R name where R parameterizes it the same way ‘Stan’ does (dnorm(), dlnorm(), dgamma()), the camelCase name (invWishart(), lkjCorr(), studentT()), and the ‘Stan’ name itself (inv_wishart(), lkj_corr(), student_t()). The canonical spelling, which is what is stored and printed back, is the R one where there is a faithful one and the camelCase one otherwise. Both positional and named arguments work. lotri validates the distribution name, its arity, and its support against the parameter’s bounds; it does not generate any ‘Stan’ code.

lotri({
  eta.cl + eta.v ~ c(0.1,
                     0.01, 0.2)
  prior(eta.cl, eta.v) ~ invWishart(4)
})

It works on a 1x1 block too (an inverse Wishart of dimension one is an inverse gamma), and an improper nu <= p - 1 is an error.

lotri({
  eta.cl ~ 0.3
  eta.v ~ 0.1
  om.eta.cl ~ 0.01
  om.eta.v ~ 0.04
})

The omega itself is untouched; only the prior is added. Correlated omega priors work the same way, including the per row line form. An om. name has to match a real between subject variability and never creates one. prior(om.eta.cl) and prior(eta.cl) mean the same thing; the om. spelling exists so the shorthand has a name to put on the left of a ~, since eta.cl ~ ... already means the omega value.

Degrees of freedom and a normal prior are alternative ways of putting a prior on an omega, so a model that gives both is an error.

lotri({
  tka <- 1
  tcl <- 3
  tv <- 4
  tka ~ 4          # tka ~ N(0, sd=2)
  tcl + tv ~ c(1,  # (tcl, tv) ~ MVN(0, Sigma)
               0.01, 1)
})

All of the matrix spellings work here, including the per row line form (tcl ~ 1; tv ~ c(0.01, 1)) and the sd(), var(), cor(), cov() and chol() transformations. The <- value remains the initial estimate; it is not the prior mean. An uncorrelated block simply becomes independent normal priors. A zero variance is an error.

Note this changes behavior: lotri({b <- 3; b ~ 0.4}) used to be a “duplicated parameter” error and is now a normal prior on b. A name that is not an estimate still specifies an eta as before.

lotri({
  tka <- 0.45
  prior(tka) ~ 0.1          # dnorm(0.45, sqrt(0.1))
  prior(tcl, tv) ~ c(1,     # multivariate, centered on the estimates
                     0.01, 1)
})

Every matrix spelling works here as it does bare, including the per row line form, so a covariance can be built up a line at a time:

lotri({
  tcl <- 3
  tv <- 4
  prior(tcl) ~ 1
  prior(tv) ~ c(0.001, 1)   # same 2x2 as `tcl ~ 1; tv ~ c(0.001, 1)`
})

An uncorrelated group becomes independent normal priors, and the mean is what the model already says. Note the line form is the one place a prior line is not order independent, since a row leans on the line before it. The point is that a bare ~ cannot be used everywhere – piping onto a model reads tka ~ 0.1 as changing the estimate – so the prior() flag gives the shorthand a spelling that works when piping too.

A namespaced distribution such as stats::dnorm(0, 1) is now an error rather than being evaluated as a variance.

lotri({
  eta.cl + eta.v ~ c(0.1,
                     0.01, 0.2)
  prior(eta.cl, eta.v) ~ dnorm(0, 0.1)
})

The two names must covary with each other but need not be the model’s entire connected block – prior(eta.cl, eta.v) works even when a third, correlated eta is also in the block, unlike a whole-block prior which still requires naming every member. prior(om.eta.cl, om.eta.v) ~ ... is accepted identically. A block cannot carry both a whole-block invWishart()/multiNormal() prior and a marginal prior on one of its own cells – these remain alternatives, not additions.

Bug fixes

lotri 1.0.4

lotri 1.0.3

lotri 1.0.2

lotri 1.0.1

lotri 1.0.0

Before you could specify matrices as:

m <- lotri({
  a + b ~ c(1,
            0.5, 1)
})

Now you can specify per row as:

m <- lotri({
  a ~ 1
  b ~ c(0.5, 1)
})

This form is now the default when converting from a matrix to a lotri expression. In addition if the matrix is large enough (by default a 5x5 matrix), these would be named when changing them to an expression:

m <- lotri({
  a ~ c(a=1)
  b ~ c(a=0.5, b=1)
  c ~ c(a=0.5, b=0.5, c=1)
  d ~ c(a=0.5, b=0.5, c=0.5, d=1)
  e ~ c(a=0.5, b=0.5, c=0.5, d=1,
        e=1)
})

This way changing to an R parsed expression will be rendered in a more human readable format.

You can change the deparsing options that are used by default with lotri with options(lotri.plusNames=TRUE) which prefers the a+b+c syntax when deparsing. Otherwise, the line format is used by default. The dimension number before naming the values in the line-format can be controlled with options(lotri.nameEst=2) or some other dimension.

lotri 0.4.4

lotri 0.4.3

lotri 0.4.2

lotri 0.4.0

lotri 0.3.1

lotri 0.2.2

lotri 0.2.1

lotri 0.1.1