使用 R lme4 或 nlme 包估计随机效应并应用用户定义的相关/协方差结构

机器算法验证 r 混合模式
2022-03-21 14:48:25

我有以下类型的数据。我评估了 10 个人,每个人重复 10 次。我有 10x10 关系矩阵(个体的所有组合之间的关系)。

set.seed(1234)
mydata <- data.frame (gen = factor(rep(1:10, each = 10)),
                      repl = factor(rep(1:10, 10)),
                      yld = rnorm(10, 5, 0.5))

这一代是不同品种的植物,因此每个都可以重复种植并测量产量。协方差矩阵是通过独立实验中的 ibd 概率计算的遗传相似性来衡量相关性。

library(lme4)
covmat <- round(nearPD(matrix(runif(100, 0, 0.2), nrow = 10))$mat, 2)
diag(covmat) <- diag(covmat)/10+1
rownames(covmat) <- colnames(covmat) <- levels(mydata$gen)

> covmat                   
10 x 10 Matrix of class "dgeMatrix"                    
      1    2    3    4    5    6    7    8    9   10
1  1.00 0.08 0.06 0.03 0.09 0.09 0.10 0.08 0.07 0.10
2  0.08 1.00 0.08 0.09 0.04 0.12 0.08 0.08 0.11 0.09
3  0.06 0.08 1.00 0.10 0.05 0.09 0.09 0.07 0.04 0.13
4  0.03 0.09 0.10 1.00 0.02 0.11 0.09 0.06 0.04 0.12
5  0.09 0.04 0.05 0.02 1.00 0.06 0.07 0.05 0.02 0.08
6  0.09 0.12 0.09 0.11 0.06 1.00 0.12 0.08 0.07 0.14
7  0.10 0.08 0.09 0.09 0.07 0.12 1.00 0.08 0.03 0.15
8  0.08 0.08 0.07 0.06 0.05 0.08 0.08 1.00 0.06 0.09
9  0.07 0.11 0.04 0.04 0.02 0.07 0.03 0.06 1.00 0.03
10 0.10 0.09 0.13 0.12 0.08 0.14 0.15 0.09 0.03 1.00

我的模型是:

yld = gen + repl + error 

gen 和 repl 都被认为是随机的,我想获得与每个 gen 相关的随机效应估计,但是我需要考虑关系矩阵。

如果嵌套模型太复杂,我会从模型中删除 repl,但理想情况下我会保留它。

yld = gen +  error 

如何使用 R 包(可能使用 nlme 或 lme4)来实现这一点?我知道 ASREML 可以做到,但我没有把握,我喜欢 R,因为它既健壮又自由。

4个回答

尝试kinship基于nlme. 有关详细信息,请参阅r-sig-mixed-models 上的此线程。当我试图为逻辑模型做这件事时,我忘记了这一点。有关已解决的示例,请参阅https://stackoverflow.com/questions/8245132

对于非正常响应,您需要修改基于 lme4 的 pedigreemm 包。它让你接近,但关系矩阵必须从谱系中创建。下面的函数是对pedigreemm函数的修改,它采用任意关系矩阵。

library(pedigreemm)
relmatmm <- function (formula, data, family = NULL, REML = TRUE, relmat = list(), 
    control = list(), start = NULL, verbose = FALSE, subset, 
    weights, na.action, offset, contrasts = NULL, model = TRUE, 
    x = TRUE, ...) 
{
    mc <- match.call()
    lmerc <- mc
    lmerc[[1]] <- as.name("lmer")
    lmerc$relmat <- NULL
    if (!length(relmat)) 
        return(eval.parent(lmerc))
    stopifnot(is.list(relmat), length(names(relmat)) == length(relmat))
    lmerc$doFit <- FALSE
    lmf <- eval(lmerc, parent.frame())
    relfac <- relmat
    relnms <- names(relmat)
    stopifnot(all(relnms %in% names(lmf$FL$fl)))
    asgn <- attr(lmf$FL$fl, "assign")
    for (i in seq_along(relmat)) {
        tn <- which(match(relnms[i], names(lmf$FL$fl)) == asgn)
        if (length(tn) > 1) 
            stop("a relationship matrix must be associated with only one random effects term")
        Zt <- lmf$FL$trms[[tn]]$Zt
        relmat[[i]] <- Matrix(relmat[[i]][rownames(Zt), rownames(Zt)], 
            sparse = TRUE)
        relfac[[i]] <- chol(relmat[[i]])
        lmf$FL$trms[[tn]]$Zt <- lmf$FL$trms[[tn]]$A <- relfac[[i]] %*% Zt
    }
    ans <- do.call(if (!is.null(lmf$glmFit)) 
        lme4:::glmer_finalize
    else lme4:::lmer_finalize, lmf)
    ans <- new("pedigreemm", relfac = relfac, ans)
    ans@call <- match.call()
    ans
}

用法类似于,pedigreemm除了你给它关系矩阵作为relmat参数而不是谱系作为pedigree参数。

m <- relmatmm(yld ~ (1|gen) + (1|repl), relmat=list(gen=covmat), data=mydata)

这在这里不适用,因为您有十个观察/个人,但是对于一个观察/个人,您需要在此函数中再增加一行和一个小补丁,lme4以允许每个随机效应只进行一次观察。

这个答案是 Aaron 提出的建议的潜在扩展,他建议使用 Pedigreem。谱系可以按照以下语法从项目中计算关系,我不知道我们如何以不同的方式使用这种关系输出。

# just example from the manual to create pedigree structure and relation matrix 
  # (although you have already the matrix in place) 
p1 <- new("pedigree",
sire = as.integer(c(NA,NA,1, 1,4,5)),
dam = as.integer(c(NA,NA,2,NA,3,2)),
label = as.character(1:6))
p1
(dtc <- as(p1, "sparseMatrix")) # T-inverse in Mrode’s notation
solve(dtc)
inbreeding(p1) 

包的混合模型拟合基于 lme4,因为 main 函数的语法类似于 lme4 包函数 lmer 函数,不同之处在于您可以将谱系对象放入其中。

pedigreemm(formula, data, family = NULL, REML = TRUE, pedigree = list(),
 control = list(),
start = NULL, verbose = FALSE, subset, weights, na.action, 
  offset, contrasts = NULL, model = TRUE, x = TRUE, ...)

我知道这不是您问题的完美答案,但这可能会有所帮助。我很高兴你问这个问题,对我来说很有趣!

lmer()lme4包中允许交叉随机效果。在这里,你会使用类似的东西

y ~ (1|gen) + (1|repl)

供完整参考;

http://www.stat.wisc.edu/~bates/PotsdamGLMM/LMMD.pdf

你的标题说“使用 lme4 或 nlme 包”,但你的文字说

如何使用 R 包(可能使用 nlme 或 lme4)来实现这一点?我知道 ASREML 可以做到,但我没有把握,我喜欢 R,因为它既健壮又自由。

这种方法不是基于这两个包,但是它是开源的并且非常灵活。具有任意协方差结构的 GBLUP 是 RKHS 回归又名 Kernel Ridge Regression的一个特例包 BGLR 估计贝叶斯框架中的方差分量。另一种选择是KRMM包,它似乎可以解决相同的模型,但使用期望最大化而不是贝叶斯方法(吉布斯采样)。但我没有测试。

BGLR 扩展文档的摘录计算

y ~ a + g + e

其中a是具有谱系衍生协方差结构g的随机效应, 是使用标记衍生协方差结构的随机效应(您可以使用另一个遗传距离而不是此处显示的定义)并且e是残差。对于您的问题,您当然可以省略a(= list(K=A, ...)。基因组关系矩阵(在本例中)必须GA中的基因型顺序 1 对 1 相关y,因此如果一个基因型在 中多次出现y,它也必须在矩阵中这样做。

框 4a:使用高斯过程拟合谱系 + 标记回归

#1# Loading and preparing the input data
library(BGLR);
data(wheat);Y<-wheat.Y; X<-wheat.X; A<-wheat.A;
y<-Y[,1]

#2# Computing the genomic relationship matrix
X<-scale(X,center=TRUE,scale=TRUE)
G<-tcrossprod(X)/ncol(X)

#3# Computing the eigen-value decomposition of G
EVD <-eigen(G)

#3# Setting the linear predictor
ETA<-list(list(K=A, model='RKHS'),
          list(V=EVD$vectors,d=EVD$values, model='RKHS'))

#4# Fitting the model
fm<-BGLR(y=y,ETA=ETA, nIter=12000, burnIn=2000,saveAt='PGBLUP_') 
save(fm,file='fmPG_BLUP.rda')

另请参阅这些计算 GBLUP 的不同方法的示例

此文档页面显示了一个包含固定效果的示例(以及其他方法,例如 BayesB,只需使用您需要的那些模型):

pheno=mice.pheno

fm=BGLR(y=pheno$Obesity.BMI,
        ETA=list(
          fixed=list(~factor(GENDER)+factor(Litter),data=pheno,model='FIXED'),
          cage=list(~factor(cage),data=pheno,model='BRR'),
          ped=list(K=A,model='RKHS'),
          mrk=list(X=X,model='BayesB')
     )
)