]> git.donarmstrong.com Git - ape.git/blob - R/compar.gee.R
current 2.1 release
[ape.git] / R / compar.gee.R
1 ## compar.gee.R (2006-10-11)
2
3 ##   Comparative Analysis with GEEs
4
5 ## Copyright 2002-2006 Emmanuel Paradis
6
7 ## This file is part of the R-package `ape'.
8 ## See the file ../COPYING for licensing issues.
9
10 compar.gee <- function(formula, data = NULL, family = "gaussian", phy,
11                        scale.fix = FALSE, scale.value = 1)
12 {
13     if (is.null(data)) data <- parent.frame() else {
14         if(!any(is.na(match(rownames(data), phy$tip.label))))
15           data <- data[phy$tip.label, ]
16         else warning("the rownames of the data.frame and the tip labels of the tree
17 do not match: the former were ignored in the analysis.")
18     }
19     effect.assign <- attr(model.matrix(formula, data = data), "assign")
20     for (i in all.vars(formula)) {
21         if (any(is.na(eval(parse(text = i), envir = data))))
22           stop("the present method cannot (yet) be used directly with missing data: you may consider removing the species with missing data from your tree with the function `drop.tip'.")
23     }
24     if (is.null(phy$edge.length))
25       stop("the tree has no branch lengths.")
26     R <- vcv.phylo(phy, cor = TRUE)
27     id <- rep(1, dim(R)[1])
28     geemod <- do.call("gee", list(formula, id, data = data, family = family, R = R,
29                                   corstr = "fixed", scale.fix = scale.fix,
30                                   scale.value = scale.value))
31     W <- geemod$naive.variance
32     if (family == "binomial")
33       W <- summary(glm(formula, family = quasibinomial, data = data))$cov.scaled
34     N <- geemod$nobs
35     dfP <- sum(phy$edge.length)*N / sum(diag(vcv.phylo(phy)))
36     obj <- list(call = geemod$call,
37                 effect.assign = effect.assign,
38                 nobs = N,
39                 coefficients = geemod$coefficients,
40                 residuals = geemod$residuals,
41                 family = geemod$family$family,
42                 link = geemod$family$link,
43                 scale = geemod$scale,
44                 W = W,
45                 dfP = dfP)
46     class(obj) <- "compar.gee"
47     obj
48 }
49
50 print.compar.gee <- function(x, ...)
51 {
52     nas <- is.na(x$coef)
53     coef <- x$coef[!nas]
54     cnames <- names(coef)
55     coef <- matrix(rep(coef, 4), ncol = 4)
56     dimnames(coef) <- list(cnames,
57                            c("Estimate", "S.E.", "t", "Pr(T > |t|)"))
58     df <- x$dfP - dim(coef)[1]
59     coef[, 2] <- sqrt(diag(x$W))
60     coef[, 3] <- coef[, 1]/coef[, 2]
61     if (df < 0) {
62         warning("not enough degrees of freedom to compute P-values.")
63         coef[, 4] <- NA
64     } else coef[, 4] <- 2 * (1 -  pt(abs(coef[, 3]), df))
65     residu <- quantile(as.vector(x$residuals))
66     names(residu) <- c("Min", "1Q", "Median", "3Q", "Max")
67     cat("\nCall:\n")
68     cat("  formula: ")
69     print(x$call$formula)
70     cat("\nNumber of observations: ", x$nobs, "\n")
71     cat("\nModel:\n")
72     cat(" Link:                     ", x$link, "\n")
73     cat(" Variance to Mean Relation:", x$family, "\n")
74     cat("\nSummary of Residuals:\n")
75     print(residu)
76     if (any(nas))
77         cat("\n\nCoefficients: (", sum(nas), " not defined because of singularities)\n",
78             sep = "")
79     else cat("\n\nCoefficients:\n")
80     print(coef)
81     cat("\nEstimated Scale Parameter: ", x$scale)
82     cat("\n\"Phylogenetic\" df (dfP): ", x$dfP, "\n")
83 }
84
85 drop1.compar.gee <- function(object, scope, quiet = FALSE, ...)
86 {
87     fm <- formula(object$call)
88     trm <- terms(fm)
89     z <- attr(trm, "term.labels")
90     ind <- object$effect.assign
91     n <- length(z)
92     ans <- matrix(NA, n, 3)
93     for (i in 1:n) {
94         wh <- which(ind == i)
95         ans[i, 1] <- length(wh)
96         ans[i, 2] <- t(object$coefficients[wh]) %*%
97           solve(object$W[wh, wh]) %*% object$coefficients[wh]
98     }
99     df <- object$dfP - length(object$coefficients)
100     if (df < 0) warning("not enough degrees of freedom to compute P-values.")
101     else ans[, 3] <- pf(ans[, 2], ans[, 1], df, lower.tail = FALSE)
102     colnames(ans) <- c("df", "F", "Pr(>F)")
103     rownames(ans) <- z
104     if (any(attr(trm, "order") > 1) && !quiet)
105       warning("there is at least one interaction term in your model:
106 you should be careful when interpreting the significance of the main effects.")
107     class(ans) <- "anova"
108     attr(ans, "heading") <- c("Single term deletions\n\nModel:\n",
109                               as.character(as.expression(fm)))
110     ans
111 }