Taking into account repeated measurements?

Hi, I had a question relating to a situation where I have a data set of subjects for whom measurements are repeated n times - can this currently be taken into accunt in Pumas so that the same random effects are used for (each real) subject? If so how? Would it be as simple as setting the Subject(;id=i) for each repeated measurement for the ith real subject in a Population?

You essentially want a random effect that spans subjects, correct?

Yes, that’s correct, but not all subjects, only a specified subset.

Even if we go “hacky” solutions I think it will be impossible unfortunately. We are aware of the fact that alternative groupings than “ID” would be interesting, but the unfortunate part is that if you bunch them together with the same ID they won’t be allowed to have the same obstimes

A very “hacky” way would probably be to just merge the time series of multiple observations for a single real subject into a single time series and a single Pumas subject, though I don’t imagine that would be very computationally favourable. What if I had the same ID but manually hacked different obstimes (the last idea you mention)?

Is this something you actually need? We could maybe come up with some interesting workarounds even if I’m a bit reluctant to do so because there may be things we have not considered… However, here are some ideas:

You can take each observed time series for subjects in a group (how many are there?) and make it a dependent variable for a “pseudo”-subject. Is there a dynamic model involved? Then you would have to replicate the entire system for each subject

@dynamics begin
  Depot1' = -ka*Depot1
  Central1' = ka*Depot1 - CL/Vc*Central1
  Depot2' = -ka*Depot2
  Central2' = ka*Depot2 - CL/Vc*Central2
  ...
  DepotN' = -ka*DepotN
  CentralN' = ka*DepotN - CL/Vc*CentralN
end
@derived begin
  dv1 ~ Normal(Central1/Vc, sigma)
  dv2 ~ Normal(Central2/Vc, sigma)
  dv3 ~ Normal(Central3/Vc, sigma)
  ...
  dvN ~ Normal(CentralN/Vc, sigma)
end

This could get real expensive real quick, but one subject would essentially wrap all the systems in one “Subject”, so you could still dose into it.

Another solution is (and this depends on many things, hopefully you don’t need to set initial values of the system): you can spread out their obstimes. Say they are all observed at time 0,1,2,…,12. Then place the first in the group at time 0:12, then next at time 20:32 the next at 40:52 and so on. If you don’t think the system is cleared after 20 units of time, you can just add reset events at those time points.

I’m not saying you should, but… and this would only have variability within group

If you wanted individual variability as well you could use occasion variables (remember to say read_pumas(...; covairates_direction=:left) for last observation carried forward (LOCF). Then each occasion would just change at 0, 20, 40, …

I think I need it - I have a data set in which each subject has various dosing protocols applied (around 50 different protocols, system clears quickly). It’s on the order of 20-30 subjects. I do have a SciML dynamical model with a neural network which has 4 variables and I don’t need to set initial conditions. If I followed your suggestion and replicate the entire system, that’d blow up to an ODE system of 100s of variables and the system is quite stiff so not sure how feasible this is. Many thanks for these suggestions, this is good food for thought!

The current best workaround/hack that I found to this is to have random effect distributions be higher dimensional (e.g. if it would be usually 1d, make it n_subjects x 1d) and have a covariate with the numerical id of a real subject, e.g. idx=1 and then in the pre block have par = tvPar * exp(eta[idx]), so only taking that specific random effect for that specific patient. Ideally I wouldn’t have to do this as the random effect dimensionality will blow up with a large number of patients, but works for a small enough number of patients.

I’m not sure that works as expected. Could you share a toy example? Wouldn’t each subject still get a different ebe for the idx’th random effect out of that MvNormal?

    @param begin
        
        ...

        tvp1 ∈ RealDomain()
        tvp2 ∈ RealDomain()
        tvp3 ∈ RealDomain()

        Ω_1 ∈ PDiagDomain(n_subj)
        Ω_2 ∈ PDiagDomain(n_subj)
        Ω_3 ∈ PDiagDomain(n_subj)

        ...

    end

    @covariates begin
        idx
    end

    @random begin
        η_1 ~ MvNormal(Ω_1)
        η_2 ~ MvNormal(Ω_2)
        η_3 ~ MvNormal(Ω_3)
    end

    @pre begin
        p1  = tvp1  * exp(η_1[idx])
        p2  = tvp1  * exp(η_2[idx])
        p3  = tvp1  * exp(η_3[idx])
    end

Here idx is Int in 1:n_subj. Now that you mention it - you are right, it’s not a correct solution to the problem. I can use the same idea and have a VectorDomain for parameters instead of having it in the randeffs, but that only works when I don’t need randeffs (and it would ultimately be more efficient to have it as randeffs I guess).