Estou tentando criar uma figura que mostra a relação entre cópias virais e cobertura do genoma (GCC). É assim que meus dados são:
No começo, acabei de traçar uma regressão linear, mas meus supervisores disseram que estava incorreto e que tentava uma curva sigmoidal. Então eu fiz isso 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))
No entanto, meus supervisores dizem que isso também está incorreto porque as curvas fazem com que o GCC possa ultrapassar 100%, o que não pode.
Minha pergunta é: qual é a melhor maneira de mostrar a relação entre cópias de vírus e o GCC? Quero deixar claro que A) baixa quantidade de vírus = baixo GCC e que B) após uma certa quantidade de vírus copia os platôs do GCC.
Eu pesquisei vários métodos diferentes - GAM, LOESS, logístico, por partes - mas não sei dizer qual é o melhor método para meus dados.
EDIT: estes são os dados:
>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
fonte
method.args=list(family=quasibinomial))
os argumentosgeom_smooth()
no seu código ggplot original.se=FALSE
. Sempre bom para mostrar às pessoas o quão grande a incerteza na verdade é ...Respostas:
Outra maneira de fazer isso seria usar uma formulação bayesiana, pode ser um pouco pesada, mas tende a facilitar a expressão de detalhes específicos do seu problema, além de obter melhores idéias sobre onde está a "incerteza". é
Stan é um amostrador de Monte Carlo com uma interface programática relativamente fácil de usar, bibliotecas estão disponíveis para R e outras, mas estou usando Python aqui
usamos um sigmóide como todo mundo: ele tem motivações bioquímicas e é matematicamente muito conveniente de se trabalhar. uma boa parametrização para esta tarefa é:
onde
alpha
define o ponto médio da curva sigmóide (ou seja, onde cruza 50%) ebeta
define a inclinação, os valores mais próximos de zero são mais planospara mostrar como é isso, podemos extrair seus dados e plotá-los com:
onde
raw_data.txt
contém os dados que você forneceu e eu transformei a cobertura em algo mais útil. os coeficientes 5.5 e 3 têm uma boa aparência e apresentam um gráfico muito parecido com as outras respostas:Para "ajustar" essa função usando Stan, precisamos definir nosso modelo usando sua própria linguagem, que é uma mistura entre R e C ++. um modelo simples seria algo como:
que esperançosamente lê OK. temos um
data
bloco que define os dados que esperamos quandoparameters
amostramos o modelo, definimos as coisas que são amostradas emodel
define a função de probabilidade. Você diz a Stan para "compilar" o modelo, o que leva um tempo, e então você pode fazer uma amostra dele com alguns dados. por exemplo:arviz
facilita as plotagens de diagnóstico, enquanto imprimir o ajuste fornece um resumo resumido dos parâmetros no estilo R:o grande desvio padrão em
beta
diz que os dados realmente não fornecem muita informação sobre esse parâmetro. Além disso, algumas das respostas que dão mais de 10 dígitos significativos em seus ajustes de modelo estão exagerando um pouco as coisasporque algumas respostas observaram que cada vírus pode precisar de seus próprios parâmetros, estendi o modelo para permitir
alpha
ebeta
variar de acordo com o "vírus". tudo fica um pouco complicado, mas os dois vírus quase certamente têmalpha
valores diferentes (ou seja, você precisa de mais cópias / μL de RRAV para a mesma cobertura) e um gráfico que mostra isso é:os dados são os mesmos de antes, mas desenhei uma curva para 40 amostras da parte posterior.
UMAV
parece relativamente bem determinado, emboraRRAV
possa seguir a mesma inclinação e precisar de uma contagem mais alta de cópias ou ter uma inclinação mais acentuada e uma contagem de cópias semelhante. a maior parte da massa posterior está precisando de uma contagem mais alta de cópias, mas essa incerteza pode explicar algumas das diferenças em outras respostas para encontrar coisas diferentesEu costumava responder isso como um exercício para melhorar meu conhecimento de Stan, e coloquei um caderno Jupyter disso aqui , caso alguém esteja interessado / queira replicar isso.
fonte
(Editado levando em consideração os comentários abaixo. Agradecemos a @BenBolker & @WeiwenNg pela contribuição útil.)
Ajuste uma regressão logística fracionária aos dados. É adequado para dados percentuais que são delimitados entre 0 e 100% e é justificado teoricamente em muitas áreas da biologia.
Observe que você pode ter que dividir todos os valores por 100 para ajustá-lo, pois os programas freqüentemente esperam que os dados variem entre 0 e 1. E, como recomenda Ben Bolker, para resolver possíveis problemas causados pelas estritas premissas da distribuição binomial em relação à variação, use um distribuição quase-binomial.
Fiz algumas suposições com base no seu código, como a existência de 2 vírus nos quais você está interessado e eles podem mostrar padrões diferentes (por exemplo, pode haver uma interação entre o tipo de vírus e o número de cópias).
Primeiro, o modelo se encaixava:
Se você confiar nos valores p, a saída não sugere que os dois vírus diferem significativamente. Isso contrasta com os resultados do @ NickCox abaixo, embora tenhamos usado métodos diferentes. De qualquer maneira, não ficaria muito confiante com 30 pontos de dados.
Segundo, a plotagem:
Não é difícil codificar uma maneira de visualizar a saída você mesmo, mas parece haver um pacote ggPredict que fará a maior parte do trabalho para você (não posso atestar, não tentei por mim mesmo). O código será parecido com:Atualização: não recomendo mais o código ou a função ggPredict de maneira mais geral. Depois de experimentar, descobri que os pontos plotados não refletem exatamente os dados de entrada, mas são alterados por algum motivo bizarro (alguns dos pontos plotados estavam acima de 1 e abaixo de 0). Portanto, recomendo codificá-lo você mesmo, embora isso seja mais trabalhoso.
fonte
family=quasibinomial()
para evitar o aviso (e os problemas subjacentes com premissas de variação muito estritas). Siga o conselho de @ mkt sobre o outro problema.Esta não é uma resposta diferente da @mkt, mas os gráficos em particular não cabem em um comentário. Primeiro ajustei uma curva logística no Stata (após registrar o preditor) em todos os dados e obtive esse gráfico
Uma equação é
100
invlogit
(-4,192654 + 1,880951log10
(Copies
))Agora, ajusto curvas separadamente para cada vírus no cenário mais simples de definição de uma variável indicadora. Aqui para o registro está um script Stata:
Isso está pressionando fortemente um conjunto de dados minúsculo, mas o valor P para vírus parece favorável ao ajuste de duas curvas em conjunto.
fonte
Tente a função sigmóide . Existem muitas formulações dessa forma, incluindo uma curva logística. A tangente hiperbólica é outra escolha popular.
Dadas as parcelas, também não posso descartar uma função simples de etapa. Receio que você não consiga diferenciar entre uma função step e qualquer número de especificações sigmóides. Você não tem nenhuma observação em que sua porcentagem está na faixa de 50%; portanto, a formulação de etapas simples pode ser a escolha mais parcimoniosa que não apresenta desempenho pior do que modelos mais complexos
fonte
Aqui estão os ajustes 4PL (4 parâmetros logísticos), restritos e irrestritos, com a equação conforme CA Holstein, M. Griffin, J. Hong, PD Sampson, "Método Estatístico para Determinar e Comparar Limites de Detecção de Bioensaios", Anal . Chem. 87 (2015) 9795-9801. A equação 4PL é mostrada nas duas figuras e os significados dos parâmetros são os seguintes: a = assíntota inferior, b = fator de inclinação, c = ponto de inflexão ed = assíntota superior.
A Figura 1 restringe a para 0% e d para 100%:
A Figura 2 não possui restrições nos 4 parâmetros na equação 4PL:
Foi divertido, não pretendo saber nada biológico e será interessante ver como tudo se resolve!
fonte
Extraí os dados do gráfico de dispersão e minha pesquisa de equações gerou uma equação de tipo logístico de 3 parâmetros como um bom candidato: "y = a / (1,0 + b * exp (-1,0 * c * x))", onde " x "é a base de log 10 por seu gráfico. Os parâmetros ajustados foram a = 9.0005947126706630E + 01, b = 1.2831794858584102E + 07 e c = 6.6483431489473155E + 00 para meus dados extraídos, um ajuste dos dados originais (log 10 x) deve produzir resultados semelhantes se você reajustar os dados originais usando meus valores como estimativas de parâmetro inicial. Meus valores de parâmetro estão produzindo R-quadrado = 0,983 e RMSE = 5,625 nos dados extraídos.
EDIT: Agora que a pergunta foi editada para incluir os dados reais, aqui está um gráfico usando a equação de 3 parâmetros acima e estimativas de parâmetros iniciais.
fonte
Desde que eu tive que abrir minha boca grande sobre Heaviside, aqui estão os resultados. Defino o ponto de transição como log10 (cópias de vírus) = 2,5. Depois, calculei os desvios padrão das duas metades do conjunto de dados - ou seja, o Heaviside está assumindo que os dados de ambos os lados têm todas as derivadas = 0.
Desvio padrão do lado direito = 4.76 Desvio
padrão do lado esquerdo = 7.72
Como acontece que há 15 amostras em cada lote, o desvio padrão geral é a média ou 6,24.
Supondo que o "RMSE" citado em outras respostas seja "erro RMS" no geral, a função Heaviside parece funcionar tanto quanto, se não melhor do que a maioria da "curva Z" (emprestada da nomenclatura da resposta fotográfica) aqui.
editar
Gráfico inútil, mas solicitado nos comentários:
fonte