[Vegan-commits] r781 - in pkg/vegan: R man
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Fri Apr 3 16:09:54 CEST 2009
Author: gsimpson
Date: 2009-04-03 16:09:54 +0200 (Fri, 03 Apr 2009)
New Revision: 781
Modified:
pkg/vegan/R/betadisper.R
pkg/vegan/man/betadisper.Rd
Log:
Bug fix and updates to betadisper
Modified: pkg/vegan/R/betadisper.R
===================================================================
--- pkg/vegan/R/betadisper.R 2009-04-02 17:45:43 UTC (rev 780)
+++ pkg/vegan/R/betadisper.R 2009-04-03 14:09:54 UTC (rev 781)
@@ -1,9 +1,12 @@
`betadisper` <-
- function(d, group, type = c("centroid","median"))
+ function(d, group, type = c("centroid","median"), tol = 1e-07)
{
## uses code from stats:::cmdscale by R Core Development Team
if(!inherits(d, "dist"))
stop("distances 'd' must be a 'dist' object")
+ type <- match.arg(type)
+ if(type == "median")
+ .NotYetUsed('type = "median"')
## checks for groups - need to be a factor for later
if(!is.factor(group))
group <- as.factor(group)
@@ -11,14 +14,23 @@
x <- matrix(0, ncol = n, nrow = n)
x[row(x) > col(x)] <- d^2
x <- x + t(x)
- .C(stats:::R_dblcen, as.double(x), as.integer(n), DUP = FALSE)
+ storage.mode(x) <- "double"
+ .C(stats:::R_dblcen, x, as.integer(n), DUP = FALSE)
e <- eigen(-x/2, symmetric = TRUE)
vectors <- e$vectors
eig <- e$values
+ ## check d is Euclidean
+ w0 <- eig[n] / eig[1]
+ if(w0 > -tol)
+ r <- sum(eig > (eig[1] * tol))
+ else
+ r <- length(eig)
+ ## truncate eig if d is Euclidean
+ eig <- eig[(rs <- seq_len(r))]
+ ## scale Eigenvectors
+ vectors <- vectors[, rs, drop = FALSE] %*% diag(sqrt(abs(eig)))
## store which are the positive eigenvalues
pos <- eig > 0
- ## scale Eigenvectors
- vectors <- vectors %*% diag(sqrt(abs(eig)))
## group centroids in PCoA space
centroids <- apply(vectors, 2, function(x) tapply(x, group, mean))
## for each of the groups, calculate distance to centroid for
@@ -35,12 +47,12 @@
dist.neg <- 0
}
} else {
- dist.pos <- vectors[, pos, drop=FALSE] -
- centroids[pos]
+ dist.pos <- sweep(vectors[, pos, drop=FALSE], 2,
+ centroids[pos])
dist.pos <- rowSums(dist.pos^2)
if (any(!pos)) {
- dist.neg <- vectors[, !pos, drop=FALSE] -
- centroids[!pos]
+ dist.neg <- sweep(vectors[, !pos, drop=FALSE], 2,
+ centroids[!pos])
dist.neg <- rowSums(dist.neg^2)
} else {
dist.neg <- 0
@@ -49,7 +61,7 @@
## zij are the distances of each point to its group centroid
zij <- sqrt(abs(dist.pos - dist.neg))
## add in correct labels
- colnames(vectors) <- names(eig) <- paste("PCoA", 1:n, sep = "")
+ colnames(vectors) <- names(eig) <- paste("PCoA", rs, sep = "")
if(is.matrix(centroids))
colnames(centroids) <- names(eig)
else
Modified: pkg/vegan/man/betadisper.Rd
===================================================================
--- pkg/vegan/man/betadisper.Rd 2009-04-02 17:45:43 UTC (rev 780)
+++ pkg/vegan/man/betadisper.Rd 2009-04-03 14:09:54 UTC (rev 781)
@@ -25,7 +25,7 @@
Tukey's 'Honest Significant Difference' method.
}
\usage{
-betadisper(d, group, type = c("centroid", "median"))
+betadisper(d, group, type = c("centroid", "median"), tol = 1e-07)
\method{anova}{betadisper}(object, \dots)
@@ -51,6 +51,7 @@
level (i.e.~one group).}
\item{type}{the type of analysis to perform. Only \code{type =
"centroid"} is currently supported.}
+ \item{tol}{tolerance for checking if \code{d} is Euclidean.}
\item{display}{character; partial match to access scores for
\code{"sites"} or \code{"species"}.}
\item{object, x}{an object of class \code{"betadisper"}, the result of a
More information about the Vegan-commits
mailing list