展示随时间增长的差异

机器算法验证 r t检验 lme4-nlme ggplot2 增长模式
2022-04-19 07:50:17

精简版

给定时间和该数据集的每次治疗是否存在差异?

或者,如果我们试图展示的差异很重要,我们有什么最好的方法来解决这个问题?

长版

好的,对不起,如果有点生物学 101,但这似乎是一个边缘情况,数据和模型需要以正确的方式排列才能得出一些结论。

似乎是一个常见问题......展示直觉而不是用更大的样本量重复这个实验会很好。

假设我有这张图,显示平均值 +- 标准差。错误:

p1

现在,这里似乎有所不同。这是否合理(避免贝叶斯方法)?

头脑简单的人的方法是采取第 4 天并应用t 检验(像往常一样:2 边、未配对、不等方差),但这在这种情况下不起作用。看起来方差太高了,因为我们每个时间点只有 3 次测量值(错误 .. 主要是我的设计,p = 0.22)。

编辑反思下一个明显的方法是线性回归的方差分析。在初稿中忽略了这一点。这似乎也不是正确的方法,因为通常的线性模型会受到异方差(随时间的夸大方差)的影响。结束编辑

我猜有一种方法可以包含所有数据,这些数据适合每个预测变量随时间推移的简单(1-2 参数)增长模型,然后使用一些正式测试比较这些模型。

这种方法应该是合理的,但对于相对不成熟的观众来说是可以理解的。

compareGrowthCurvesstatmod中查看过,阅读了有关grofit的信息,并尝试了根据 SE 上的这个问题改编的线性混合效果模型后者最接近账单,尽管在我的情况下,随着时间的推移,测量结果不是来自同一个主题,所以我不确定混合效果/多级模型是否合适。

一种明智的方法是将每次增长率建模为线性和固定的,并将随机效应设为Tx ,然后测试它的重要性,尽管我认为这种方法的优点存在一些争议。

(此外,此方法指定了一个线性模型,该模型似乎不是模拟增长比较的最佳方法,在一个预测变量尚未达到上限的情况下,另一个看起来基本上是静态的。我猜有一个广义的混合效应模型方法来解决这个困难,这将是更合适的。)

现在代码:

df1 <- data.frame(Day = rep(rep(0:4, each=3), 2),
              Tx = rep(c("Control", "BHB"), each=15),
              y = c(rep(16e3, 3),
              32e3, 56e3, 6e3,
              36e3, 14e3, 24e3,
              90e3, 22e3, 18e3,
              246e3, 38e3, 82e3,
              rep(16e3, 3),
              16e3, 34e3, 16e3,
              20e3, 20e3, 24e3,
              4e3, 12e3, 16e3,
              20e3, 5e3, 12e3))
### standard error
stdErr <- function(x) sqrt(var(x)) / sqrt(length(x))
library(plyr)
### summarise as mean and standard error to allow for plotting
df2 <- ddply(df1, c("Day", "Tx"), summarise,
             m1 = mean(y),
             se = stdErr(y) )
library(ggplot2)
### plot with position dodge
pd <- position_dodge(.1)
ggplot(df2, aes(x=Day, y=m1, color=Tx)) +
 geom_errorbar(aes(ymin=m1-se, ymax=m1+se), width=.1, position=pd) +
 geom_line(position=pd) +
 geom_point(position=pd, size=3) +
 ylab("No. cells / ml")

一些正式的测试:

### t-test day 4
with(df1[df1$Day==4, ], t.test(y ~ Tx))
### anova
anova(lm(y ~ Tx + Day, df1))
### mixed effects model
library(nlme)
f1 <- lme(y ~ Day, random = ~1|Tx, data=df1[df1$Day!=0, ])
library(RLRsim)
exactRLRT(f1)

这最后的给予

    simulated finite sample distribution of RLRT.  (p-value based on 10000
    simulated values)

data:  
RLRT = 1.6722, p-value = 0.0465

我由此得出结论,在假设治疗随时间变化没有影响的零假设下,该数据(或更极端的数据)的概率接近于难以捉摸的 0.05。

再次抱歉,如果这看起来有点基本,但我觉得这样的案例可以用来说明建模在避免进一步不必要的实验重复方面的重要性。

2个回答

1)日志,我认为日志会起作用。(动机、误差随测量大小而变化,您的误差线也可能达到负值,即正态分布不正确且不那么强大)

m<-lm(y~factor(Tx),data=df1) #p ~ 0.05
m<-lm(log(y)~factor(Tx),data=df1) #p ~ 0.015

并且等于

m<-lm(y~factor(Day)+factor(Tx),data=df1) #p ~ 0.05
m<-lm(log(y)~factor(Day)+factor(Tx),data=df1) #p ~ 0.015

2)另外,更多的数据。如果分布范围如此之广,那么仅仅进行几次测量是不够的。这就像物理上不可能的定律。

3)另一个,使用(现实的->不是线性的,而是指数的)模型,该模型将所有数据考虑在内并可以减少测量误差(对于不同的实验实体,您仍然会有参数的变化)。例如使用

df1 <- data.frame(Day = rep(rep(0:4, each=3), 2),
                  Tx = rep(c(1,2), each=15),
                  y = c(rep(16e3, 3),
                        32e3, 56e3, 6e3,
                        36e3, 14e3, 24e3,
                        90e3, 22e3, 18e3,
                        246e3, 38e3, 82e3,
                        rep(16e3, 3),
                        16e3, 34e3, 16e3,
                        20e3, 20e3, 24e3,
                        4e3, 12e3, 16e3,
                        20e3, 5e3, 12e3),
                  id=c(rep(c(1,2,3),5),rep(c(4,5,6),5))
)

m <- nls(log(y) ~ log(a) + (b[id]*Day),
         start  = list(a = 16747, b = rep(0.4,6) ),
         data = df1 )

你得到完全不同的系数 b

         b1          b2          b3          b4          b5          b6 
 0.59905318  0.16483349  0.20879753 -0.10920228 -0.15905458 -0.02652816 

(如果数据质量允许更复杂的增长模型,例如包括滞后阶段,这可能会得到改善)

4)如果每个类只有三个数据点,排名测试可能会更稳健

好的,所以我们放弃了,并且在身体上做得很好,而且效果很好。

尽管如此,这仍然是一个边缘案例,因此将在此处保留一段时间。根据我的“GraphPadPrisn”手册,“AIC”是解决此类问题的方法,因此在我自己验证之前将保持打开状态。也许是物理解决方案更简单的代际问题之一。

在这种特殊情况下,我很高兴收到反馈说统计数据不是解决问题的最佳方法,并且当“付诸行动”时,解决方案应该始终是经验性的。

如果出现更好的情况,当然会改变接受的答案。