Régression à effets mixtes non linéaires dans R

14

Étonnamment, je n'ai pas pu trouver de réponse à la question suivante en utilisant Google:

J'ai quelques données biologiques de plusieurs individus qui montrent un comportement de croissance à peu près sigmoïde dans le temps. Je souhaite donc le modéliser en utilisant une croissance logistique standard

P(t) = k*p0*exp(r*t) / (k+p0*(exp(r*t)-1))

avec p0 étant la valeur de départ à t = 0, k étant la limite asymptotique à t-> infini et r étant la vitesse de croissance. Pour autant que je puisse voir, je peux facilement modéliser cela en utilisant nls (manque de compréhension de ma part: pourquoi ne puis-je pas modéliser quelque chose de similaire en utilisant la régression logit standard en ajustant le temps et les données? EDIT: Merci Nick, apparemment les gens le font par exemple pour proportions, mais rarement http://www.stata-journal.com/article.html?article=st0147 . La prochaine question sur cette tangente serait de savoir si le modèle peut éventuellement gérer des valeurs aberrantes> 1).

Maintenant, je souhaite autoriser certains effets fixes (principalement catégoriques) et aléatoires (un ID individuel et éventuellement aussi un ID d'étude) sur les trois paramètres k, p0 et r. Nlme est-il la meilleure façon de procéder? Le modèle SSlogis semble raisonnable pour ce que j'essaie de faire, est-ce correct? L'un des modèles suivants est-il un modèle raisonnable pour commencer? Je n'arrive pas à obtenir les bonnes valeurs de départ et update () ne semble fonctionner que pour des effets aléatoires, pas fixes - des indices?

nlme(y ~ k*p0*exp(r*t) / (k+p0*(exp(r*t)-1)), ## not working at all (bad numerical properties?)
            data = data,
            fixed = k + p0 + r ~ var1 + var2,
            random = k + p0 + r ~ 1|UID,
            start = c(p0=1, k=100, r=1))

nlme(y ~ SSlogis(t, Asym, xmid, scal), ## not working, as start= is inappropriate
            data = data,
            fixed = Asym + xmid + scal ~ var1 + var2, ## works fine with ~ 1
            random = Asym + xmid + scal ~ 1|UID,
            start = getInitial(y ~ SSlogis(Dauer, Asym, xmid, scal), data = data))

Comme je suis nouveau dans les modèles mixtes non linéaires en particulier et les modèles non linéaires en général, j'apprécierais quelques recommandations de lecture ou des liens vers des tutoriels / FAQ avec des questions pour les débutants.

Rob Hall
la source
2
Si vous considérez k comme connu, vous pouvez faire évoluer vos populations de P / k. Si k est quelque chose à estimer, cela signifie à lui seul que votre problème n'est pas une régression logit standard.
Nick Cox
1
Merci Nick. Oui, au final, je pense que k doit être estimé et inclus dans la régression. Mon intérêt pour l'utilisation de la régression logit était purement académique. J'ai pensé que cela pourrait être un bon modèle pour commencer avant de passer à la modélisation non linéaire, mais je n'ai pas pu trouver d'exemples de régression logit pour les données non binaires à l'aide de Google. Je me demandais s'il y avait une raison (par exemple, des hypothèses de distribution sur les erreurs) qui en fait une mauvaise idée d'utiliser par exemple glmer avec un lien logit avec des données continues.
Rob Hall
3
La modélisation logit pour les réponses qui sont des proportions continues existe depuis un certain temps, mais n'est apparemment pas bien connue. Voir par exemple Baum dans stata-journal.com/sjpdf.html?articlenum=st0147 Néanmoins, ce n'est pas votre situation. Je ne peux pas commenter les implémentations R.
Nick Cox
Merci Nick pour ce lien intéressant - qui clarifie certaines choses pour moi. Malheureusement, il semble que je ne puisse pas encore voter pour votre réponse. (Dans le cas où les gens ont du mal à accéder au lien direct, ce qui suit a fonctionné pour moi: stata-journal.com/article.html?article=st0147 )
Rob Hall
1
La croissance logistique implique une courbe montante monotone. Si les données ne correspondent pas, vous obtiendrez un mauvais ajustement ou le logiciel ne jouera pas, selon exactement ce que vous faites.
Nick Cox

Réponses:

12

Je voulais partager certaines des choses que j'ai apprises depuis que j'ai posé cette question. nlme semble être un moyen raisonnable de modéliser des effets mixtes non linéaires dans R. Commencez avec un modèle de base simple:

library(nlme)
data <- groupedData(y ~ t | UID, data=data) ## not strictly necessary
initVals <- getInitial(y ~ SSlogis(t, Asym, xmid, scal), data = data)
baseModel<- nlme(y ~ SSlogis(t, Asym, xmid, scal),
    data = data,
    fixed = list(Asym ~ 1, xmid ~ 1, scal ~ 1),
    random = Asym + xmid + scal ~ 1|UID,
    start = initVals
)

Utilisez ensuite la mise à jour pour augmenter la complexité du modèle. Le paramètre de démarrage est légèrement délicat à travailler, il peut prendre un peu de bricolage pour comprendre l'ordre. Notez comment le nouvel effet fixe pour var1 sur Asym suit l'effet fixe régulier pour Asym.

 nestedModel <- update(baseModel, fixed=list(Asym ~ var1, xmid ~ 1, scal ~ 1), start = c(fixef(baseModel)[1], 0, fixef(baseModel)[2], fixef(baseModel)[3]))

lme4 semblait plus robuste contre les valeurs aberrantes de mon ensemble de données et semblait offrir une convergence plus fiable pour les modèles plus complexes. Cependant, il semble que l'inconvénient soit que les fonctions de vraisemblance pertinentes doivent être spécifiées manuellement. Ce qui suit est le modèle de croissance logistique avec un effet fixe de var1 (binaire) sur Asym. Vous pouvez ajouter des effets fixes sur xmid et scal de la même manière. Notez l'étrange façon de spécifier le modèle en utilisant une double formule comme résultat ~ effets fixes ~ effets aléatoires.

library(lme4) ## careful loading nlme and lme4 concurrently
customLogitModel <- function(t, Asym, AsymVar1, xmid, scal) {
    (Asym+AsymVar1*var1)/(1+exp((xmid-t)/scal))
}

customLogitModelGradient <- deriv(
    body(customLogitModel)[[2]], 
    namevec = c("Asym", "AsymVar1", "xmid", "scal"), 
    function.arg=customLogitModel
)

## find starting parameters
initVals <- getInitial(y ~ SSlogis(t, Asym, xmid, scal), data = data)

# Fit the model
model <- nlmer(
    y ~ customLogitModelGradient(t=t, Asym, AsymVar1, xmid, scal, var1=var) ~ 
    # Random effects with a second ~
    (Asym | UID) + (xmid | UID) + (scal | UID), 
    data = data, 
    start = c(Asym=initVals[1], AsymVar1=0, xmid=initVals[2], scal=initVals[3])
)
Rob Hall
la source
1
Merci Rob pour ton message, c'est en fait exactement ce que j'essaie de faire avec mes données. Je ne comprends pas ce qui est var1 dans le nestedModel sur Asym et comment vous l'avez calculé?
Ceci est juste un exemple sur la façon d'inclure l'effet d'une variable sur Asym: "Ce qui suit est le modèle de croissance logistique avec un effet fixe de var1 (binaire) sur Asym." Par exemple, vous avez la variable "Treated" qui a deux valeurs 0 et 1, substituez donc "Treated" à "var1".
PA6OTA