[Vegan-commits] r1537 - in pkg/vegan: R inst man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Thu Mar 10 19:35:29 CET 2011


Author: jarioksa
Date: 2011-03-10 19:35:29 +0100 (Thu, 10 Mar 2011)
New Revision: 1537

Modified:
   pkg/vegan/R/metaMDSrotate.R
   pkg/vegan/inst/ChangeLog
   pkg/vegan/man/metaMDS.Rd
Log:
metaMDSrotate can now rotate > 2D ordinations

Modified: pkg/vegan/R/metaMDSrotate.R
===================================================================
--- pkg/vegan/R/metaMDSrotate.R	2011-03-10 12:01:00 UTC (rev 1536)
+++ pkg/vegan/R/metaMDSrotate.R	2011-03-10 18:35:29 UTC (rev 1537)
@@ -1,32 +1,51 @@
 ### Rotates metaMDS result so that axis one is parallel to vector 'x'
 `metaMDSrotate` <-
-    function(object, vec, choices = 1:2, ...) 
+    function(object, vec, ...) 
 {
     if (!inherits(object, "metaMDS"))
-        stop("function works only with 'metaMDS' results")
-    if (length(choices) != 2)
-        stop("function can be only used with 2dim plots")
-    if (NCOL(object$points) > 2)
-        warning(gettextf("only two of %d axes are rotated",
-                         NCOL(object$points)))
+        stop(gettextf("function works only with 'metaMDS' results"))
+    x <- object$points
+    sp <- object$species
+    N <- NCOL(x)
+    if (N < 2)
+        stop(gettextf("needs at least 2 dimensions"))
     vec <- drop(vec)
     if (length(dim(vec)) > 1)
-        stop("function works only with univariate 'x'")
-    ## envfit finds the direction cosine
-    rot <- envfit(object, vec, choices = choices, ...)$vectors$arrows
-    rot <- drop(rot)
-    ## rotation matrix [[sin theta, cos theta] [-cos theta, sin theta]]
-    rot <- rbind(rot, rev(rot))
-    rot[2,1] <- -rot[2,1]
-    ## transpose (inverse) of the rotation matrix
-    rot <- t(rot)
-    ## Rotation of points and species scores
-    object$points[, choices] <-
-        object$points[, choices, drop=FALSE] %*% rot
+        stop(gettextf, "function works only with univariate 'vec'")
+    ## scores must be orthogonal for the next loop to work
+    if (N > 2) {
+        pc <- prcomp(x)
+        x <- pc$x
+        if (!all(is.na(sp)))
+            sp <- sp %*% pc$rotation
+    }
+    ## envfit finds the direction cosine. We rotate first axis to
+    ## 'vec' which means that we make other axes orthogonal to 'vec'
+    ## one by one
+    for (k in 2:N) {
+        rot <- envfit(x, vec, choices = c(1,k), permutations=0)$vectors$arrows
+        rot <- drop(rot)
+        ## rotation matrix [[sin theta, cos theta] [-cos theta, sin theta]]
+        rot <- rbind(rot, rev(rot))
+        rot[2,1] <- -rot[2,1]
+        ## transpose (inverse) of the rotation matrix
+        rot <- t(rot)
+        ## Rotation of points and species scores
+        x[, c(1,k)] <- x[, c(1,k)] %*% rot
+        if (!all(is.na(sp)))
+            sp[, c(1,k)] <- sp[, c(1,k)] %*% rot
+    }
+    ## Rotate 2..N axes to PC
+    if (N > 2 && attr(object$points, "pc")) {
+        pc <- prcomp(x[,-1])
+        x[,-1] <- pc$x
+        if (!all(is.na(sp)))
+            sp[,-1] <- sp[,-1] %*% pc$rotation
+    }
+    ## '[] <-' retains attributes
+    object$points[] <- x
+    object$species[] <- sp
     attr(object$points, "pc") <- FALSE
-    if (!is.null(object$species))
-        object$species[, choices] <-
-            object$species[, choices, drop=FALSE] %*% rot
     object
 }
 

Modified: pkg/vegan/inst/ChangeLog
===================================================================
--- pkg/vegan/inst/ChangeLog	2011-03-10 12:01:00 UTC (rev 1536)
+++ pkg/vegan/inst/ChangeLog	2011-03-10 18:35:29 UTC (rev 1537)
@@ -7,14 +7,20 @@
 	* ordisurf: got a formula interface as an alternative to define
 	the model.
 
-	* metaMDSrotate: function can only rotate two dimensions. It was
-	supposed to be able to pick two dimensions from multidimensional
-	solutions, but failed. Now it really rotates two dimensions, and
-	lefts the rest as unrotated instead of destroying them and only
-	returning the two axes. Needs improvement if we want to have this
-	as a generic function. Indeed, JO had great doubts about releasing
-	this function, but then light-mindedly let it go to 1.16-14 &
-	1.17-0.
+	* metaMDSrotate: can now rotate > 2-dim solutions so that the
+	first axis is parallel to a given vector and all others are
+	orthogonal to the vector (and rotated to PC if they were
+	originally). Earlier had argument 'choices' which was supposed to
+	select only two axes to be rotated (but failed before rev 1533),
+	but now lost 'choices' and always uses all dimensions, and
+	orthogonalies dim 2 and beyond against the given vector. There was
+	a query in R-sig-ecology on having two vectors in 3-dim ordination
+	which triggered the current changes, but this does not still
+	answer to the question of
+	https://stat.ethz.ch/pipermail/r-sig-ecology/2011-March/001947.html.
+	It would be possible to have this with recursive metaMDSrotate for
+	1..N for first 'vec', then 2..N for the second 'vec', but the
+	later 'vec's could be correlated with previous axes.
 	
 Version 1.18-24 (closed March 10, 2011)
 

Modified: pkg/vegan/man/metaMDS.Rd
===================================================================
--- pkg/vegan/man/metaMDS.Rd	2011-03-10 12:01:00 UTC (rev 1536)
+++ pkg/vegan/man/metaMDS.Rd	2011-03-10 18:35:29 UTC (rev 1537)
@@ -43,7 +43,7 @@
 postMDS(X, dist, pc=TRUE, center=TRUE, halfchange, threshold=0.8,
         nthreshold=10, plot=FALSE, ...)
 metaMDSredist(object, ...)
-metaMDSrotate(object, vec, choices, ...)
+metaMDSrotate(object, vec, ...)
 }
 
 \arguments{



More information about the Vegan-commits mailing list