多次表面接触后手指上的细菌:非正常数据、重复测量、交叉参与者

机器算法验证 r 方差分析 重复测量 lme4-nlme 咕噜咕噜
2022-03-13 15:44:49

介绍

我有参与者在两种情况下反复接触大肠杆菌污染的表面(A = 戴手套,B = 不戴手套)。我想知道戴手套和戴手套时指尖上的细菌数量是否存在差异,以及接触次数之间是否存在差异。这两个因素都在参与者内部。

实验方法:

参与者(n=35)用同一根手指触摸每个方格一次,最多接触 8 次(见图 a)。 a) 手指接触 8 个表面,b) 每次接触表面后手指上的 CFU

然后我用棉签擦拭参与者的手指,并在每次接触后测量指尖上的细菌。然后他们使用手指触摸不同数量的表面,依此类推,从 1 到 8 个触点(见图 b)。

这是真实数据:真实数据

数据是非正态的,因此请参阅下面的细菌边缘分布|NumberContacts。x=细菌。每个方面是不同数量的联系人。

在此处输入图像描述

模型

根据变形虫的建议lme4::glmer尝试使用 Gamma(link="log") 和 NumberContacts 的多项式:

cfug<-glmer(CFU ~ Gloves + poly(NumberContacts,2) + (-1+NumberContacts|Participant),
            data=(K,CFU<4E5),
           family=Gamma(link="log")
            )
plot(cfug)

注意。Gamma(link="inverse") 不会运行说 PIRLS 减半未能减少偏差。

结果:

cfug的拟合与残差 在此处输入图像描述

qqp(resid(cfug))

在此处输入图像描述

问题:

我的 glmer 模型是否正确定义以包含每个参与者的随机效应以及每个人都做实验A和实验B的事实

添加:

参与者之间似乎存在自相关。这可能是因为它们没有在同一天进行测试,并且细菌瓶会随着时间的推移而生长和减少。有关系吗?

acf(CFU,lag=35) 显示了一个参与者和下一个参与者之间的显着相关性。

在此处输入图像描述

3个回答

一些用于探索数据的图

下面是八个,每个表面接触数量一个,xy 图显示手套与不戴手套。

每个人都用一个点绘制。均值、方差和协方差用红点和椭圆表示(马氏距离对应于 97.5% 的总体)。

您可以看到,与人口分布相比,影响很小。“不戴手套”的平均值更高,而更多表面接触的平均值会更高(这可以证明是显着的)。但效果只是很小(总体而言14log 减少),并且有很多人实际上戴手套的细菌数量更高

小的相关性表明确实存在来自个人的随机效应(如果没有来自人的影响,那么配对手套和不戴手套之间应该没有相关性)。但这只是一个很小的影响,个人可能对“手套”和“不戴手套”有不同的随机影响(例如,对于所有不同的接触点,个人对“手套”的计数可能始终高于/低于“不戴手套”) .

戴手套和不戴手套的 xy 图

下图是 35 个人中每个人的单独图。这个图的想法是看行为是否是同质的,也看什么样的函数看起来合适。

请注意,“不戴手套”是红色的。在大多数情况下,红线越高,“不戴手套”的情况下细菌越多。

我相信线性图应该足以捕捉这里的趋势。二次图的缺点是系数会更难解释(你不会直接看到斜率是正还是负,因为线性项和二次项都会对此产生影响)。

但更重要的是,您会看到不同个体之间的趋势差异很大,因此为截距和个体斜率添加随机效应可能很有用。

每个人的地块

模型

使用下面的模型

  • 每个人都会得到自己的曲线拟合(线性系数的随机效应)。
  • 该模型使用对数转换的数据并适合常规(高斯)线性模型。在评论中变形虫提到日志链接与对数正态分布无关。但这是不同的。yN(log(μ),σ2)不同于log(y)N(μ,σ2)
  • 应用权重是因为数据是异方差的。数字越大,变化越窄。这可能是因为细菌计数有一定的上限,而变化主要是由于从表面到手指的传播失败(= 与较低的计数有关)。另见 35 个地块。主要是少数个体的变异比其他个体高得多。(我们还在 qq 图中看到更大的尾巴,过度分散)
  • 没有使用截距项,而是添加了一个“对比”项。这样做是为了使系数更容易解释。

.

K    <- read.csv("~/Downloads/K.txt", sep="")
data <- K[K$Surface == 'P',]
Contactsnumber   <- data$NumberContacts
Contactscontrast <- data$NumberContacts * (1-2*(data$Gloves == 'U'))
data <- cbind(data, Contactsnumber, Contactscontrast)
m    <- lmer(log10CFU ~ 0 + Gloves + Contactsnumber + Contactscontrast + 
                        (0 + Gloves + Contactsnumber + Contactscontrast|Participant) ,
             data=data, weights = data$log10CFU)

这给

> summary(m)
Linear mixed model fit by REML ['lmerMod']
Formula: log10CFU ~ 0 + Gloves + Contactsnumber + Contactscontrast + (0 +  
    Gloves + Contactsnumber + Contactscontrast | Participant)
   Data: data
Weights: data$log10CFU

REML criterion at convergence: 180.8

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.0972 -0.5141  0.0500  0.5448  5.1193 

Random effects:
 Groups      Name             Variance  Std.Dev. Corr             
 Participant GlovesG          0.1242953 0.35256                   
             GlovesU          0.0542441 0.23290   0.03            
             Contactsnumber   0.0007191 0.02682  -0.60 -0.13      
             Contactscontrast 0.0009701 0.03115  -0.70  0.49  0.51
 Residual                     0.2496486 0.49965                   
Number of obs: 560, groups:  Participant, 35

Fixed effects:
                  Estimate Std. Error t value
GlovesG           4.203829   0.067646   62.14
GlovesU           4.363972   0.050226   86.89
Contactsnumber    0.043916   0.006308    6.96
Contactscontrast -0.007464   0.006854   -1.09

QQ图

残差

获取绘图的代码

化学计量学::drawMahal 函数

# editted from chemometrics::drawMahal
drawelipse <- function (x, center, covariance, quantile = c(0.975, 0.75, 0.5, 
                                              0.25), m = 1000, lwdcrit = 1, ...) 
{
  me <- center
  covm <- covariance
  cov.svd <- svd(covm, nv = 0)
  r <- cov.svd[["u"]] %*% diag(sqrt(cov.svd[["d"]]))
  alphamd <- sqrt(qchisq(quantile, 2))
  lalpha <- length(alphamd)
  for (j in 1:lalpha) {
    e1md <- cos(c(0:m)/m * 2 * pi) * alphamd[j]
    e2md <- sin(c(0:m)/m * 2 * pi) * alphamd[j]
    emd <- cbind(e1md, e2md)
    ttmd <- t(r %*% t(emd)) + rep(1, m + 1) %o% me
#    if (j == 1) {
#      xmax <- max(c(x[, 1], ttmd[, 1]))
#      xmin <- min(c(x[, 1], ttmd[, 1]))
#      ymax <- max(c(x[, 2], ttmd[, 2]))
#      ymin <- min(c(x[, 2], ttmd[, 2]))
#      plot(x, xlim = c(xmin, xmax), ylim = c(ymin, ymax), 
#           ...)
#    }
  }
  sdx <- sd(x[, 1])
  sdy <- sd(x[, 2])
  for (j in 2:lalpha) {
    e1md <- cos(c(0:m)/m * 2 * pi) * alphamd[j]
    e2md <- sin(c(0:m)/m * 2 * pi) * alphamd[j]
    emd <- cbind(e1md, e2md)
    ttmd <- t(r %*% t(emd)) + rep(1, m + 1) %o% me
#    lines(ttmd[, 1], ttmd[, 2], type = "l", col = 2)
    lines(ttmd[, 1], ttmd[, 2], type = "l", col = 1, lty=2)  #
  }
  j <- 1
  e1md <- cos(c(0:m)/m * 2 * pi) * alphamd[j]
  e2md <- sin(c(0:m)/m * 2 * pi) * alphamd[j]
  emd <- cbind(e1md, e2md)
  ttmd <- t(r %*% t(emd)) + rep(1, m + 1) %o% me
#  lines(ttmd[, 1], ttmd[, 2], type = "l", col = 1, lwd = lwdcrit)
  invisible()
}

5 x 7 绘图

#### getting data
K <- read.csv("~/Downloads/K.txt", sep="")

### plotting 35 individuals

par(mar=c(2.6,2.6,2.1,1.1))
layout(matrix(1:35,5))

for (i in 1:35) {
  # selecting data with gloves for i-th participant
  sel <- c(1:624)[(K$Participant==i) & (K$Surface == 'P') & (K$Gloves == 'G')]
      # plot data
  plot(K$NumberContacts[sel],log(K$CFU,10)[sel], col=1,
       xlab="",ylab="",ylim=c(3,6))
      # model and plot fit
  m <- lm(log(K$CFU[sel],10) ~ K$NumberContacts[sel])
  lines(K$NumberContacts[sel],predict(m), col=1)

  # selecting data without gloves for i-th participant 
  sel <- c(1:624)[(K$Participant==i) & (K$Surface == 'P') & (K$Gloves == 'U')]
     # plot data 
  points(K$NumberContacts[sel],log(K$CFU,10)[sel], col=2)
     # model and plot fit
  m <- lm(log(K$CFU[sel],10) ~ K$NumberContacts[sel])
  lines(K$NumberContacts[sel],predict(m), col=2)
  title(paste0("participant ",i))
}

2 x 4 绘图

#### plotting 8 treatments (number of contacts)

par(mar=c(5.1,4.1,4.1,2.1))
layout(matrix(1:8,2,byrow=1))

for (i in c(1:8)) {
  # plot canvas
  plot(c(3,6),c(3,6), xlim = c(3,6), ylim = c(3,6), type="l", lty=2, xlab='gloves', ylab='no gloves')

  # select points and plot
  sel1 <- c(1:624)[(K$NumberContacts==i) & (K$Surface == 'P') & (K$Gloves == 'G')]
  sel2 <- c(1:624)[(K$NumberContacts==i) & (K$Surface == 'P') & (K$Gloves == 'U')]
  points(K$log10CFU[sel1],K$log10CFU[sel2])

  title(paste0("contact ",i))

  # plot mean
  points(mean(K$log10CFU[sel1]),mean(K$log10CFU[sel2]),pch=21,col=1,bg=2)

  # plot elipse for mahalanobis distance
  dd <- cbind(K$log10CFU[sel1],K$log10CFU[sel2])
  drawelipse(dd,center=apply(dd,2,mean),
            covariance=cov(dd),
            quantile=0.975,col="blue",
            xlim = c(3,6), ylim = c(3,6), type="l", lty=2, xlab='gloves', ylab='no gloves')
}

首先,在你的图表上做得很好;它给出了数据的清晰表示,因此您已经可以根据接触次数和是否使用手套来查看数据中的模式类型。 看看这张图,我想你会用一个基本的对数多项式模型得到很好的结果,对参与者有随机效应。您选择的模型看起来很合理,但您也可以考虑为联系人数量添加一个二次项。

至于是否使用MASS:glmmPQLlme4:glmer用于您的模型,我的理解是这两个函数将拟合相同的模型(只要您将模型方程、分布和链接函数设置为相同),但它们使用不同的估计方法来找到拟合。我可能弄错了,但我从文档中的理解是,使用Wolfinger 和 O'Connell (1993)glmmPQL中描述的惩罚准似然,而使用 Gauss-Hermite 正交。如果您担心它,您可以使用这两种方法拟合您的模型并检查它们是否给出相同的系数估计值,这样您将更有信心拟合算法已收敛到系数的真实 MLE。glmer


应该NumberContacts是分类因素吗?

此变量具有从您的图中显示的自然顺序,与响应变量具有平滑关系,因此您可以合理地将其视为数字变量。如果要包含,factor(NumberContacts)那么您将不会限制其形式,并且您不会失去很多自由度。您甚至可以在Gloves*factor(NumberContacts)不损失太多自由度的情况下使用交互。但是,值得考虑的是使用因子变量是否会涉及过度拟合数据。鉴于您的绘图中存在相当平滑的关系,一个简单的线性函数或二次函数将获得良好的结果而不会过度拟合。


你如何制作Participant一个随机斜率而不是截距变量?

您已经使用对数链接函数将响应变量置于对数尺度上,因此截距效应对Participant响应产生乘法效应。如果你给它一个随机斜率与之交互,NumberContacts那么它将对响应产生基于功率的影响。如果你想要这个,那么你可以得到它,(~ -1 + NumberContacts|Participant)它会删除截距,但会根据接触的数量添加一个斜率。


我应该使用 Box-Cox 来转换我的数据吗?(例如 λ=0.779)

如果有疑问,请尝试使用此转换拟合模型,并使用适当的拟合优度统计量将其与其他模型进行比较。如果您要使用此转换,最好保留参数λ作为一个自由参数,让它作为模型的一部分进行估计,而不是预先指定一个值。


我应该包括方差权重吗?

首先查看您的残差图,看看是否有异方差的证据。根据您已经包含的图,在我看来这不是问题,因此您不需要为方差添加任何权重。如果有疑问,您可以使用简单的线性函数添加权重,然后执行统计测试以查看权重的斜率是否平坦。这相当于对异方差性的正式测试,这将为您的选择提供一些支持。


我应该在中包含自相关NumberContacts吗?

如果您已经为参与者包含了一个随机效应项,那么在联系人数量上添加一个自相关项可能不是一个好主意。您的实验对不同数量的联系人使用不同的手指,因此您不会期望在您已经考虑参与者的情况下出现自相关。除了参与者效应之外,添加自相关项意味着您认为不同手指的结果之间存在条件依赖性,基于接触的数量,即使对于给定的参与者也是如此。


您的图表很好地显示了关系,但您可以通过添加标题和副标题信息并为其提供更好的轴标签来从美学上改进它。您还可以通过删除其标题并将“是”更改为“手套”并将“否”更改为“无手套”来简化您的图例。

事实上,有理由认为从一个参与者那里获取的测量值并不独立于从另一参与者那里获取的测量值。例如,有些人可能倾向于用更多(或更少)的力来按压他们的手指,这会影响他们在每个接触次数上的所有测量值。

因此,在这种情况下,2 路重复测量 ANOVA 将是一个可接受的模型。

或者,也可以应用混合效应模型participant作为随机因素。这是一个更先进和更复杂的解决方案。