Estoy tratando de crear una figura que muestre la relación entre las copias virales y la cobertura del genoma (CCG). Así es como se ven mis datos:
Al principio, acabo de trazar una regresión lineal, pero mis supervisores me dijeron que eso era incorrecto y que probé una curva sigmoidea. Así que hice esto usando geom_smooth:
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))
Sin embargo, mis supervisores dicen que esto también es incorrecto porque las curvas hacen que parezca que GCC puede superar el 100%, lo que no puede.
Mi pregunta es: ¿cuál es la mejor manera de mostrar la relación entre las copias de virus y el CCG? Quiero dejar en claro que A) copias bajas de virus = bajo CCG, y que B) después de una cierta cantidad de virus copia las mesetas de CCG.
He investigado muchos métodos diferentes: GAM, LOESS, logístico, por partes, pero no sé cómo saber cuál es el mejor método para mis datos.
EDITAR: estos son los datos:
>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
fuente
method.args=list(family=quasibinomial))
los argumentosgeom_smooth()
en su código ggplot original.se=FALSE
. Siempre es bueno mostrarle a la gente cuán grande es la incertidumbre ...Respuestas:
Otra forma de hacerlo sería utilizar una formulación bayesiana, puede ser un poco pesado para empezar, pero tiende a hacer que sea mucho más fácil expresar detalles de su problema, así como obtener mejores ideas sobre dónde está la "incertidumbre". es
Stan es una muestra de Monte Carlo con una interfaz programática relativamente fácil de usar, las bibliotecas están disponibles para R y otros, pero estoy usando Python aquí
Usamos un sigmoide como todos los demás: tiene motivaciones bioquímicas además de ser matemáticamente muy conveniente para trabajar. Una buena parametrización para esta tarea es:
donde
alpha
define el punto medio de la curva sigmoidea (es decir, donde cruza el 50%) ybeta
define la pendiente, los valores más cercanos a cero son más planospara mostrar cómo se ve esto, podemos obtener sus datos y trazarlos con:
donde
raw_data.txt
contiene los datos que proporcionó y transformé la cobertura en algo más útil. los coeficientes 5.5 y 3 se ven bien y dan una gráfica muy parecida a las otras respuestas:para "ajustar" esta función usando Stan necesitamos definir nuestro modelo usando su propio lenguaje que es una mezcla entre R y C ++. un modelo simple sería algo así como:
que con suerte dice OK. Tenemos un
data
bloque que define los datos que esperamos cuando muestreamos el modelo,parameters
definimos las cosas que se muestrean ymodel
define la función de probabilidad. Le dice a Stan que "compile" el modelo, lo que lleva un tiempo, y luego puede tomar muestras de él con algunos datos. por ejemplo:arviz
hace que las gráficas de diagnóstico sean fáciles, mientras que la impresión del ajuste le brinda un buen resumen de parámetros de estilo R:La gran desviación estándar
beta
indica que los datos realmente no proporcionan mucha información sobre este parámetro. También algunas de las respuestas que dan más de 10 dígitos significativos en sus ajustes de modelo exageran un poco las cosasDebido a que algunas respuestas señalaron que cada virus podría necesitar sus propios parámetros, extendí el modelo para permitir
alpha
ybeta
variar según el "Virus". todo se vuelve un poco complicado, pero los dos virus casi con seguridad tienenalpha
valores diferentes (es decir, necesita más copias / μL de RRAV para la misma cobertura) y un gráfico que muestra esto es:los datos son los mismos que antes, pero dibujé una curva para 40 muestras de la parte posterior.
UMAV
parece relativamente bien determinado, mientras queRRAV
podría seguir la misma pendiente y necesitar un mayor conteo de copias, o tener una pendiente más pronunciada y un conteo de copias similar. la mayor parte de la masa posterior depende de la necesidad de un mayor número de copias, pero esta incertidumbre podría explicar algunas de las diferencias en otras respuestas para encontrar cosas diferentesSobre todo solía responder esto como un ejercicio para mejorar mi conocimiento de Stan, y he puesto un cuaderno Jupyter de esto aquí en caso de que alguien esté interesado / quiera replicar esto.
fuente
(Editado teniendo en cuenta los comentarios a continuación. Gracias a @BenBolker y @WeiwenNg por sus útiles comentarios).
Ajuste una regresión logística fraccional a los datos. Se adapta bien a los datos porcentuales que están delimitados entre 0 y 100% y están bien justificados teóricamente en muchas áreas de la biología.
Tenga en cuenta que es posible que tenga que dividir todos los valores por 100 para ajustarlos, ya que los programas frecuentemente esperan que los datos oscilen entre 0 y 1. Y, como recomienda Ben Bolker, para abordar los posibles problemas causados por los supuestos estrictos de la distribución binomial con respecto a la varianza, use un distribución cuasibinomial en su lugar.
He hecho algunas suposiciones basadas en su código, como que hay 2 virus que le interesan y que pueden mostrar patrones diferentes (es decir, puede haber una interacción entre el tipo de virus y la cantidad de copias).
Primero, el modelo se ajusta:
Si confía en los valores p, el resultado no sugiere que los dos virus difieran significativamente. Esto contrasta con los resultados de @ NickCox a continuación, aunque utilizamos diferentes métodos. No estaría muy seguro de ninguna manera con 30 puntos de datos.
En segundo lugar, la trama:
No es difícil codificar una forma de visualizar la salida usted mismo, pero parece haber un paquete ggPredict que hará la mayor parte del trabajo por usted (no puedo garantizarlo, no lo he probado yo mismo). El código se verá más o menos así:Actualización: ya no recomiendo el código o la función ggPredict de manera más general. Después de probarlo, descubrí que los puntos trazados no reflejan exactamente los datos de entrada, sino que se cambian por alguna extraña razón (algunos de los puntos trazados estaban por encima de 1 y por debajo de 0). Así que recomiendo codificarlo usted mismo, aunque eso es más trabajo.
fuente
family=quasibinomial()
para evitar la advertencia (y los problemas subyacentes con suposiciones de varianza demasiado estrictas). Siga los consejos de @ mkt sobre el otro problema.Esta no es una respuesta diferente de @mkt, pero los gráficos en particular no caben en un comentario. Primero ajusto una curva logística en Stata (después de registrar el predictor) a todos los datos y obtengo este gráfico
Una ecuación es
100
invlogit
(-4,192654 + 1,880951log10
(Copies
))Ahora ajusto las curvas por separado para cada virus en el escenario más simple de virus que define una variable indicadora. Aquí para el registro hay un script Stata:
Esto está presionando mucho en un pequeño conjunto de datos, pero el valor P para virus parece ser compatible con el ajuste de dos curvas juntas.
fuente
Prueba la función sigmoidea . Hay muchas formulaciones de esta forma, incluida una curva logística. La tangente hiperbólica es otra opción popular.
Dadas las tramas, tampoco puedo descartar una función de paso simple. Me temo que no podrá diferenciar entre una función de paso y cualquier cantidad de especificaciones sigmoideas. No tiene ninguna observación en la que su porcentaje esté en el rango del 50%, por lo que la formulación de pasos simples puede ser la opción más parsimoinosa que no funciona peor que los modelos más complejos.
fuente
Aquí están los ajustes 4PL (logística de 4 parámetros), tanto restringidos como no restringidos, con la ecuación según CA Holstein, M. Griffin, J. Hong, PD Sampson, "Método estadístico para determinar y comparar límites de detección de bioensayos", Anal . Chem 87 (2015) 9795-9801. La ecuación 4PL se muestra en ambas figuras y los significados de los parámetros son los siguientes: a = asíntota inferior, b = factor de pendiente, c = punto de inflexión yd = asíntota superior.
La Figura 1 restringe a a igual a 0% yd igual a 100%:
La Figura 2 no tiene restricciones en los 4 parámetros en la ecuación 4PL:
¡Esto fue divertido, no pretendo saber nada biológico y será interesante ver cómo se soluciona todo!
fuente
Extraje los datos de su diagrama de dispersión, y mi búsqueda de ecuaciones arrojó una ecuación de tipo logístico de 3 parámetros como un buen candidato: "y = a / (1.0 + b * exp (-1.0 * c * x))", donde " x "es la base de registro 10 por su parcela. Los parámetros ajustados fueron a = 9.0005947126706630E + 01, b = 1.2831794858584102E + 07 yc = 6.6483431489473155E + 00 para mis datos extraídos, un ajuste de los datos originales (log 10 x) debería producir resultados similares si vuelve a ajustar los datos originales usando mis valores como estimaciones de parámetros iniciales. Los valores de mis parámetros están produciendo R-cuadrado = 0.983 y RMSE = 5.625 en los datos extraídos.
EDITAR: ahora que la pregunta se ha editado para incluir los datos reales, aquí hay un gráfico que utiliza la ecuación de 3 parámetros y las estimaciones de parámetros iniciales anteriores.
fuente
Como tuve que abrir mi boca grande sobre Heaviside, aquí están los resultados. Configuré el punto de transición a log10 (viruscopies) = 2.5. Luego calculé las desviaciones estándar de las dos mitades del conjunto de datos, es decir, el Heaviside está asumiendo que los datos en ambos lados tienen todas las derivadas = 0.
Dev. Estándar del lado derecho = 4.76
Dev. Estándar del lado izquierdo = 7.72
Como resulta que hay 15 muestras en cada lote, el dev estándar es la media, o 6.24.
Suponiendo que el "RMSE" citado en otras respuestas es "error RMS" en general, la función Heaviside parecería funcionar al menos tan bien, si no mejor, que la mayoría de la "curva Z" (tomada de la nomenclatura de respuesta fotográfica) aquí.
editar
Gráfico inútil, pero solicitado en los comentarios:
fuente