R: Procrustes analysis. Using singular value decomposition (SVD)...
iProcrustes
R Documentation
Procrustes analysis. Using singular value decomposition (SVD) to
determine a linear transformation to align the
points in X to the points in a reference matrix Y.
Description
Based on generalized Procrustes analysis, this function determines a
linear transformation (rotation/reflection and scalling) of the points in
matrix x to align them to their reference points
in matrix xbar. The alignemnt is carried out by
minimizing the distance between the points in x and xbar.
A numerical matrix to be align to points in xbar, the second
arguement. The columns represents the coordinates of the points. The
matrices x and xbar must have the same dimensions.
xbar
A numerical, reference matrix to which points in matrix x
are to be aligned.
rotation.only
Logical. When rotaion.only is TRUE, it allows the
function to lose reflection component of the linear transformation. Although
it might not give the best-fitting aligenment, when
dealing with flow cytometry data alignment, a non-reflection transformation is
prefered. When rotaion.only is FALSE, it allows the function to
retain the reflection component.
scalling
Logical. When scalling is FALSE, it allows the
function to calculate the linear transformation without a scalling factor.
That is, the returning scalling factor is set to 1.
translate
Logical. Set translate to FALSE when the points in
matrices x and xbar are already centralized prior to applying this function.
When translate is TRUE, it allows the function to translate the
centroid the points in matrix x to that of points in xbar.
Details
Suppose the points in matrix X and ar{X} are centralized
(meaning their centroids are at the origin). The
linear transformation of X for aligning X to its reference
matrix ar{X}., i.e., min ||sXQ - ar{X}||_F, is given by:
Q = VU^T,
and
s = trace(ar{X}^TXQ) / trace(X^T X),
where V and U are the sigular value vectors of ar{X}^T X (that is,
ar{X}^T X = U Σ V^T), and s is the scalling factor.
Value
A list of the linear tranformation with items
Q
An orthogonal, rotation/reflection matrix.
scal
A scalling factor
.
T
(optional) A translation vector used to shift the centroid of the
points in matrix x to the origin. Returned when translate
is TRUE.
T.xbar
(optional) Centered xbar (that is, the centroid
of the points in xbar is translated to the origin). Returned when
translate is TRUE.
Note that the return values of this function do not include the transformed
matrix scal* x* Q or scal*(x-IT)*Q, where T is the
translation vector and I is an n-by-1 vector with elements
1.
## Example 1
x <- matrix(runif(20), nrow=10, ncol=2)+ 1.4
s <- matrix(c(cos(60), -sin(60), sin(60), cos(60)),
nrow=2, ncol=2, byrow=TRUE)
xbar <- 2.2 *(x %*% s) - 0.1
lt <- iProcrustes(x, xbar, translate=TRUE) ## return linear transformation
lt
## showing result
I <- matrix(1, nrow=nrow(x), ncol=1)
tx <- x - I %*% lt$T
## get the transformed matrix xnew
xnew <- lt$scal * (tx %*% lt$Q)
if (require(lattice)) {
xyplot(V1 ~ V2,
do.call(make.groups, lapply(list(x=x, xbar=xbar, T.xbar=lt$T.xbar,
xnew=xnew),as.data.frame)),
group=which, aspect=c(0.7), pch=c(1,3,2,4), col.symbol="black",
main=("Align the points in x to xbar"),
key=list(points=list(pch=c(1,3,2,4), col="black"), space="right",
text=list(c("x", "xbar", "T.xbar", "xnew"))))
}
## Example 2. centralized x and xbar prior to using iProcrustes
x <- matrix(runif(10), nrow=5, ncol=2)
s <- matrix(c(cos(60), -sin(60), sin(60), cos(60)),
nrow=2, ncol=2, byrow=TRUE)
xbar <- 1.2 *(x %*% s) - 2
I <- matrix(1, nrow=nrow(x), ncol=1)
x <- x-(I %*% colMeans(x)) ## shift the centroid of points in x to the origin
xbar <- xbar - (I %*% colMeans(xbar)) ## shift centroid to the origin
lt <- iProcrustes(x, xbar, translate=FALSE) ## return linear transformation
## only return the rotation/reflection matrix and scalling factor
lt
xnew=lt$scal *(x %*% lt$Q) ## transformed matrix aligned to centralized xbar
if (require(lattice)) {
xyplot(V1 ~ V2,
do.call(make.groups, lapply(list(x=x,xbar=xbar,
xnew=xnew), as.data.frame)),
group=which, auto.key=list(space="right"))
}
Results
R version 3.3.1 (2016-06-21) -- "Bug in Your Hair"
Copyright (C) 2016 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.
> library(flowStats)
Loading required package: flowCore
Loading required package: fda
Loading required package: splines
Loading required package: Matrix
Attaching package: 'Matrix'
The following object is masked from 'package:flowCore':
%&%
Attaching package: 'fda'
The following object is masked from 'package:graphics':
matplot
Loading required package: mvoutlier
Loading required package: sgeostat
sROC 0.1-2 loaded
Loading required package: cluster
Loading required package: flowWorkspace
Loading required package: flowViz
Loading required package: lattice
Loading required package: ncdfFlow
Loading required package: RcppArmadillo
Loading required package: BH
Loading required package: gridExtra
> png(filename="/home/ddbj/snapshot/RGM3/R_BC/result/flowStats/iProcrustes.Rd_%03d_medium.png", width=480, height=480)
> ### Name: iProcrustes
> ### Title: Procrustes analysis. Using singular value decomposition (SVD) to
> ### determine a linear transformation to align the points in X to the
> ### points in a reference matrix Y.
> ### Aliases: iProcrustes
>
> ### ** Examples
>
> ## Example 1
> x <- matrix(runif(20), nrow=10, ncol=2)+ 1.4
> s <- matrix(c(cos(60), -sin(60), sin(60), cos(60)),
+ nrow=2, ncol=2, byrow=TRUE)
> xbar <- 2.2 *(x %*% s) - 0.1
>
> lt <- iProcrustes(x, xbar, translate=TRUE) ## return linear transformation
> lt
$T
[1] 1.881520 1.897843
$Q
[,1] [,2]
[1,] -0.9524130 0.3048106
[2,] -0.3048106 -0.9524130
$scal
[1] 2.2
$T.xbar
[,1] [,2]
[1,] 1.0151945 0.52036693
[2,] 0.1876105 -0.97380402
[3,] -1.3480336 -0.47899586
[4,] 0.9808552 -0.07904441
[5,] 0.5582530 -0.11413573
[6,] -0.8546179 0.31452015
[7,] -0.3861145 -0.31097066
[8,] -0.6135420 0.44992692
[9,] -0.5400927 0.57093051
[10,] 1.0004874 0.10120617
>
> ## showing result
> I <- matrix(1, nrow=nrow(x), ncol=1)
> tx <- x - I %*% lt$T
> ## get the transformed matrix xnew
> xnew <- lt$scal * (tx %*% lt$Q)
>
> if (require(lattice)) {
+ xyplot(V1 ~ V2,
+ do.call(make.groups, lapply(list(x=x, xbar=xbar, T.xbar=lt$T.xbar,
+ xnew=xnew),as.data.frame)),
+ group=which, aspect=c(0.7), pch=c(1,3,2,4), col.symbol="black",
+ main=("Align the points in x to xbar"),
+ key=list(points=list(pch=c(1,3,2,4), col="black"), space="right",
+ text=list(c("x", "xbar", "T.xbar", "xnew"))))
+ }
>
> ## Example 2. centralized x and xbar prior to using iProcrustes
> x <- matrix(runif(10), nrow=5, ncol=2)
> s <- matrix(c(cos(60), -sin(60), sin(60), cos(60)),
+ nrow=2, ncol=2, byrow=TRUE)
> xbar <- 1.2 *(x %*% s) - 2
> I <- matrix(1, nrow=nrow(x), ncol=1)
> x <- x-(I %*% colMeans(x)) ## shift the centroid of points in x to the origin
> xbar <- xbar - (I %*% colMeans(xbar)) ## shift centroid to the origin
> lt <- iProcrustes(x, xbar, translate=FALSE) ## return linear transformation
> ## only return the rotation/reflection matrix and scalling factor
> lt
$Q
[,1] [,2]
[1,] -0.9524130 0.3048106
[2,] -0.3048106 -0.9524130
$scal
[1] 1.2
>
> xnew=lt$scal *(x %*% lt$Q) ## transformed matrix aligned to centralized xbar
> if (require(lattice)) {
+ xyplot(V1 ~ V2,
+ do.call(make.groups, lapply(list(x=x,xbar=xbar,
+ xnew=xnew), as.data.frame)),
+ group=which, auto.key=list(space="right"))
+ }
>
>
>
>
>
>
> dev.off()
null device
1
>