Ich versuche, eine Abbildung zu erstellen, die die Beziehung zwischen Viruskopien und Genomabdeckung (GCC) zeigt. So sehen meine Daten aus:
Zuerst habe ich nur eine lineare Regression gezeichnet, aber meine Vorgesetzten sagten mir, dass dies nicht korrekt sei, und versuchten es mit einer Sigmoidalkurve. Also habe ich das mit geom_smooth gemacht:
library(scales)
ggplot(scatter_plot_new, aes(x = Copies_per_uL, y = Genome_cov, colour = Virus)) +
geom_point() +
scale_x_continuous(trans = log10_trans(), breaks = trans_breaks("log10", function(x) 10^x), labels = trans_format("log10", math_format(10^.x))) +
geom_smooth(method = "gam", formula = y ~ s(x), se = FALSE, size = 1) +
theme_bw() +
theme(legend.position = 'top', legend.text = element_text(size = 10), legend.title = element_text(size = 12), axis.text = element_text(size = 10), axis.title = element_text(size=12), axis.title.y = element_text(margin = margin (r = 10)), axis.title.x = element_text(margin = margin(t = 10))) +
labs(x = "Virus copies/µL", y = "GCC (%)") +
scale_y_continuous(breaks=c(25,50,75,100))
Meine Vorgesetzten sagen jedoch, dass dies auch falsch ist, da die Kurven den Eindruck erwecken, dass GCC über 100% hinausgehen kann, was nicht der Fall ist.
Meine Frage lautet: Wie lässt sich die Beziehung zwischen Viruskopien und GCC am besten veranschaulichen? Ich möchte klarstellen, dass A) niedrige Viruskopien = niedrige GCC, und dass B) nach einer bestimmten Menge von Viren die GCC-Plateaus kopiert.
Ich habe viele verschiedene Methoden recherchiert - GAM, LÖSS, logistisch, stückweise - aber ich weiß nicht, wie ich sagen soll, welche Methode für meine Daten die beste ist.
EDIT: das sind die Daten:
>print(scatter_plot_new)
Subsample Virus Genome_cov Copies_per_uL
1 S1.1_RRAV RRAV 100 92500
2 S1.2_RRAV RRAV 100 95900
3 S1.3_RRAV RRAV 100 92900
4 S2.1_RRAV RRAV 100 4049.54
5 S2.2_RRAV RRAV 96.9935 3809
6 S2.3_RRAV RRAV 94.5054 3695.06
7 S3.1_RRAV RRAV 3.7235 86.37
8 S3.2_RRAV RRAV 11.8186 84.2
9 S3.3_RRAV RRAV 11.0929 95.2
10 S4.1_RRAV RRAV 0 2.12
11 S4.2_RRAV RRAV 5.0799 2.71
12 S4.3_RRAV RRAV 0 2.39
13 S5.1_RRAV RRAV 4.9503 0.16
14 S5.2_RRAV RRAV 0 0.08
15 S5.3_RRAV RRAV 4.4147 0.08
16 S1.1_UMAV UMAV 5.7666 1.38
17 S1.2_UMAV UMAV 26.0379 1.72
18 S1.3_UMAV UMAV 7.4128 2.52
19 S2.1_UMAV UMAV 21.172 31.06
20 S2.2_UMAV UMAV 16.1663 29.87
21 S2.3_UMAV UMAV 9.121 32.82
22 S3.1_UMAV UMAV 92.903 627.24
23 S3.2_UMAV UMAV 83.0314 615.36
24 S3.3_UMAV UMAV 90.3458 632.67
25 S4.1_UMAV UMAV 98.6696 11180
26 S4.2_UMAV UMAV 98.8405 12720
27 S4.3_UMAV UMAV 98.7939 8680
28 S5.1_UMAV UMAV 98.6489 318200
29 S5.2_UMAV UMAV 99.1303 346100
30 S5.3_UMAV UMAV 98.8767 345100
quelle
method.args=list(family=quasibinomial))
die Argumentegeom_smooth()
in Ihren ursprünglichen ggplot-Code einzufügen.se=FALSE
. Immer schön zu zeigen, wie groß die Unsicherheit tatsächlich ist ...Antworten:
Ein anderer Weg, dies zu erreichen, wäre die Verwendung einer Bayes'schen Formulierung. Es kann anfangs etwas schwer sein, aber es macht es in der Regel viel einfacher, Einzelheiten Ihres Problems auszudrücken und bessere Vorstellungen darüber zu bekommen, wo die "Unsicherheit" liegt. ist
Stan ist ein Monte-Carlo-Sampler mit einer relativ einfach zu bedienenden Programmierschnittstelle. Bibliotheken sind für R und andere verfügbar, aber ich verwende hier Python
Wir verwenden wie alle anderen auch ein Sigmoid: Es hat biochemische Motivationen und ist mathematisch sehr einfach zu handhaben. Eine schöne Parametrisierung für diese Aufgabe ist:
Wo
alpha
der Mittelpunkt der Sigmoidkurve definiert (dh wo er 50% kreuzt) undbeta
die Steigung definiert, sind Werte nahe Null flacherUm zu zeigen, wie dies aussieht, können wir Ihre Daten abrufen und zeichnen mit:
Wo
raw_data.txt
enthält die Daten, die Sie angegeben haben, und ich habe die Berichterstattung in etwas Nützlicheres umgewandelt. Die Koeffizienten 5.5 und 3 sehen gut aus und geben eine Darstellung, die den anderen Antworten sehr ähnlich ist:Um diese Funktion mit Stan "anzupassen", müssen wir unser Modell mit einer eigenen Sprache definieren, die eine Mischung aus R und C ++ ist. Ein einfaches Modell wäre so etwas wie:
was hoffentlich OK lautet. Wir haben einen
data
Block, der die Daten definiert, die wir erwarten, wenn wir das Modellparameters
abtasten, die Dinge, die abgetastet werden, undmodel
die Wahrscheinlichkeitsfunktion definiert. Sie weisen Stan an, das Modell zu "kompilieren", was eine Weile dauert, und dann können Sie mit einigen Daten davon abtasten. beispielsweise:arviz
Erleichtert das Ausdrucken von Diagnosediagnosen, und beim Drucken der Anpassung erhalten Sie eine schöne Zusammenfassung der Parameter im R-Stil:Die große Standardabweichung von gibt an
beta
, dass die Daten nicht wirklich viele Informationen zu diesem Parameter liefern. Auch einige der Antworten, die 10+ signifikante Ziffern in ihren Modellanpassungen angeben, übertreiben die Dinge etwasDa in einigen Antworten darauf hingewiesen wurde, dass jeder Virus möglicherweise seine eigenen Parameter benötigt, habe ich das Modell erweitert, um zuzulassen
alpha
undbeta
je nach "Virus" zu variieren. es wird alles ein bisschen fummelig, aber die beiden Viren haben mit ziemlicher Sicherheit unterschiedlichealpha
Werte (dh Sie benötigen mehr Kopien / μl RRAV für die gleiche Abdeckung) und ein Diagramm, das Folgendes zeigt:Die Daten sind die gleichen wie zuvor, aber ich habe eine Kurve für 40 Proben des Seitenzahns gezeichnet.
UMAV
scheint relativ gut bestimmt zu sein,RRAV
könnte jedoch der gleichen Steigung folgen und eine höhere Kopienanzahl erfordern oder eine steilere Steigung und eine ähnliche Kopienanzahl aufweisen. Der Großteil der posterioren Masse benötigt eine höhere Kopienzahl, aber diese Unsicherheit könnte einige der Unterschiede bei anderen Antworten erklären, die andere Dinge findenIch meist Beantwortung dieses als Übung verwendete mein Wissen von Stan zu verbessern, und ich habe einen Jupyter Notebook diesen setzte hier , falls jemand interessiert ist / will dies replizieren.
quelle
(Unter Berücksichtigung der folgenden Kommentare bearbeitet. Vielen Dank an @BenBolker & @WeiwenNg für hilfreiche Eingaben.)
Passen Sie eine partielle logistische Regression an die Daten an. Es eignet sich gut für prozentuale Daten, die zwischen 0 und 100% liegen und in vielen Bereichen der Biologie theoretisch gut begründet sind.
Beachten Sie, dass Sie möglicherweise alle Werte durch 100 teilen müssen, um sie anzupassen, da Programme häufig einen Datenbereich zwischen 0 und 1 erwarten. Um mögliche Probleme zu beheben, die durch die strengen Annahmen der Binomialverteilung in Bezug auf die Varianz verursacht werden, verwenden Sie a, wie von Ben Bolker empfohlen stattdessen Quasibinomialverteilung.
Ich habe einige Annahmen getroffen, die auf Ihrem Code basieren, z. B. dass es zwei Viren gibt, die Sie interessieren und die möglicherweise unterschiedliche Muster aufweisen (dh, es kann eine Wechselwirkung zwischen dem Virentyp und der Anzahl der Kopien geben).
Zunächst passte das Modell:
Wenn Sie den p-Werten vertrauen, deutet die Ausgabe nicht darauf hin, dass sich die beiden Viren signifikant unterscheiden. Dies steht im Gegensatz zu den Ergebnissen von @ NickCox, obwohl wir unterschiedliche Methoden angewendet haben. Mit 30 Datenpunkten wäre ich sowieso nicht sehr zuversichtlich.
Zweitens ist die Handlung:
Es ist nicht schwer, einen Weg zu finden, um die Ausgabe selbst zu visualisieren, aber es scheint ein ggPredict-Paket zu geben, das die meiste Arbeit für Sie erledigt (kann nicht dafür bürgen, ich habe es selbst nicht ausprobiert). Der Code sieht ungefähr so aus:Update: Ich empfehle den Code oder die ggPredict-Funktion nicht mehr allgemeiner. Nach dem Ausprobieren stellte ich fest, dass die eingezeichneten Punkte nicht genau die Eingabedaten widerspiegeln, sondern aus bizarren Gründen geändert wurden (einige der eingezeichneten Punkte lagen über 1 und unter 0). Daher empfehle ich, es selbst zu codieren, obwohl das mehr Arbeit ist.
quelle
family=quasibinomial()
diese Option, um die Warnung (und die zugrunde liegenden Probleme mit zu strengen Varianzannahmen) zu vermeiden. Nehmen Sie den Rat von @ mkt bezüglich des anderen Problems an.Dies ist keine andere Antwort als @mkt, aber insbesondere Grafiken passen nicht in einen Kommentar. Ich habe zuerst eine logistische Kurve in Stata (nach dem Protokollieren des Prädiktors) an alle Daten angepasst und diese Grafik erhalten
Eine Gleichung lautet
100
invlogit
(-4,192654 + 1,880951log10
(Copies
))Im einfachsten Szenario, in dem ein Virus eine Indikatorvariable definiert, passe ich die Kurven für jeden Virus separat an. Hier für den Datensatz ist ein Stata-Skript:
Dies drängt auf einen winzigen Datensatz, aber der P-Wert für den Virus scheint die Anpassung von zwei Kurven gemeinsam zu unterstützen.
quelle
Probieren Sie die Sigmoid- Funktion aus. Es gibt viele Formulierungen dieser Form, einschließlich einer logistischen Kurve. Hyperbolischer Tangens ist eine weitere beliebte Wahl.
Angesichts der Handlungen kann ich auch eine einfache Sprungfunktion nicht ausschließen. Ich befürchte, Sie werden nicht in der Lage sein, zwischen einer Sprungfunktion und einer beliebigen Anzahl von Sigmoidspezifikationen zu unterscheiden. Sie haben keine Beobachtungen, bei denen Ihr Prozentsatz im Bereich von 50% liegt. Daher kann die einfache Schrittformulierung die sparsamste Wahl sein, die nicht schlechter abschneidet als komplexere Modelle
quelle
Hier sind die 4PL (4 parameter logistic) -Fits, sowohl eingeschränkt als auch nicht eingeschränkt, mit der Gleichung gemäß CA Holstein, M. Griffin, J. Hong, PD Sampson, "Statistische Methode zur Bestimmung und zum Vergleich der Nachweisgrenzen von Bioassays", Anal . Chem. 87 (2015) 9795 & ndash; 9801. Die 4PL-Gleichung ist in beiden Figuren gezeigt und die Parameterbedeutungen sind wie folgt: a = untere Asymptote, b = Steigungsfaktor, c = Wendepunkt und d = obere Asymptote.
Abbildung 1 beschränkt a auf 0% und d auf 100%:
Abbildung 2 unterliegt keinen Einschränkungen für die 4 Parameter in der 4PL-Gleichung:
Das hat Spaß gemacht, ich mache keinen Vorwand, irgendetwas Biologisches zu wissen, und es wird interessant sein zu sehen, wie sich alles einpendelt!
quelle
Ich habe die Daten aus Ihrem Streudiagramm extrahiert und meine Gleichungssuche ergab eine logistische Gleichung mit drei Parametern als guten Kandidaten: "y = a / (1,0 + b * exp (-1,0 * c * x))", wobei " x "ist die logarithmische Basis 10 für Ihr Diagramm. Die angepassten Parameter waren a = 9.0005947126706630E + 01, b = 1.2831794858584102E + 07 und c = 6.6483431489473155E + 00. Eine Anpassung der (log 10 x) Originaldaten sollte bei erneuter Anpassung zu ähnlichen Ergebnissen führen die ursprünglichen Daten unter Verwendung meiner Werte als anfängliche Parameterschätzungen. Meine Parameterwerte ergeben R-Quadrat = 0,983 und RMSE = 5,625 für die extrahierten Daten.
BEARBEITEN: Nachdem die Frage so bearbeitet wurde, dass sie die tatsächlichen Daten enthält, ist hier eine grafische Darstellung unter Verwendung der obigen 3-Parameter-Gleichung und der anfänglichen Parameterschätzungen.
quelle
Da ich meine große Klappe über Heaviside aufmachen musste, sind hier die Ergebnisse. Ich habe den Übergangspunkt auf log10 (viruscopies) = 2.5 gesetzt. Dann berechnete ich die Standardabweichungen der beiden Hälften des Datensatzes - das heißt, der Heaviside geht davon aus, dass die Daten auf beiden Seiten alle Ableitungen = 0 haben.
Rechte Seite std dev = 4,76
linke Seite std dev = 7,72
Da sich herausstellt, dass in jeder Charge 15 Proben enthalten sind, ist der Standard-Gesamtwert der Mittelwert oder 6,24.
Unter der Annahme, dass das in anderen Antworten angegebene "RMSE" insgesamt "RMS-Fehler" ist, scheint die Heaviside-Funktion mindestens so gut zu funktionieren wie die meisten "Z-Kurven" -Passungen (aus der fotografischen Antwortnomenklatur entlehnt), wenn nicht sogar besser als diese Hier.
bearbeiten
Nutzloses Diagramm, aber in Kommentaren angefordert:
quelle