2017-10-17 24 views
0

J'ai quelques données où je voudrais adapter un modèle non linéaire à chaque sous-ensemble de données en utilisant nls, puis superposer les modèles ajustés sur un graphique des points de données en utilisant ggplot2. Plus précisément, le modèle est de la formeComment tracer la sortie d'un modèle nls dans ggplot2

y~V*x/(K+x) 

que vous pouvez reconnaître comme Michaelis-Menten. Une façon d'y parvenir est d'utiliser geom_smooth, mais si j'utilise geom_smooth, je n'ai aucun moyen de récupérer les coefficients pour l'ajustement du modèle. Alternativement, je pourrais adapter les données en utilisant nls puis les lignes de tracé adaptées en utilisant geom_smooth, mais alors comment puis-je savoir que les courbes qui sont tracées par geom_smooth sont les mêmes que celles données par mon ajustement nls? Je ne peux pas passer les coefficients de mon nls à geom_smooth et lui dire de les utiliser à moins que je puisse obtenir geom_smooth pour utiliser seulement un sous-ensemble des données, alors je peux spécifier les paramètres de départ pour que ça fonctionne, mais ... fois que je l'ai essayé que je reçois une erreur de lecture comme suit:

Aesthetics must be either length 1 or the same as the data (8): x, y, colour 

Voici quelques exemples de données maquillée J'utilise:

Concentration <- c(500.0,250.0,100.0,62.5,50.0,25.0,12.5,5.0, 
        500.0,250.0,100.0,62.5,50.0,25.0,12.5,5.0) 

drug <- c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2) 

rate <- c(1.889220,1.426500,0.864720,0.662210,0.564340,0.343140,0.181120,0.077170, 
      3.995055,3.011800,1.824505,1.397237,1.190078,0.723637,0.381865,0.162771) 

file<-data.frame(Concentration,drug,rate) 

où la concentration sera x dans mon intrigue et taux sera y; la drogue sera la variable de couleur. Si j'écris ce qui suit, j'obtiens cette erreur:

plot <- ggplot(file,aes(x=file[,1],y=file[,3],color=Compound))+geom_point() 

plot<-plot+geom_smooth(data=subset(file,file[,2]==drugNames[i]),method.args=list(formula=y~Vmax*x/(Km+x),start=list(Vmax=coef(models[[i]])[1],Km=coef(models[[i]])[2])),se=FALSE,size=0.5) 

où models [[]] est une liste de paramètres de modèle retournés par nls.

Des idées sur la façon dont je peux sous-représenter une trame de données dans geom_smooth afin que je puisse tracer individuellement des courbes en utilisant les paramètres de départ de mon ajustement nls?

+1

double possible de [ggplot2 fonction de la parcelle avec plusieurs arguments] (https: // stackoverflow.com/questions/42598375/ggplot2-plot-function-with-several-arguments) –

+1

Non lié, mais 'plot',' file' comme noms de variables n'est pas une bonne idée (des fonctions existent avec ces noms). – neilfws

+1

Aussi: cela aiderait à voir le code qui a généré 'models'. – neilfws

Répondre

1

La solution idéale serait de tracer les résultats de nls() en utilisant ggplot, mais voici une solution "rapide et sale" basée sur quelques observations. D'abord, vous pouvez être sûr que si vous utilisez la même formule pour nls() et geom_smooth(method = "nls"), vous obtiendrez les mêmes coefficients. C'est parce que ce dernier appelle le premier. Deuxièmement, en utilisant vos données d'exemple, nls() converge vers les mêmes valeurs de Vmax et Km (différentes pour chaque médicament), indépendamment de la valeur de départ. En d'autres termes, il n'est pas nécessaire de construire des modèles en utilisant des valeurs de départ dans la gamme pour chaque médicament individuel. Un des éléments suivants donnent le même résultat pour le médicament 1 (et de même pour la drogue 2):

library(dplyr) 
# use maximum as start 
df1 %>% 
    filter(drug == 1) %>% 
    nls(rate ~ Vm * Concentration/(K + Concentration), 
     data = ., 
     start = list(K = max(.$Concentration), Vm = max(.$rate))) 

# use minimum as start 
df1 %>% 
    filter(drug == 1) %>% 
    nls(rate ~ Vm * Concentration/(K + Concentration), 
     data = ., 
     start = list(K = min(.$Concentration), Vm = min(.$rate))) 

# use arbitrary values as start 
df1 %>% 
    filter(drug == 1) %>% 
    nls(rate ~ Vm * Concentration/(K + Concentration), 
     data = ., 
     start = list(K = 50, Vm = 2)) 

donc le meilleur moyen de tracer les courbes est simplement de cartographier le médicament à un ggplot esthétique, comme la couleur. Cela va construire des courbes séparées nls à partir des mêmes valeurs de départ et vous pouvez ensuite revenir à nls() si nécessaire pour obtenir les coefficients, sachant que les modèles doivent être les mêmes que l'intrigue.

En utilisant vos données d'exemple file (mais ne l'appelez pas file, je df1):

library(ggplot2) 
df1 <- structure(list(Concentration = c(500, 250, 100, 62.5, 50, 25, 12.5, 5, 
             500, 250, 100, 62.5, 50, 25, 12.5, 5), 
         drug = c(1, 1, 1, 1, 1, 1, 1, 1, 
           2, 2, 2, 2, 2, 2, 2, 2), 
         rate = c(1.88922, 1.4265, 0.86472, 0.66221, 0.56434, 0.34314, 
           0.18112, 0.07717, 3.995055, 3.0118, 1.824505, 1.397237, 
           1.190078, 0.723637, 0.381865, 0.162771)), 
         .Names = c("Concentration", "drug", "rate"), 
         row.names = c(NA, -16L), 
         class = "data.frame") 

# could use e.g. Km = min(df1$Concentration) for start 
# but here we use arbitrary values 
ggplot(df1, aes(Concentration, rate)) + 
    geom_point() + 
    geom_smooth(method = "nls", 
       method.args = list(formula = y ~ Vmax * x/(Km + x), 
           start = list(Km = 50, Vmax = 2)), 
       data = df1, 
       se = FALSE, 
       aes(color = factor(drug))) 

enter image description here

+0

Merci! c'est parfait. désolé pour les erreurs dans mon code ci-dessus – HappyDog