Estimando efeitos aleatórios e aplicando estrutura de correlação / covariância definida pelo usuário com o pacote R lme4 ou nlme

9

Eu tenho o seguinte tipo de dados. Avaliei 10 indivíduos, cada um repetido 10 vezes. Tenho matriz de relação 10x10 (relação entre todas as combinações dos indivíduos).

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))

Essa geração é de variedades diferentes de plantas, de modo que cada uma pode ser cultivada repetidamente e o rendimento é medido. A matriz de covariância é medida de parentesco por similaridade genética calculada pelas probabilidades ibd em experimentos separados.

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

Meu modelo é:

yld = gen + repl + error 

gen e repl são considerados aleatórios e eu quero obter as estimativas de efeitos aleatórios associados a cada geração, no entanto, preciso considerar a matriz de relacionamento.

Se for muito complexo para caber em modelos aninhados, eu apenas removeria o repl do modelo, mas o ideal é mantê-lo.

yld = gen +  error 

Como conseguir isso usando pacotes R, talvez com nlme ou lme4? Eu sei que o ASREML pode fazer isso, mas não tenho retenção e amo o R por ser robusto e gratuito.

Ram Sharma
fonte
1
Aaron, obrigado por seus pensamentos, esperança terá sugestão mais robusta sobre isso ...
Ram Sharma
O exemplo é extremamente confuso porque sugere fortemente um tipo diferente de conjunto de dados; contradiz a questão. Exclua este exemplo ou forneça um exemplo realista.
whuber
@whuber eu editei um pouco do meu erro de digitação e fiz o meu ponto mais claro, esperança ajuda
Ram Sharma
@ RamSharma: tomei a liberdade de criar uma amostra de matriz de covariância definida positiva e fiz algumas edições menores; fique à vontade para editar novamente se eu tiver alterado algo importante.
Aaron saiu de Stack Overflow
Acho que devemos migrar isso para o stackoverflow, para obter mais visualizações. Eu não sei como fazê-lo, alguém pode ajudar?
John

Respostas:

6

Experimente o kinshippacote, que é baseado nlme. Veja este tópico em r-sig-mixed-models para obter detalhes. Eu tinha me esquecido disso enquanto tentava fazer isso por um modelo logístico. Consulte /programming/8245132 para obter um exemplo elaborado.

Para respostas não normais, você precisa modificar o pacote pedigreemm, baseado no lme4. Isso o aproxima, mas a matriz de relacionamento deve ser criada a partir de uma linhagem. A função abaixo é uma modificação da pedigreemmfunção que utiliza uma matriz de relacionamento arbitrária.

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
}

O uso é semelhante a, pedigreemmexceto se você fornecer a matriz de relacionamento como relmatargumento, em vez da linhagem como pedigreeargumento.

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

Isso não se aplica aqui, pois você tem dez observações / indivíduo, mas para uma observação / indivíduo, você precisa de mais uma linha nesta função e um patch menor lme4para permitir apenas uma observação por efeito aleatório.

Aaron deixou Stack Overflow
fonte
Que tal: lme (yld ~ 1, data = mydata, aleatório = ~ gen + repl, correlação = covmat) # a fórmula está dando e com erro e não tenho certeza se a estrutura de correlação se aplica à replicação ou termo residual, o que fazer você pensa ?
John
@ John: Efeitos aleatórios cruzados são complicados nlmee é necessário algo mais complicado gen + repl; Além disso, acho que a correlação precisa chamar uma das nlmefunções de covariância / correlação covmatcomo parâmetro. A notação para isso é realmente complicada, para dizer mais, eu precisaria de Pinhiero / Bates, o que não preciso hoje.
Aaron saiu de Stack Overflow
então, se não houver efeito de repl, você acha que o lme (yld ~ 1, data = mydata, random = ~ gen, correlação = covmat) é apropriado ou equivalente ao código asreml: asreml (yld ~ 1, random = ~ gen, ginverse = lista (gen = inv.covmat), dados = mydata), onde é inv.covmat triângulo inferior derretido matriz (ver documentação asreml-r)
John
A notação correta provavelmente seria algo como lme(yld ~ 1, data = mydata, random = ~ 1 | gen, correlation = corSymm(value=covmatX, form= ~ gen, fixed=TRUE)), onde covmatXestá uma versão modificada covmatpara fazê-lo como corSymmquiser. Também não tenho certeza de que o formtermo seja correto.
Aaron saiu de Stack Overflow
@ Aaron, tem esse patch à mão? Eu precisaria-lo muitas vezes para ajustar um modelo com um único indivíduo para cada classe ... eu poderia querer perguntar como questão separada .... pode ser muito nesta questão
Ram Sharma
4

Essa resposta é uma potencial expansão da sugestão feita por Aaron, que sugeriu o uso de Pedigreem. O pedigreem pode calcular o relacionamento dos projetos como segue a sintaxe, não sei como podemos usar essa saída de relacionamento de maneira diferente.

# 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) 

O ajuste do modelo misto do pacote é baseado no lme4, pois a sintaxe da função principal é semelhante à função lmer da função do pacote lme4, exceto que você pode colocar o objeto de linhagem nele.

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, ...)

Sei que essa não é a resposta perfeita para sua pergunta, mas isso pode ajudar um pouco. Fico feliz que você fez esta pergunta, interessante para mim!

John
fonte
1
Sugerida por RamSharma: Solução usando parentesco : require(kinship); model1 <- lmekin(yld ~1, random = ~ 1|gen, varlist =list(covmat), data=mydata).
24411 chl
1
mais edições na minha sugestão:, model1 <- lmekin(yld ~1, random = ~ 1|gen, varlist =list(covmat), data=mydata)ainda há um problema, desculpe-me por postagens prematuras. Alguém pode consertar isso?
Ram Sharma #
0

lmer()no lme4pacote permite efeitos aleatórios cruzados. Aqui, você usaria algo como

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

Para uma referência completa;

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

hóspede
fonte
3
sim, o ajuste do efeito aleatório cruzado não é um problema isolado; no entanto, o ajuste da estrutura de co-variação definida pelo usuário é o principal problema, e a pergunta busca principalmente a resposta para isso.
John