├── R ├── .DS_Store ├── deprecated.defunct.r ├── findMeanSpec.r ├── readland.fcsv.r ├── coords.subset.r ├── writeland.tps.r ├── two.d.array.r ├── readmulti.nts.r ├── readmulti.tps.R ├── globalIntegration.r ├── editTemplate.r ├── compare.ZVrel.R ├── geomorph.data.frame.r ├── arrayspecs.r ├── interlmkdist.r ├── digit.curves.r ├── integration.Vrel.r ├── read.ply.r ├── readland.tps.r ├── plotAllSpecimens.r ├── warpRefMesh.r ├── warpRefOutline.r └── shapeHulls.r ├── data ├── lizards.rda ├── mosquito.rda ├── pupfish.rda ├── ratland.rda ├── scallops.rda ├── plethodon.rda ├── pupfish.ws.rda ├── scallopPLY.rda ├── hummingbirds.rda ├── larvalMorph.rda ├── plethspecies.rda └── plethShapeFood.rda ├── tests └── testthat.R ├── .gitignore ├── vignettes └── figs │ ├── fixed.3D.png │ ├── PCAplot2D.png │ ├── tree.plot.png │ ├── example_spec2.png │ └── example_template.png ├── .Rbuildignore ├── man ├── mosquito.Rd ├── ratland.Rd ├── plot.evolrate.Rd ├── print.evolrate.Rd ├── plot.CR.Rd ├── print.evolrate1.Rd ├── print.compare.CR.Rd ├── print.compare.pls.Rd ├── print.CR.Rd ├── print.combined.set.Rd ├── print.compare.ZVrel.Rd ├── print.gm.prcomp.Rd ├── plot.CR.phylo.Rd ├── plot.gpagen.Rd ├── print.gpagen.Rd ├── summary.evolrate.Rd ├── summary.evolrate1.Rd ├── plot.physignal.Rd ├── print.geomorphShapes.Rd ├── summary.compare.CR.Rd ├── print.procD.lm.Rd ├── summary.CR.Rd ├── summary.compare.pls.Rd ├── summary.gm.prcomp.Rd ├── plot.physignal.z.Rd ├── print.CR.phylo.Rd ├── print.physignal.Rd ├── summary.combined.set.Rd ├── summary.compare.ZVrel.Rd ├── summary.geomorphShapes.Rd ├── summary.gpagen.Rd ├── print.compare.physignal.z.Rd ├── print.physignal.z.Rd ├── print.pls.Rd ├── summary.CR.phylo.Rd ├── summary.procD.lm.Rd ├── summary.physignal.Rd ├── print.bilat.symmetry.Rd ├── print.physignal.eigen.Rd ├── scallops.Rd ├── summary.compare.physignal.z.Rd ├── summary.physignal.z.Rd ├── summary.pls.Rd ├── print.morphol.disparity.Rd ├── summary.bilat.symmetry.Rd ├── summary.physignal.eigen.Rd ├── scallopPLY.Rd ├── summary.morphol.disparity.Rd ├── plethspecies.Rd ├── plethShapeFood.Rd ├── plot.mshape.Rd ├── plethodon.Rd ├── plot.bilat.symmetry.Rd ├── hummingbirds.Rd ├── pupfish.Rd ├── geomorph-package.Rd ├── na.omit.geomorph.data.frame.Rd ├── plot.physignal.eigen.Rd ├── pupfish.ws.Rd ├── writeland.tps.Rd ├── readland.fcsv.Rd ├── lizards.Rd ├── plot.pls.Rd ├── larvalMorph.Rd ├── coords.subset.Rd ├── findMeanSpec.Rd ├── readmulti.tps.Rd ├── readmulti.nts.Rd ├── geomorph.data.frame.Rd ├── mshape.Rd ├── two.d.array.Rd ├── interlmkdist.Rd ├── plot.procD.lm.Rd ├── read.ply.Rd ├── plotAllSpecimens.Rd ├── define.links.Rd ├── globalIntegration.Rd ├── editTemplate.Rd ├── compare.ZVrel.Rd ├── arrayspecs.Rd ├── define.modules.Rd ├── integration.Vrel.Rd ├── plot.gm.prcomp.Rd ├── read.morphologika.Rd ├── warpRefOutline.Rd ├── compare.physignal.z.Rd ├── make_ggplot.Rd ├── rotate.coords.Rd ├── readland.nts.Rd ├── plotspec.Rd ├── shapeHulls.Rd ├── digit.curves.Rd ├── warpRefMesh.Rd ├── fixed.angle.Rd ├── plotOutliers.Rd ├── readland.tps.Rd ├── digit.fixed.Rd ├── picknplot.shape.Rd ├── compare.CR.Rd └── digitize2d.Rd ├── geomorph.Rproj ├── cran-comments.md ├── README.md ├── DESCRIPTION └── inst └── CITATION /R/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/R/.DS_Store -------------------------------------------------------------------------------- /data/lizards.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/lizards.rda -------------------------------------------------------------------------------- /data/mosquito.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/mosquito.rda -------------------------------------------------------------------------------- /data/pupfish.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/pupfish.rda -------------------------------------------------------------------------------- /data/ratland.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/ratland.rda -------------------------------------------------------------------------------- /data/scallops.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/scallops.rda -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(RRPP) 3 | 4 | test_check("geomorph") 5 | -------------------------------------------------------------------------------- /data/plethodon.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/plethodon.rda -------------------------------------------------------------------------------- /data/pupfish.ws.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/pupfish.ws.rda -------------------------------------------------------------------------------- /data/scallopPLY.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/scallopPLY.rda -------------------------------------------------------------------------------- /data/hummingbirds.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/hummingbirds.rda -------------------------------------------------------------------------------- /data/larvalMorph.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/larvalMorph.rda -------------------------------------------------------------------------------- /data/plethspecies.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/plethspecies.rda -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rhistory 2 | .Rproj.user 3 | .RData 4 | CRAN-SUBMISSION 5 | .DS_Store 6 | .Rapp.history -------------------------------------------------------------------------------- /data/plethShapeFood.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/data/plethShapeFood.rda -------------------------------------------------------------------------------- /vignettes/figs/fixed.3D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/vignettes/figs/fixed.3D.png -------------------------------------------------------------------------------- /vignettes/figs/PCAplot2D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/vignettes/figs/PCAplot2D.png -------------------------------------------------------------------------------- /vignettes/figs/tree.plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/vignettes/figs/tree.plot.png -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^cran-comments\.md$ 2 | ^CRAN-RELEASE$ 3 | ^.*\.Rproj$ 4 | ^\.Rproj\.user$ 5 | ^CRAN-SUBMISSION$ 6 | -------------------------------------------------------------------------------- /vignettes/figs/example_spec2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/vignettes/figs/example_spec2.png -------------------------------------------------------------------------------- /vignettes/figs/example_template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geomorphR/geomorph/HEAD/vignettes/figs/example_template.png -------------------------------------------------------------------------------- /R/deprecated.defunct.r: -------------------------------------------------------------------------------- 1 | #' Deprecated and defunct functions in geomorph 2 | #' 3 | #' The following function is now defunct 4 | #' 5 | #' 6 | -------------------------------------------------------------------------------- /man/mosquito.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{mosquito} 5 | \alias{mosquito} 6 | \title{Landmarks on mosquito wings} 7 | \description{ 8 | Landmarks on mosquito wings 9 | } 10 | \author{ 11 | Dean Adams 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/ratland.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{ratland} 5 | \alias{ratland} 6 | \title{Landmark data from dataset rat} 7 | \description{ 8 | Landmark data from dataset rat 9 | } 10 | \references{ 11 | Bookstein, F. L. 1991. Morphometric tools for landmark data: Geometry and Biology. 12 | Cambridge Univ. Press, New York. 13 | } 14 | \author{ 15 | Dean Adams 16 | } 17 | \keyword{datasets} 18 | -------------------------------------------------------------------------------- /geomorph.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | ProjectId: 15af3529-6701-4064-b447-f88be690e14c 3 | 4 | RestoreWorkspace: Default 5 | SaveWorkspace: Default 6 | AlwaysSaveHistory: Default 7 | 8 | EnableCodeIndexing: Yes 9 | UseSpacesForTab: Yes 10 | NumSpacesForTab: 2 11 | Encoding: UTF-8 12 | 13 | RnwWeave: Sweave 14 | LaTeX: pdfLaTeX 15 | 16 | LineEndingConversion: None 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageBuildArgs: --md5 22 | -------------------------------------------------------------------------------- /man/plot.evolrate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.evolrate} 4 | \alias{plot.evolrate} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{evolrate}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object} 11 | 12 | \item{...}{other arguments passed to plot} 13 | } 14 | \description{ 15 | Plot Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | \keyword{visualization} 22 | -------------------------------------------------------------------------------- /man/print.evolrate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.evolrate} 4 | \alias{print.evolrate} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{evolrate}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/plot.CR.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.CR} 4 | \alias{plot.CR} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{CR}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object (from \code{\link{phylo.modularity}})} 11 | 12 | \item{...}{other arguments passed to plot} 13 | } 14 | \description{ 15 | Plot Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | \keyword{visualization} 22 | -------------------------------------------------------------------------------- /man/print.evolrate1.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.evolrate1} 4 | \alias{print.evolrate1} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{evolrate1}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.compare.CR.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.compare.CR} 4 | \alias{print.compare.CR} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{compare.CR}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.compare.pls.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.compare.pls} 4 | \alias{print.compare.pls} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{compare.pls}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.CR.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.CR} 4 | \alias{print.CR} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{CR}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object (from \code{\link{phylo.modularity}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.combined.set.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.combined.set} 4 | \alias{print.combined.set} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{combined.set}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.compare.ZVrel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.compare.ZVrel} 4 | \alias{print.compare.ZVrel} 5 | \title{Print/Summary function for geomorph} 6 | \usage{ 7 | \method{print}{compare.ZVrel}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary function for geomorph 16 | } 17 | \author{ 18 | Dean Adams 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.gm.prcomp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.gm.prcomp} 4 | \alias{print.gm.prcomp} 5 | \title{Print/Summary function for geomorph} 6 | \usage{ 7 | \method{print}{gm.prcomp}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary function for geomorph 16 | } 17 | \author{ 18 | Antigoni Kaliontzopoulou 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/plot.CR.phylo.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.CR.phylo} 4 | \alias{plot.CR.phylo} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{CR.phylo}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object (from \code{\link{phylo.modularity}})} 11 | 12 | \item{...}{other arguments passed to plot} 13 | } 14 | \description{ 15 | Plot Function for geomorph 16 | } 17 | \author{ 18 | Dean Adams 19 | } 20 | \keyword{utilities} 21 | \keyword{visualization} 22 | -------------------------------------------------------------------------------- /man/plot.gpagen.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.gpagen} 4 | \alias{plot.gpagen} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{gpagen}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object (from \code{\link{gpagen}})} 11 | 12 | \item{...}{other arguments passed to plotAllSpecimens} 13 | } 14 | \description{ 15 | Plot Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | \keyword{visualization} 22 | -------------------------------------------------------------------------------- /man/print.gpagen.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.gpagen} 4 | \alias{print.gpagen} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{gpagen}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object (from \code{\link{gpagen}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.evolrate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.evolrate} 4 | \alias{summary.evolrate} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{evolrate}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.evolrate1.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.evolrate1} 4 | \alias{summary.evolrate1} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{evolrate1}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/plot.physignal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.physignal} 4 | \alias{plot.physignal} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{physignal}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object (from \code{\link{physignal}})} 11 | 12 | \item{...}{other arguments passed to plot} 13 | } 14 | \description{ 15 | Plot Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | \keyword{visualization} 22 | -------------------------------------------------------------------------------- /man/print.geomorphShapes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.geomorphShapes} 4 | \alias{print.geomorphShapes} 5 | \title{Print/Summary function for geomorph} 6 | \usage{ 7 | \method{print}{geomorphShapes}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.compare.CR.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.compare.CR} 4 | \alias{summary.compare.CR} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{compare.CR}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.procD.lm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.procD.lm} 4 | \alias{print.procD.lm} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{procD.lm}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object (from \code{\link{procD.lm}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.CR.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.CR} 4 | \alias{summary.CR} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{CR}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object (from \code{\link{phylo.modularity}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.compare.pls.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.compare.pls} 4 | \alias{summary.compare.pls} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{compare.pls}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.gm.prcomp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.gm.prcomp} 4 | \alias{summary.gm.prcomp} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{gm.prcomp}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Antigoni Kaliontzopoulou 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/plot.physignal.z.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.physignal.z} 4 | \alias{plot.physignal.z} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{physignal.z}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object (from \code{\link{physignal.z}})} 11 | 12 | \item{...}{other arguments passed to plot} 13 | } 14 | \description{ 15 | Plot Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | \keyword{visualization} 22 | -------------------------------------------------------------------------------- /man/print.CR.phylo.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.CR.phylo} 4 | \alias{print.CR.phylo} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{CR.phylo}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object (from \code{\link{phylo.modularity}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Dean Adams 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.physignal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.physignal} 4 | \alias{print.physignal} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{physignal}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object (from \code{\link{physignal}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.combined.set.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.combined.set} 4 | \alias{summary.combined.set} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{combined.set}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.compare.ZVrel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.compare.ZVrel} 4 | \alias{summary.compare.ZVrel} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{compare.ZVrel}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Dean Adams 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.geomorphShapes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.geomorphShapes} 4 | \alias{summary.geomorphShapes} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{geomorphShapes}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.gpagen.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.gpagen} 4 | \alias{summary.gpagen} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{gpagen}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object (from \code{\link{gpagen}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.compare.physignal.z.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.compare.physignal.z} 4 | \alias{print.compare.physignal.z} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{compare.physignal.z}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.physignal.z.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.physignal.z} 4 | \alias{print.physignal.z} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{physignal.z}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object (from \code{\link{physignal.z}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.pls.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.pls} 4 | \alias{print.pls} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{pls}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object (from \code{\link{phylo.integration}} or \code{\link{two.b.pls}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.CR.phylo.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.CR.phylo} 4 | \alias{summary.CR.phylo} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{CR.phylo}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object (from \code{\link{phylo.modularity}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Dean Adams 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.procD.lm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.procD.lm} 4 | \alias{summary.procD.lm} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{procD.lm}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object (from \code{\link{procD.lm}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.physignal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.physignal} 4 | \alias{summary.physignal} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{physignal}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object (from \code{\link{physignal}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.bilat.symmetry.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.bilat.symmetry} 4 | \alias{print.bilat.symmetry} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{bilat.symmetry}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object (from \code{\link{bilat.symmetry}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.physignal.eigen.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.physignal.eigen} 4 | \alias{print.physignal.eigen} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{physignal.eigen}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object (from \code{\link{physignal.eigen}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Dean Adams 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/scallops.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{scallops} 5 | \alias{scallops} 6 | \title{Landmark data from scallop shells} 7 | \description{ 8 | Landmark data from scallop shells 9 | } 10 | \references{ 11 | Serb et al. (2011). "Morphological convergence of shell shape in distantly related 12 | scallop species (Mollusca: Pectinidae)." Zoological Journal of the Linnean Society 163: 571-584. 13 | } 14 | \author{ 15 | Dean Adams and Erik Otarola-Castillo 16 | } 17 | \keyword{datasets} 18 | -------------------------------------------------------------------------------- /man/summary.compare.physignal.z.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.compare.physignal.z} 4 | \alias{summary.compare.physignal.z} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{compare.physignal.z}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.physignal.z.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.physignal.z} 4 | \alias{summary.physignal.z} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{physignal.z}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object (from \code{\link{physignal.z}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.pls.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.pls} 4 | \alias{summary.pls} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{pls}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object (from \code{\link{phylo.integration}} or \code{\link{two.b.pls}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/print.morphol.disparity.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{print.morphol.disparity} 4 | \alias{print.morphol.disparity} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{print}{morphol.disparity}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{print/summary object (from \code{\link{morphol.disparity}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.bilat.symmetry.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.bilat.symmetry} 4 | \alias{summary.bilat.symmetry} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{bilat.symmetry}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object (from \code{\link{bilat.symmetry}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/summary.physignal.eigen.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.physignal.eigen} 4 | \alias{summary.physignal.eigen} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{physignal.eigen}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object (from \code{\link{physignal.eigen}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Dean Adams 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/scallopPLY.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{scallopPLY} 5 | \alias{scallopPLY} 6 | \title{3D scan of a scallop shell from a .ply file in mesh3d format} 7 | \description{ 8 | 3D scan of a scallop shell from a .ply file in mesh3d format 9 | } 10 | \references{ 11 | Serb et al. (2011). "Morphological convergence of shell shape in distantly related 12 | scallop species (Mollusca: Pectinidae)." Zoological Journal of the Linnean Society 163: 571-584. 13 | } 14 | \author{ 15 | Emma Sherratt 16 | } 17 | \keyword{datasets} 18 | -------------------------------------------------------------------------------- /man/summary.morphol.disparity.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{summary.morphol.disparity} 4 | \alias{summary.morphol.disparity} 5 | \title{Print/Summary Function for geomorph} 6 | \usage{ 7 | \method{summary}{morphol.disparity}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{print/summary object (from \code{\link{morphol.disparity}})} 11 | 12 | \item{...}{other arguments passed to print/summary} 13 | } 14 | \description{ 15 | Print/Summary Function for geomorph 16 | } 17 | \author{ 18 | Michael Collyer 19 | } 20 | \keyword{utilities} 21 | -------------------------------------------------------------------------------- /man/plethspecies.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{plethspecies} 5 | \alias{plethspecies} 6 | \title{Head shape and phylogenetic relationships for several Plethodon salamander species} 7 | \description{ 8 | Head shape and phylogenetic relationships for several Plethodon salamander species 9 | } 10 | \references{ 11 | Phylogeny pruned from: Wiens et al. (2006). Evol. 12 | 13 | Data from: Adams and Rohlf (2000); Adams et al. (2007); Arif et al. (2007) Myers and Adams (2008) 14 | } 15 | \author{ 16 | Dean Adams 17 | } 18 | \keyword{datasets} 19 | -------------------------------------------------------------------------------- /man/plethShapeFood.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{plethShapeFood} 5 | \alias{plethShapeFood} 6 | \title{Head shape and food use data from Plethodon salamanders} 7 | \description{ 8 | Head shape and food use data from Plethodon salamanders 9 | } 10 | \references{ 11 | Adams, D. C., and F. J. Rohlf. 2000. Ecological character 12 | displacement in Plethodon: biomechanical differences found from a geometric 13 | morphometric study. Proceedings of the National Academy of Sciences, 14 | U.S.A. 97:4106-4111 15 | } 16 | \author{ 17 | Dean Adams 18 | } 19 | \keyword{datasets} 20 | -------------------------------------------------------------------------------- /man/plot.mshape.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.mshape} 4 | \alias{plot.mshape} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{mshape}(x, links = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object (from \code{\link{mshape}})} 11 | 12 | \item{links}{An optional matrix defining for links between landmarks} 13 | 14 | \item{...}{other arguments passed to plot} 15 | } 16 | \description{ 17 | Plot Function for geomorph 18 | } 19 | \seealso{ 20 | \code{\link{define.links}} 21 | } 22 | \author{ 23 | Antigoni Kaliontzopoulou 24 | } 25 | \keyword{utilities} 26 | \keyword{visualization} 27 | -------------------------------------------------------------------------------- /man/plethodon.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{plethodon} 5 | \alias{plethodon} 6 | \title{Landmark data from Plethodon salamander heads} 7 | \description{ 8 | Landmark data from Plethodon salamander heads 9 | } 10 | \references{ 11 | Adams, D. C. 2004. Character displacement via aggressive interference in Appalachian salamanders. 12 | Ecology. 85:2664-2670. 13 | 14 | Adams, D.C. 2010. Parallel evolution of character displacement driven by competitive selection 15 | in terrestrial salamanders. BMC Evolutionary Biology. 10(72)1-10. 16 | } 17 | \author{ 18 | Dean Adams 19 | } 20 | \keyword{datasets} 21 | -------------------------------------------------------------------------------- /man/plot.bilat.symmetry.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.bilat.symmetry} 4 | \alias{plot.bilat.symmetry} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{bilat.symmetry}(x, warpgrids = TRUE, mesh = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object (from \code{\link{bilat.symmetry}})} 11 | 12 | \item{warpgrids}{Logical argument whether to include warpgrids} 13 | 14 | \item{mesh}{Option to include mesh in warpgrids plots} 15 | 16 | \item{...}{other arguments passed to plot} 17 | } 18 | \description{ 19 | Plot Function for geomorph 20 | } 21 | \author{ 22 | Michael Collyer 23 | } 24 | \keyword{utilities} 25 | \keyword{visualization} 26 | -------------------------------------------------------------------------------- /man/hummingbirds.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{hummingbirds} 5 | \alias{hummingbirds} 6 | \title{Landmark data from hummingbird bills (includes sliding semilandmarks on curves)} 7 | \description{ 8 | Landmark data from hummingbird bills (includes sliding semilandmarks on curves) 9 | } 10 | \references{ 11 | Berns, C.M., and Adams, D.C. 2010. Bill shape and sexual shape dimorphism between two species 12 | of temperate hummingbirds: Archilochus alexandri (black-chinned hummingbirds) and Archilochus colubris 13 | (ruby-throated hummingbirds). The Auk. 127:626-635. 14 | } 15 | \author{ 16 | Chelsea Berns and Dean Adams 17 | } 18 | \keyword{datasets} 19 | -------------------------------------------------------------------------------- /man/pupfish.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{pupfish} 5 | \alias{pupfish} 6 | \title{Landmarks on pupfish} 7 | \description{ 8 | Landmark data from Cyprindon pecosensis body shapes, with indication of Sex and 9 | Population from which fish were sampled (Marsh or Sinkhole). 10 | } 11 | \details{ 12 | These data were previously aligned 13 | with GPA. Centroid size (CS) is also provided. 14 | } 15 | \references{ 16 | Collyer, M.L., D.J. Sekora, and D.C. Adams. 2015. A method for analysis of phenotypic 17 | change for phenotypes described by high-dimensional data. Heredity. 115: 357-365. 18 | } 19 | \author{ 20 | Michael Collyer 21 | } 22 | \keyword{datasets} 23 | -------------------------------------------------------------------------------- /man/geomorph-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \name{geomorph-package} 4 | \alias{geomorph-package} 5 | \alias{geomorph} 6 | \title{Geometric morphometric analyses for 2D/3D data} 7 | \description{ 8 | Functions in this package allow one to read, manipulate, and digitize landmark data; generate shape 9 | variables via Procrustes analysis for points, curves and surface data, perform statistical analyses 10 | of shape variation and covariation, and provide graphical depictions of shapes and patterns of 11 | shape variation. 12 | } 13 | \section{geomorph TOC}{ 14 | 15 | geomorph-package 16 | } 17 | 18 | \author{ 19 | Dean C. Adams, Michael Collyer, Antigoni Kaliontzopoulou, and Erica Baken 20 | } 21 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Resubmission 2 | This is a patch release, 4.0.10. It also provides several new functions. 3 | 4 | ## Test environments 5 | * local OS X install, R 4.4.2 6 | * win-builder (devel and release) 7 | * R-hub (all platforms) 8 | 9 | ## R CMD check results 10 | There were no ERRORs or WARNINGs. 11 | 12 | ## R-hub check results 13 | Windows: OK 14 | macos: OK 15 | 16 | macos-arm64: 17 | linux-R-devel: 18 | 19 | 1: Warning: 'rgl.init' failed, running with 'rgl.useNULL = TRUE'. 20 | 21 | This caused geomorph to not install on Linux-R-devel and MacOS-Arm64 platforms. This seems to be internal to R-hub and 22 | should have no bearing on the `geomorph 4.0.10` package. 23 | 24 | ## Downstream dependencies 25 | I checked 12 reverse dependencies: 26 | OK: 12 27 | BROKEN: 0 -------------------------------------------------------------------------------- /man/na.omit.geomorph.data.frame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{na.omit.geomorph.data.frame} 4 | \alias{na.omit.geomorph.data.frame} 5 | \title{Handle missing values in rrpp.data.frame objects} 6 | \usage{ 7 | \method{na.omit}{geomorph.data.frame}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{object (from \code{\link{geomorph.data.frame}})} 11 | 12 | \item{...}{further arguments (currently not used)} 13 | } 14 | \description{ 15 | Handle missing values in rrpp.data.frame objects 16 | } 17 | \examples{ 18 | data(plethspecies) 19 | Y.gpa <- gpagen(plethspecies$land, verbose = TRUE) 20 | gdf <- geomorph.data.frame(Y.gpa) 21 | gdf$d <- Y.gpa$procD 22 | gdf$group <- c(rep(1, 4), rep(2, 4), NA) # one unknown group designation 23 | gdf 24 | ndf <- na.omit(gdf) 25 | ndf 26 | } 27 | \author{ 28 | Michael Collyer 29 | } 30 | \keyword{utilities} 31 | -------------------------------------------------------------------------------- /man/plot.physignal.eigen.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.physignal.eigen} 4 | \alias{plot.physignal.eigen} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{physignal.eigen}(x, type = c("conf", "vectors", "both"), confidence = 0.95, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object (from \code{\link{physignal.eigen}})} 11 | 12 | \item{type}{the manner in which the distribution of permuted outcomes is represented: 13 | confidence bands (type = "conf"), vectors (type = "vectors"), or both (type = "both")} 14 | 15 | \item{confidence}{A numerical value designating the confidence interval range} 16 | 17 | \item{...}{other arguments passed to plot} 18 | } 19 | \description{ 20 | Plot Function for geomorph 21 | } 22 | \author{ 23 | Michael Collyer and Dean Adams 24 | } 25 | \keyword{utilities} 26 | \keyword{visualization} 27 | -------------------------------------------------------------------------------- /man/pupfish.ws.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{pupfish.ws} 5 | \alias{pupfish.ws} 6 | \title{Landmarks on pupfish} 7 | \description{ 8 | Landmark data from pupfish body shapes, with indication of Sex, Population and 9 | Species from which fish were sampled. Landmarks represent a subset of those from the 10 | original publication. A phylogeny and phylogenetic covariance matrix are 11 | included. 12 | } 13 | \details{ 14 | These data were previously aligned 15 | with GPA. Centroid size (CS) is also provided. 16 | } 17 | \references{ 18 | Adams, D.C and M.L Collyer. 2024. Extending phylogenetic regression models for 19 | comparing within-species patterns across the tree of life. 20 | Methods in Ecology and Evolution. DOI: 10.1111/2041-210X.14438 21 | } 22 | \author{ 23 | Dean Adams and Michael Collyer 24 | } 25 | \keyword{datasets} 26 | -------------------------------------------------------------------------------- /man/writeland.tps.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/writeland.tps.r 3 | \name{writeland.tps} 4 | \alias{writeland.tps} 5 | \title{Write landmark data to tps file} 6 | \usage{ 7 | writeland.tps(A, file, scale = NULL, specID = TRUE) 8 | } 9 | \arguments{ 10 | \item{A}{A 3D array (p x k x n) containing landmark coordinates for a set of specimens} 11 | 12 | \item{file}{Name of the *.tps file to be created} 13 | 14 | \item{scale}{An optional vector containing the length of the scale for each specimen} 15 | 16 | \item{specID}{A logical value stating whether specimen ID names should be saved to line ID=} 17 | } 18 | \description{ 19 | Write *.tps file from obtain landmark coordinates in a 3-dimensional array 20 | } 21 | \details{ 22 | This function writes a *.tps file from a 3-dimensional array (p x k x n) 23 | of landmark coordinates. 24 | } 25 | \author{ 26 | Dean Adams 27 | } 28 | \keyword{IO} 29 | -------------------------------------------------------------------------------- /man/readland.fcsv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/readland.fcsv.r 3 | \name{readland.fcsv} 4 | \alias{readland.fcsv} 5 | \title{Read landmark data matrix from fcsv file} 6 | \usage{ 7 | readland.fcsv(file = NULL) 8 | } 9 | \arguments{ 10 | \item{file}{The name of a *.fcsv file containing three-dimensional landmark data to be read in} 11 | } 12 | \value{ 13 | Function returns a p x 3 matrix of x, y, z coordinates for p landmarks. 14 | 15 | Note: to read in multiple files the following is useful: 16 | 17 | filelist <- list.files(path = "PATH TO FOLDER with FILES", pattern = "*.fcsv", full.names = TRUE) 18 | 19 | mydata <- simplify2array(lapply(filelist, readland.fcsv)) 20 | } 21 | \description{ 22 | Read landmark data for a single specimen from an fcsv file obtained from SlicerMorph. 23 | } 24 | \details{ 25 | This function merely extracts x, y, z coordinates from an fcsv file. 26 | } 27 | \author{ 28 | Murat Maga, Michael Collyer and Dean Adams 29 | } 30 | \keyword{IO} 31 | -------------------------------------------------------------------------------- /man/lizards.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{lizards} 5 | \alias{lizards} 6 | \title{Dorsal head shape data of lizards} 7 | \description{ 8 | Superimposed landmark data of the dorsal view of lizard heads 9 | } 10 | \details{ 11 | Dataset includes superimposed landmarks (coords), centroid size (cs), an index of individuals (ind) and digitizing repetitions (rep), and a table of symmetrical matching 12 | landmarks (lm.pairs). The object is a \code{\link{geomorph.data.frame}}. 13 | The dataset corresponds to the data for population "b" from Lazic et al. 2015. 14 | } 15 | \references{ 16 | Lazic, M., Carretero, M.A., Crnobrnja-Isailovic, J. & Kaliontzopoulou, A. 2015. Effects of 17 | environmental disturbance on phenotypic variation: an integrated assessment of canalization, developmental 18 | stability, modularity and allometry in lizard head shape. American Naturalist 185: 44-58. 19 | } 20 | \author{ 21 | Antigoni Kaliontzopoulou 22 | } 23 | \keyword{datasets} 24 | -------------------------------------------------------------------------------- /man/plot.pls.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.pls} 4 | \alias{plot.pls} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{pls}(x, label = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{x}{plot object (from \code{\link{phylo.integration}} or \code{\link{two.b.pls}})} 11 | 12 | \item{label}{Optional vector to label points} 13 | 14 | \item{...}{other arguments passed to plot. The function returns values that can be used with 15 | \code{\link{picknplot.shape}} (in a limited capacity). In most cases, greater 16 | flexibility can be attained with using \code{\link{plotRefToTarget}} and \code{\link{shape.predictor}}.} 17 | } 18 | \value{ 19 | If shapes = TRUE, function returns a list containing the shape coordinates of the extreme ends of axis1 and axis2 20 | if 3D arrays were originally provided for each 21 | } 22 | \description{ 23 | Plot Function for geomorph 24 | } 25 | \author{ 26 | Michael Collyer 27 | } 28 | \keyword{utilities} 29 | \keyword{visualization} 30 | -------------------------------------------------------------------------------- /man/larvalMorph.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \docType{data} 4 | \name{larvalMorph} 5 | \alias{larvalMorph} 6 | \title{Head and tail shapes of larval salamanders} 7 | \description{ 8 | Landmark data from heads and tails of larval Salamanders exposed to different treatments of herbicides. 9 | } 10 | \details{ 11 | Data set includes tail landmarks (coords), index for identifying semilandmarks (sliders), and vectors 12 | for variables including herbicide treatment (Treatment) and Family (Family). The latter variable indicates 13 | the egg masses (clutches) sampled in the wild from which individual eggs were randomly assigned to treatment. 14 | See Levis et al. (2016) for more experimental details. 15 | } 16 | \references{ 17 | Levis, N.A, M.L. Schooler, J.R. Johnson, and M.L. Collyer. 2016. The effects of terrestrial and aquatic herbicides on 18 | larval salamander morphology and swim speed. Biological Journal of the Linnean Society. 118:569-581. 19 | } 20 | \author{ 21 | Michael Collyer 22 | } 23 | \keyword{datasets} 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # geomorph 2 | Geomorph is a software package for performing all stages of geometric morphometric shape analysis of 2- and 3-dimensional landmark points, as well as semilandmarks on curves and surfaces, in the R statistical computing environment. This repository is dedicated to providing beta versions between CRAN uploads. 3 | 4 | ### To install the current geomorph R-package from CRAN: 5 | 6 | Within R: 7 | 8 | install.packages("geomorph") 9 | 10 | For Mac users: please also install XQuartz from . This allows the library(rgl) to function. 11 | 12 | ### To install the current version of geomorph R-package from Github using devtools: 13 | 14 | Within R: 15 | 16 | install.packages("devtools") 17 | 18 | devtools::install_github("geomorphR/geomorph", ref = "Stable", build_vignettes = TRUE) 19 | 20 | This installs a stable release of the current version of geomorph on CRAN, allowing us to quickly fix errors that slip thorough the cracks and are uploaded with the CRAN version. 21 | 22 | -------------------------------------------------------------------------------- /man/coords.subset.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/coords.subset.r 3 | \name{coords.subset} 4 | \alias{coords.subset} 5 | \title{Subset landmark coordinates via a factor} 6 | \usage{ 7 | coords.subset(A, group) 8 | } 9 | \arguments{ 10 | \item{A}{A 3D array (p x k x n) containing landmark coordinates for a set of specimens} 11 | 12 | \item{group}{A grouping factor of length n, for splitting the array into sub-arrays} 13 | } 14 | \description{ 15 | Subset (split) landmark coordinates via a grouping factor 16 | } 17 | \details{ 18 | This function splits a set of landmark coordinates into subsets, as described by a factor. The 19 | result is a list of separate sets of landmarks. 20 | } 21 | \examples{ 22 | \dontrun{ 23 | data(pupfish) 24 | group <- factor(paste(pupfish$Pop, pupfish$Sex)) 25 | levels(group) 26 | new.coords <- coords.subset(A = pupfish$coords, group = group) 27 | names(new.coords) # see the list levels 28 | # group shape means 29 | lapply(new.coords, mshape) 30 | } 31 | } 32 | \author{ 33 | Michael Collyer 34 | } 35 | \keyword{utilities} 36 | -------------------------------------------------------------------------------- /man/findMeanSpec.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/findMeanSpec.r 3 | \name{findMeanSpec} 4 | \alias{findMeanSpec} 5 | \title{Identify specimen closest to the mean of a set of Procrustes shape variables} 6 | \usage{ 7 | findMeanSpec(A) 8 | } 9 | \arguments{ 10 | \item{A}{A 3D array (p x k x n) containing landmark coordinates for a set of Procrustes shape variables} 11 | } 12 | \value{ 13 | Function returns the name and address of the specimen closest to the mean of the set of 14 | Procrustes shape variables. 15 | } 16 | \description{ 17 | A function to identify which specimen lies closest to the estimated mean 18 | shape for a set of Procrustes shape variables. 19 | } 20 | \details{ 21 | Function takes a 3D array of Procrustes shape variables (such as made by \code{\link{gpagen}}, 22 | calculates the distance of each to the estimated mean shape, and returns the name and 23 | address of the closest specimen. This function can be used 24 | to identify the specimen to be used by \code{\link{warpRefMesh}}. 25 | } 26 | \seealso{ 27 | \code{\link{warpRefMesh}} 28 | } 29 | \author{ 30 | Emma Sherratt 31 | } 32 | \keyword{utilities} 33 | -------------------------------------------------------------------------------- /man/readmulti.tps.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/readmulti.tps.R 3 | \name{readmulti.tps} 4 | \alias{readmulti.tps} 5 | \title{Read and combine multiple tps files} 6 | \usage{ 7 | readmulti.tps(filelist, ...) 8 | } 9 | \arguments{ 10 | \item{filelist}{A vector containing the file paths to all the tps files to be compiled} 11 | 12 | \item{...}{other arguments to be passed to \code{\link{readland.tps}}} 13 | } 14 | \value{ 15 | Function returns a (p x k x n) array, where p is the number of landmark points, k is the number 16 | of landmark dimensions (2 or 3), and n is the total number of specimens across all tps files included in the folder read. 17 | } 18 | \description{ 19 | Read multiple tps files to obtain landmark coordinates and combine them into a single array 20 | } 21 | \details{ 22 | This is a wrapper of \code{\link{readland.tps}} to allow reading landmark coordinates, in 2D or 3D, from several tps files , and compiling them into an array for proceeding with GM procedures. 23 | 24 | The arguments specID and negNA of \code{\link{readland.tps}} can be directly set through this function. 25 | } 26 | \author{ 27 | Antigoni Kaliontzopoulou 28 | 29 | Michael Collyer 30 | } 31 | -------------------------------------------------------------------------------- /R/findMeanSpec.r: -------------------------------------------------------------------------------- 1 | #' Identify specimen closest to the mean of a set of Procrustes shape variables 2 | #' 3 | #' A function to identify which specimen lies closest to the estimated mean 4 | #' shape for a set of Procrustes shape variables. 5 | #' 6 | #' Function takes a 3D array of Procrustes shape variables (such as made by \code{\link{gpagen}}, 7 | #' calculates the distance of each to the estimated mean shape, and returns the name and 8 | #' address of the closest specimen. This function can be used 9 | #' to identify the specimen to be used by \code{\link{warpRefMesh}}. 10 | #' 11 | #' @param A A 3D array (p x k x n) containing landmark coordinates for a set of Procrustes shape variables 12 | #' @export 13 | #' @seealso \code{\link{warpRefMesh}} 14 | #' @keywords utilities 15 | #' @author Emma Sherratt 16 | #' @return Function returns the name and address of the specimen closest to the mean of the set of 17 | #' Procrustes shape variables. 18 | findMeanSpec <- function(A){ 19 | if(!is.array(A)) { 20 | stop("Data matrix not a 3D array (see 'arrayspecs').") } 21 | ref <- mshape(A) 22 | x <- two.d.array(A) 23 | x <- rbind(x, as.vector(t(ref))) 24 | dists <- as.matrix(dist(x))[,(nrow(x))] 25 | spec <- which(dists == min(dists[dists>0])) 26 | return(spec) 27 | } 28 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: geomorph 2 | Title: Geometric Morphometric Analyses of 2D and 3D Landmark Data 3 | Version: 4.0.10.999 4 | Authors@R: c( 5 | person("Dean", "Adams", , "dcadams@iastate.edu", c("aut", "cre")), 6 | person("Michael", "Collyer", , role = "aut"), 7 | person("Antigoni", "Kaliontzopoulou", , role = "aut"), 8 | person("Erica", "Baken", , role = "aut") 9 | ) 10 | Description: Read, manipulate, and digitize landmark data, generate shape 11 | variables via Procrustes analysis for points, curves and surfaces, perform 12 | shape analyses, and provide graphical depictions of shapes and patterns of 13 | shape variation. 14 | License: GPL (>= 3) 15 | URL: https://github.com/geomorphR/geomorph 16 | Encoding: UTF-8 17 | LazyData: true 18 | RoxygenNote: 7.3.2 19 | Depends: RRPP(>= 2.1.0), rgl, R(>= 4.4.0), Matrix 20 | Imports: graphics, grDevices, stats, utils, jpeg, ape, parallel, ggplot2 21 | Suggests: 22 | knitr, 23 | rmarkdown, 24 | testthat (>= 3.0.0), 25 | dplyr 26 | VignetteBuilder: knitr 27 | NeedsCompilation: no 28 | Packaged: 2025-02-02 29 | Author: Dean Adams [aut, cre], 30 | Michael Collyer [aut], 31 | Antigoni Kaliontzopoulou [aut], 32 | Erica Baken [aut] 33 | Maintainer: Dean Adams 34 | Repository: CRAN 35 | Config/testthat/edition: 3 36 | -------------------------------------------------------------------------------- /R/readland.fcsv.r: -------------------------------------------------------------------------------- 1 | #' Read landmark data matrix from fcsv file 2 | #' 3 | #' Read landmark data for a single specimen from an fcsv file obtained from SlicerMorph. 4 | #' 5 | #' This function merely extracts x, y, z coordinates from an fcsv file. 6 | #' 7 | #' @param file The name of a *.fcsv file containing three-dimensional landmark data to be read in 8 | #' @keywords IO 9 | #' @export 10 | #' @author Murat Maga, Michael Collyer and Dean Adams 11 | #' @return Function returns a p x 3 matrix of x, y, z coordinates for p landmarks. 12 | #' 13 | #' Note: to read in multiple files the following is useful: 14 | #' 15 | #' filelist <- list.files(path = "PATH TO FOLDER with FILES", pattern = "*.fcsv", full.names = TRUE) 16 | #' 17 | #' mydata <- simplify2array(lapply(filelist, readland.fcsv)) 18 | 19 | readland.fcsv = function (file = NULL) { 20 | testfile <- scan(file=file, what="char", quote="", sep="\n", strip.white=TRUE, comment.char="\"", quiet=TRUE) 21 | header_no <- length(grep("#", testfile)) 22 | res <- read.csv(file = file, skip = header_no, header = F)[, 1:4] 23 | res.ind <- res[, 1] 24 | res.nms <- try( 25 | unlist(strsplit(res.ind, "vtkMRMLMarkups")), silent = TRUE) 26 | if(inherits(res.nms, "try-error")) res.nms <- res.ind else 27 | res.nms <- res.nms[seq(2, length(res.nms), 2)] 28 | res <- res[,-1] 29 | rownames(res) <- res.nms 30 | return(as.matrix(res)) 31 | } 32 | -------------------------------------------------------------------------------- /man/readmulti.nts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/readmulti.nts.r 3 | \name{readmulti.nts} 4 | \alias{readmulti.nts} 5 | \title{Read and combine multiple nts files} 6 | \usage{ 7 | readmulti.nts(filelist) 8 | } 9 | \arguments{ 10 | \item{filelist}{A vector containing the file paths to all the nts files to be compiled} 11 | } 12 | \value{ 13 | Function returns a 3D array (p x k x n), where p is the number of landmark points, k is 14 | the number of landmark dimensions (2 or 3), and n is the number of specimens. The third dimension 15 | of this array contains names for each specimen, which are retrieved from the nts specimen labels, 16 | if those are available. Specimens in nts files without labels are named as filename_# where # are consecutive 17 | numbers. 18 | } 19 | \description{ 20 | Read multiple nts (or .dta) files to obtain landmark coordinates and combine them into a single array 21 | } 22 | \details{ 23 | This is a wrapper of \code{\link{readland.nts}} to allow reading landmark coordinates, in 2D or 3D, 24 | from several nts (or .dta) files, and compiling them into an array for proceeding with GM procedures. 25 | 26 | See \code{\link{readland.nts}} for adequately formatting NTS files and requirements that need to be met 27 | for that (and therefore this) function to work correctly. 28 | } 29 | \references{ 30 | Rohlf, F. J. 2012 NTSYSpc: Numerical taxonomy and multivariate analysis system. Version 31 | 2.2. Exeter Software, New York. 32 | } 33 | \author{ 34 | Antigoni Kaliontzopoulou 35 | } 36 | -------------------------------------------------------------------------------- /R/coords.subset.r: -------------------------------------------------------------------------------- 1 | #' Subset landmark coordinates via a factor 2 | #' 3 | #' Subset (split) landmark coordinates via a grouping factor 4 | #' 5 | #' This function splits a set of landmark coordinates into subsets, as described by a factor. The 6 | #' result is a list of separate sets of landmarks. 7 | #' 8 | #' @param A A 3D array (p x k x n) containing landmark coordinates for a set of specimens 9 | #' @param group A grouping factor of length n, for splitting the array into sub-arrays 10 | #' @keywords utilities 11 | #' @export 12 | #' @author Michael Collyer 13 | #' @examples 14 | #' \dontrun{ 15 | #' data(pupfish) 16 | #' group <- factor(paste(pupfish$Pop, pupfish$Sex)) 17 | #' levels(group) 18 | #' new.coords <- coords.subset(A = pupfish$coords, group = group) 19 | #' names(new.coords) # see the list levels 20 | #' # group shape means 21 | #' lapply(new.coords, mshape) 22 | #' } 23 | coords.subset <- function(A, group){ 24 | dims <- dim(A) 25 | if(length(dims) != 3) stop("coordinates must be in the form of a 3D array - consider using arrayspecs") 26 | p <- dims[1]; k <- dims[2]; n <- dims[3] 27 | group <- as.factor(group) 28 | M <- mshape(A); M[M!=0] <- 0 29 | if(length(group) != n) stop("number of specimens do not match between coords and grouping factor") 30 | Y <- as.data.frame(two.d.array(A)) 31 | X <- split(Y, group) 32 | redo <- function(x) { 33 | x <- as.matrix(x) 34 | y <- lapply(1:NROW(x), function(j) M + matrix(x[j,], p, k, byrow = TRUE)) 35 | names(y) <- rownames(x) 36 | simplify2array(y) 37 | } 38 | out <- lapply(X, redo) 39 | out 40 | } 41 | -------------------------------------------------------------------------------- /man/geomorph.data.frame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.data.frame.r 3 | \name{geomorph.data.frame} 4 | \alias{geomorph.data.frame} 5 | \title{Create a data frame with shape data} 6 | \usage{ 7 | geomorph.data.frame(...) 8 | } 9 | \arguments{ 10 | \item{...}{a list of objects to include in the data frame.} 11 | } 12 | \description{ 13 | A list similar to a data frame to facilitate analysis of shape data. 14 | } 15 | \details{ 16 | This function produces a list that can be used like a data frame in other analytical functions. 17 | The purpose is similar to the function, \code{\link[base]{data.frame}}, but without the constraint that 18 | data must conform to an n (observations) x p (variables) matrix. Rather, the list produced is 19 | constrained only by n. List objects can be Procrustes shape variables, matrices, variables, 20 | distance matrices, and phylogenetic trees. Results from \code{\link{gpagen}} can be directly 21 | imported into a geomorph.data.frame to utilize the coordinates and centroid size as variables. (See Examples) 22 | } 23 | \examples{ 24 | \dontrun{ 25 | data(plethodon) 26 | Y.gpa <- gpagen(plethodon$land, PrinAxes = FALSE) 27 | gdf <- geomorph.data.frame(Y.gpa) 28 | attributes(gdf) 29 | 30 | gdf <- geomorph.data.frame(Y.gpa, species = plethodon$species, 31 | site = plethodon$site) 32 | attributes(gdf) 33 | 34 | # Using geomorph.data.frame to facilitate analysis 35 | anova(procD.lm(coords ~ Csize + species * site, data = gdf)) 36 | } 37 | } 38 | \author{ 39 | Michael Collyer 40 | } 41 | \keyword{utilities} 42 | -------------------------------------------------------------------------------- /R/writeland.tps.r: -------------------------------------------------------------------------------- 1 | #' Write landmark data to tps file 2 | #' 3 | #' Write *.tps file from obtain landmark coordinates in a 3-dimensional array 4 | #' 5 | #' This function writes a *.tps file from a 3-dimensional array (p x k x n) 6 | #' of landmark coordinates. 7 | #' 8 | #' @param A A 3D array (p x k x n) containing landmark coordinates for a set of specimens 9 | #' @param file Name of the *.tps file to be created 10 | #' @param scale An optional vector containing the length of the scale for each specimen 11 | #' @param specID A logical value stating whether specimen ID names should be saved to line ID= 12 | #' @export 13 | #' @keywords IO 14 | #' @author Dean Adams 15 | writeland.tps<-function(A, file, scale = NULL, specID = TRUE){ 16 | n<-dim(A)[3] 17 | k<-dim(A)[2] 18 | p<-dim(A)[1] 19 | lmline<-ifelse(k==2,paste("LM=",p,sep=""), paste("LM3=",p,sep="")) 20 | file.create(file, showWarnings=TRUE) 21 | if(!is.null(scale)){ 22 | scaleline<-paste("SCALE", "=", scale, sep="") 23 | } 24 | for(i in 1:n){ 25 | write(lmline,file,append = TRUE) 26 | write.table(A[,,i],file,col.names = FALSE, row.names = FALSE,append=TRUE) 27 | if(!is.null(scale)){ 28 | if(length(scaleline) == 1){write(scaleline,file,append=TRUE)} 29 | if(length(scaleline) > 1){write(scaleline[i],file,append=TRUE)} 30 | } 31 | if(specID==TRUE){ 32 | if(is.null(dimnames(A)[[3]])) dimnames(A)[[3]] <- c(1:dim(A)[3]) 33 | idline<-paste("ID=",dimnames(A)[[3]][i],sep="") 34 | write(idline,file,append = TRUE) 35 | } 36 | write("",file,append = TRUE) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /man/mshape.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.support.code.r 3 | \name{mshape} 4 | \alias{mshape} 5 | \title{Estimate mean shape for a set of aligned specimens} 6 | \usage{ 7 | mshape(A, na.action = 1) 8 | } 9 | \arguments{ 10 | \item{A}{Either a list (length n, p x k), A 3D array (p x k x n), or a matrix (n x pk) containing GPA-aligned coordinates for a set of specimens} 11 | 12 | \item{na.action}{An index for how to treat missing values: 1 = stop analysis; 2 = return NA for coordinates 13 | with missing values for any specimen; 3 = attempt to calculate means for coordinates for all non-missing values.} 14 | } 15 | \description{ 16 | Estimate the mean shape for a set of aligned specimens 17 | } 18 | \details{ 19 | The function estimates the average landmark coordinates for a set of aligned specimens. 20 | Three different methods are available for missing data (see Arguments and Examples). 21 | 22 | One can then use the generic function \code{\link{plot}} to produce a numbered plot of landmark 23 | positions and potentially add links, in order to review landmark positions 24 | } 25 | \examples{ 26 | \dontrun{ 27 | data(plethodon) 28 | Y.gpa <- gpagen(plethodon$land) #GPA-alignment 29 | A <- Y.gpa$coords 30 | A[[1]] <- NA # make a missing value, just for example 31 | 32 | mshape(Y.gpa$coords) # mean (consensus) configuration 33 | # mshape(A, na.action = 1) # will return an error 34 | mshape(A, na.action = 2) # returns NA in spot of missing value 35 | mshape(A, na.action = 3) # finds mean values from all possible values 36 | } 37 | } 38 | \author{ 39 | Antigoni Kaliontzopoulou & Michael Collyer 40 | } 41 | \keyword{utilities} 42 | -------------------------------------------------------------------------------- /man/two.d.array.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/two.d.array.r 3 | \name{two.d.array} 4 | \alias{two.d.array} 5 | \title{Convert (p x k x n) data array into 2D data matrix} 6 | \usage{ 7 | two.d.array(A, sep = ".") 8 | } 9 | \arguments{ 10 | \item{A}{A 3D array (p x k x n) containing landmark coordinates for a set of specimens} 11 | 12 | \item{sep}{An optional argument for variable labeling, combining landmark labels (e.g., 1, 2, 3, ...) 13 | and partial dimension labels (e.g., "x", "y", and "z"), much like the \code{\link{paste}} function. 14 | The default is sep = ".", but this can be changed to any separator. 15 | One should make sure to match separators with \code{\link{arrayspecs}} if switching between matrices and arrays.} 16 | } 17 | \value{ 18 | Function returns a two-dimensional matrix of dimension (n x [p x k]), where rows 19 | represent specimens and columns represent variables. 20 | } 21 | \description{ 22 | Convert a three-dimensional array of landmark coordinates into a two-dimensional matrix 23 | } 24 | \details{ 25 | This function converts a (p x k x n) array of landmark coordinates into a two-dimensional 26 | matrix (n x [p x k]). The latter format of the shape data is useful for performing subsequent statistical 27 | analyses in R (e.g., PCA, MANOVA, PLS, etc.). Row labels are preserved if included in 28 | the original array. 29 | } 30 | \examples{ 31 | \dontrun{ 32 | data(plethodon) 33 | plethodon$land #original data in the form of 3D array 34 | 35 | two.d.array(plethodon$land) # Convert to a 2D data matrix 36 | } 37 | } 38 | \seealso{ 39 | \code{\link{arrayspecs}} 40 | } 41 | \author{ 42 | Dean Adams and Emma Sherratt 43 | } 44 | \keyword{utilities} 45 | -------------------------------------------------------------------------------- /R/two.d.array.r: -------------------------------------------------------------------------------- 1 | #' Convert (p x k x n) data array into 2D data matrix 2 | #' 3 | #' Convert a three-dimensional array of landmark coordinates into a two-dimensional matrix 4 | #' 5 | #' This function converts a (p x k x n) array of landmark coordinates into a two-dimensional 6 | #' matrix (n x [p x k]). The latter format of the shape data is useful for performing subsequent statistical 7 | #' analyses in R (e.g., PCA, MANOVA, PLS, etc.). Row labels are preserved if included in 8 | #' the original array. 9 | #' 10 | #' @param A A 3D array (p x k x n) containing landmark coordinates for a set of specimens 11 | #' @param sep An optional argument for variable labeling, combining landmark labels (e.g., 1, 2, 3, ...) 12 | #' and partial dimension labels (e.g., "x", "y", and "z"), much like the \code{\link{paste}} function. 13 | #' The default is sep = ".", but this can be changed to any separator. 14 | #' One should make sure to match separators with \code{\link{arrayspecs}} if switching between matrices and arrays. 15 | #' 16 | #' @keywords utilities 17 | #' @export 18 | #' @author Dean Adams and Emma Sherratt 19 | #' @return Function returns a two-dimensional matrix of dimension (n x [p x k]), where rows 20 | #' represent specimens and columns represent variables. 21 | #' @seealso \code{\link{arrayspecs}} 22 | #' @examples 23 | #' \dontrun{ 24 | #' data(plethodon) 25 | #' plethodon$land #original data in the form of 3D array 26 | #' 27 | #' two.d.array(plethodon$land) # Convert to a 2D data matrix 28 | #' } 29 | two.d.array<-function(A, sep = "."){ 30 | pxk <- dim(A)[1]*dim(A)[2] 31 | n <- dim(A)[3] 32 | tmp <- aperm(A, c(3,2,1)) 33 | dim(tmp) <- c(n,pxk) 34 | rownames(tmp)<-dimnames(A)[[3]] 35 | colnames(tmp)<-as.vector(t(outer(dimnames(A)[[1]], 36 | dimnames(A)[[2]], 37 | FUN = paste, sep=sep))) 38 | return(tmp) 39 | } 40 | -------------------------------------------------------------------------------- /man/interlmkdist.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/interlmkdist.r 3 | \name{interlmkdist} 4 | \alias{interlmkdist} 5 | \title{Calculate linear distances between landmarks} 6 | \usage{ 7 | interlmkdist(A, lmks) 8 | } 9 | \arguments{ 10 | \item{A}{A 3D array (p x k x n) containing landmark coordinates for a set of specimens} 11 | 12 | \item{lmks}{A matrix or dataframe of landmark addresses for the start and end landmarks defining m linear measurements (can be either 2-x-m or m-x-2). 13 | Either the rows or the columns should have names 'start' and 'end' to define landmarks.} 14 | } 15 | \value{ 16 | Function returns a matrix (n x m) of m linear distances for n specimens 17 | } 18 | \description{ 19 | A function to calculate linear distances between a set of landmark coordinates (interlandmark distances) 20 | } 21 | \details{ 22 | Function takes a 3D array of landmark coordinates from a set of specimens and the addresses for the start 23 | and end landmarks defining linear measurements and then 24 | calculates the interlandmark distances. The function returns a matrix of linear distances for all specimens. 25 | If the 'lmks' matrix has row or column names defining the name of the linear measurements, the returned matrix will use 26 | these for column names (see example). If only two interlandmark distances, 'lmks' input must be m x 2. 27 | } 28 | \examples{ 29 | 30 | \dontrun{ 31 | data(plethodon) 32 | # Make a matrix defining three interlandmark distances 33 | lmks <- matrix(c(8,9,6,12,4,2), ncol=2, byrow=TRUE, 34 | dimnames = list(c("eyeW", "headL", "mouthL"),c("start", "end"))) 35 | 36 | # where 8-9 is eye width; 6-12 is head length; 4-2 is mouth length 37 | # or alternatively 38 | 39 | lmks <- data.frame(eyeW = c(8,9), headL = c(6,12), mouthL = c(4,2), 40 | row.names = c("start", "end")) 41 | 42 | A <- plethodon$land 43 | lineardists <- interlmkdist(A, lmks) 44 | } 45 | } 46 | \author{ 47 | Emma Sherratt & Michael Collyer 48 | } 49 | \keyword{utilities} 50 | -------------------------------------------------------------------------------- /man/plot.procD.lm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.procD.lm} 4 | \alias{plot.procD.lm} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{procD.lm}( 8 | x, 9 | type = c("diagnostics", "regression", "PC"), 10 | outliers = FALSE, 11 | predictor = NULL, 12 | reg.type = c("PredLine", "RegScore"), 13 | ... 14 | ) 15 | } 16 | \arguments{ 17 | \item{x}{plot object (from \code{\link{procD.lm}})} 18 | 19 | \item{type}{Indicates which type of plot, choosing among diagnostics, 20 | regression, or principal component plots. Diagnostic plots are similar to 21 | \code{\link{lm}} diagnostic plots, but for multivariate data. Regression plots 22 | plot multivariate dispersion in some fashion against predictor values. PC plots 23 | project data onto the eigenvectors of the covariance matrix for fitted values.} 24 | 25 | \item{outliers}{Logical argument to include outliers plot, if diagnostics 26 | are performed} 27 | 28 | \item{predictor}{An optional vector if "regression" plot type is chosen, 29 | and is a variable likely used in \code{\link{procD.lm}}. 30 | This vector is a vector of covariate values equal to the number of observations.} 31 | 32 | \item{reg.type}{If "regression" is chosen for plot type, this argument 33 | indicates whether a prediction line 34 | (Predline) plot, or regression score (RegScore) plotting is performed.} 35 | 36 | \item{...}{other arguments passed to plot (helpful to employ 37 | different colors or symbols for different groups). See 38 | \code{\link{plot.default}} and \code{\link{par}}} 39 | } 40 | \value{ 41 | An object of class "plot.procD.lm" is a list with components 42 | that can be used in other plot functions, such as the type of plot, points, 43 | a group factor, and other information depending on the plot parameters used. 44 | } 45 | \description{ 46 | Plot Function for geomorph 47 | } 48 | \author{ 49 | Michael Collyer 50 | } 51 | \keyword{utilities} 52 | \keyword{visualization} 53 | -------------------------------------------------------------------------------- /man/read.ply.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/read.ply.r 3 | \name{read.ply} 4 | \alias{read.ply} 5 | \title{Read mesh data (vertices and faces) from ply files} 6 | \usage{ 7 | read.ply(file, ShowSpecimen = TRUE, addNormals = TRUE) 8 | } 9 | \arguments{ 10 | \item{file}{An ASCII ply file} 11 | 12 | \item{ShowSpecimen}{logical Indicating whether or not the ply file should be displayed} 13 | 14 | \item{addNormals}{logical Indicating whether or not the normals of each vertex should be calculated (using \code{\link[rgl]{addNormals}})} 15 | } 16 | \value{ 17 | Function returns the following components: 18 | \item{mesh3d}{list of class mesh3d- see rgl for details} 19 | } 20 | \description{ 21 | A function to read ply files, which can be used for digitizing landmark coordinates or for shape warps. 22 | } 23 | \details{ 24 | Function reads three-dimensional surface data in the form of a single ply file 25 | (Polygon File Format; ASCII format only, from 3D scanners such as NextEngine and David scanners). 26 | Vertices of the surface may then be used to digitize three-dimensional points, 27 | and semilandmarks on curves and surfaces. The surface may also be used as a mesh for visualizing 3D deformations (\code{\link{warpRefMesh}}). 28 | The function opens the ply file and plots the mesh, 29 | with faces rendered if file contains faces, and colored if the file contains vertex color. 30 | Vertex normals allow better visualization and more accurate digitizing with \code{\link{digit.fixed}}. 31 | } 32 | \examples{ 33 | \dontrun{ 34 | # If the file has no mesh color, or color is undesirable, user can 35 | # assign this as follows: 36 | # Using the example scallop PLY 37 | data(scallopPLY) 38 | myply <- scallopPLY$ply 39 | myply$material$color <- "gray" # using color word 40 | myply$material$color <- "#FCE6C9" # using RGB code 41 | } 42 | } 43 | \seealso{ 44 | \code{\link[rgl]{rgl-package}} (used in 3D plotting) 45 | } 46 | \author{ 47 | Dean Adams & Emma Sherratt 48 | } 49 | \keyword{IO} 50 | -------------------------------------------------------------------------------- /man/plotAllSpecimens.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotAllSpecimens.r 3 | \name{plotAllSpecimens} 4 | \alias{plotAllSpecimens} 5 | \title{Plot landmark coordinates for all specimens} 6 | \usage{ 7 | plotAllSpecimens( 8 | A, 9 | mean = TRUE, 10 | links = NULL, 11 | label = FALSE, 12 | plot_param = list() 13 | ) 14 | } 15 | \arguments{ 16 | \item{A}{A 3D array (p x k x n) containing Procrustes shape variables for a set of specimens} 17 | 18 | \item{mean}{A logical value indicating whether the mean shape should be included in the plot} 19 | 20 | \item{links}{An optional matrix defining for links between landmarks (only if mean=TRUE)} 21 | 22 | \item{label}{A logical value indicating whether landmark numbers will be plotted (only if mean=TRUE)} 23 | 24 | \item{plot_param}{A list of plot parameters for the points (pt.bg, pt.cex), mean (mean.bg, mean.cex), links (link.col, link.lwd, link.lty) and landmark labels (txt.cex, txt.adj, txt.pos, txt.col)} 25 | } 26 | \description{ 27 | Function plots landmark coordinates for a set of specimens 28 | } 29 | \details{ 30 | The function creates a plot of the landmark coordinates for all specimens. This is useful for examining 31 | patterns of variation in Procrustes shape variables, after a GPA has been performed. If "mean = TRUE", the mean shape will be calculated and added to the plot. 32 | Additionally, if a matrix of links is provided, the landmarks of the mean shape will be connected by lines. 33 | The link matrix is an m x 2 matrix, where m is the desired number of links. Each row of the link matrix 34 | designates the two landmarks to be connected by that link. The function will plot either two- or 35 | three-dimensional data (e.g. see \code{\link{define.links}}). 36 | } 37 | \examples{ 38 | \dontrun{ 39 | data(plethodon) 40 | Y.gpa <- gpagen(plethodon$land) #GPA-alignment 41 | 42 | plotAllSpecimens(Y.gpa$coords, links = plethodon$links) 43 | } 44 | } 45 | \seealso{ 46 | \code{\link[rgl]{rgl-package}} (used in 3D plotting) 47 | } 48 | \author{ 49 | Dean Adams 50 | } 51 | \keyword{visualization} 52 | -------------------------------------------------------------------------------- /man/define.links.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/define.links.r 3 | \name{define.links} 4 | \alias{define.links} 5 | \title{Define links between landmarks} 6 | \usage{ 7 | define.links(spec, ptsize = 1, links = NULL) 8 | } 9 | \arguments{ 10 | \item{spec}{Name of specimen, as an object matrix containing 2D or 3D landmark coordinates} 11 | 12 | \item{ptsize}{Numeric Size to plot the landmarks} 13 | 14 | \item{links}{Optional An existing links matrix to add on to} 15 | } 16 | \value{ 17 | Function returns a matrix of which landmarks will be links 18 | to be used by \code{\link{plotAllSpecimens}} & \code{\link{plotRefToTarget}} option 'links='. 19 | } 20 | \description{ 21 | An interactive function to define which landmarks should be linked to aid visualization. 22 | } 23 | \details{ 24 | Function takes a matrix of digitized landmark coordinates (e.g. from \code{\link{mshape}}) and 25 | allows the user to define pairs of landmarks to be linked, for visualization purposes. The output is a matrix 26 | to be used by \code{\link{plotAllSpecimens}} & \code{\link{plotRefToTarget}} option 'links='. 27 | 28 | Note to RStudio users: if the 'zoom' of your RStudio window is set to something other than 100%, 29 | sometimes the function can fail to identify the selected points ('warning: no point within 0.25 inches'). 30 | In these cases, set your zoom to 100%: Tools -> Global Options... -> Appearance -> Zoom: 100%. 31 | 32 | \subsection{Selection}{ 33 | In the plot window select two landmarks that will be linked. In the console, the user will be prompted 34 | to continue linking landmarks to build the wireframe or end the session (typing y or n respectively). 35 | For 2D data in plot window, use LEFT mouse button to select landmarks. 36 | For 3D data in rgl window, use RIGHT mouse button (or command+LEFT for mac) to select landmarks. 37 | } 38 | } 39 | \seealso{ 40 | \code{\link{plotAllSpecimens}} 41 | 42 | \code{\link{plotRefToTarget}} 43 | 44 | \code{\link[rgl]{rgl-package}} (used in 3D plotting) 45 | } 46 | \author{ 47 | Emma Sherratt 48 | } 49 | \keyword{utilities} 50 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite package 'geomorph' in a publication use the first two references. If analyses with RRPP were used, cite the four references:") 2 | 3 | bibentry(bibtype = "Article", 4 | title = "geomorph v4.0 and gmShiny: enhanced analytics and a new graphical interface for a comprehensive morphometric experience.", 5 | author = c(person("E. K.", "Baken"), 6 | person("M. L.", "Collyer"), 7 | person("A.", "Kaliontzopoulou"), 8 | person("D. C.", "Adams")), 9 | year = "2021", 10 | journal = "Methods in Ecology and Evolution", 11 | volume = "12", 12 | pages = "2355-2363") 13 | 14 | bibentry(bibtype = "misc", 15 | title = "Geomorph: Software for geometric morphometric analyses. R package version 4.0.10", 16 | author = c(person("D. C.", "Adams"), 17 | person("M. L.", "Collyer"), 18 | person("A.", "Kaliontzopoulou"), 19 | person("E. K.", "Baken")), 20 | year = "2025", 21 | url = " https://cran.r-project.org/package=geomorph") 22 | 23 | bibentry(bibtype = "misc", 24 | title = "{RRPP}: Linear Model Evaluation with Randomized Residuals in a Permutation Procedure, R package version 2.0.4.", 25 | author = c(person("M. L.", "Collyer"), 26 | person("D. C.", "Adams")), 27 | year = "2024", 28 | url = "https://cran.r-project.org/package=RRPP") 29 | 30 | bibentry(bibtype = "misc", 31 | title = "{RRPP}: An R package for fitting linear models to high‐dimensional data using residual randomization. ", 32 | author = c(person("M. L.", "Collyer"), 33 | person("D. C.", "Adams")), 34 | year = "2018", 35 | journal = "Methods in Ecology and Evolution", 36 | volume = "9", 37 | issue = "2", 38 | pages = "1772-1779") 39 | 40 | citFooter("As geomorph is evolving quickly, you may want to cite also its version number (found with 'library(help = geomorph)'). Additionally, the RRPP package should also be cited for any analyses using RRPP. (See 'library(help = RRPP)' or 'citation('RRPP')'.)") -------------------------------------------------------------------------------- /man/globalIntegration.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/globalIntegration.r 3 | \name{globalIntegration} 4 | \alias{globalIntegration} 5 | \title{Quantify global integration relative to self-similarity} 6 | \usage{ 7 | globalIntegration(A, ShowPlot = TRUE) 8 | } 9 | \arguments{ 10 | \item{A}{3D array (p1 x k x n) containing Procrustes shape variables} 11 | 12 | \item{ShowPlot}{A logical value indicating whether or not the plot should be returned} 13 | } 14 | \description{ 15 | Function quantifies the overall level of morphological integration for a set of Procrustes shape variables 16 | } 17 | \details{ 18 | The function quantifies the overall level of morphological integration for a set of 19 | Procrustes shape coordinates. It is assumed that the landmarks have previously been 20 | aligned using Generalized Procrustes Analysis (GPA) [e.g., with \code{\link{gpagen}}]. 21 | Based on the set of aligned specimens, the function estimates the set of bending energies at various 22 | spatial scales, and plots the log of the variance of the partial warps versus the log of their 23 | corresponding bending energies (Bookstein 2015). The slope of a regression of these data provides information 24 | regarding the degree of overall morphological integration (or lack thereof). 25 | 26 | A slope of negative one corresponds to self-similarity, implying that patterns of shape variation are 27 | similar across spatial scales. Steeper slopes (i.e., those more extreme than -1.0) correspond to data that are globally 28 | integrated, while shallower slopes (between -1 and 0) correspond to data that are 'disintegrated (see Bookstein 2015). Isotropic data 29 | will have an expected slope of zero. 30 | } 31 | \examples{ 32 | \dontrun{ 33 | data(plethodon) 34 | Y.gpa <- gpagen(plethodon$land) #GPA-alignment 35 | 36 | globalIntegration(Y.gpa$coords) 37 | } 38 | } 39 | \references{ 40 | Bookstein, F. L. 2015. Integration, disintegration, and self-similarity: 41 | Characterizing the scales of shape variation in landmark data. Evol. Biol.42(4): 395-426. 42 | } 43 | \author{ 44 | Dean Adams 45 | } 46 | \keyword{analysis} 47 | -------------------------------------------------------------------------------- /man/editTemplate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/editTemplate.r 3 | \name{editTemplate} 4 | \alias{editTemplate} 5 | \title{Edit 3D template} 6 | \usage{ 7 | editTemplate(template, fixed, n) 8 | } 9 | \arguments{ 10 | \item{template}{Matrix of template 3D coordinates} 11 | 12 | \item{fixed}{Number of "fixed" landmark points (non surface sliding points)} 13 | 14 | \item{n}{Number of points to be removed} 15 | } 16 | \value{ 17 | Function returns a matrix containing the x,y,z coordinates of the new template landmarks. 18 | Function also writes to the working directory 'template.txt' containing the x,y,z coordinates of the updated template 19 | } 20 | \description{ 21 | An interactive function to remove landmarks from a 3D template file. 22 | } 23 | \details{ 24 | The function edits a 'template.txt' file made by \code{\link{buildtemplate}}, which must be in the current 25 | working directory, and which is overwritten. Use read.table("template.txt", header = T) to read in the template 26 | first. 27 | \subsection{Selection}{ 28 | Choosing which landmarks will be deleted involves landmark selection using a mouse in the rgl plot window. 29 | With a standard 3-button (PC) buildtemplate uses: 30 | \enumerate{ 31 | \item the RIGHT mouse button (primary) to choose points to be deleted, 32 | \item the LEFT mouse button (secondary) is used to rotate mesh, 33 | \item the mouse SCROLLER (third/middle) is used to zoom in and out. 34 | } 35 | NOTE: Digitizing functions on MACINTOSH computers using a standard 3-button mice works as specified. Macs using platform 36 | specific single button mice, XQuartz must be configured: go to Preferences > Input > tick "Emulate three button mouse": 37 | \enumerate{ 38 | \item press button to rotate 3D mesh, 39 | \item press button while pressing COMMAND key to select points to be deleted, 40 | \item press button while pressing OPTION key to adjust mesh perspective. 41 | \item the mouse SCROLLER or trackpad two finger scroll is used to zoom in an out. 42 | } 43 | } 44 | } 45 | \seealso{ 46 | \code{\link[rgl]{rgl-package}} (used in 3D plotting) 47 | } 48 | \author{ 49 | Erik Otarola-Castillo & Emma Sherratt 50 | } 51 | \keyword{digitizing} 52 | -------------------------------------------------------------------------------- /man/compare.ZVrel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compare.ZVrel.R 3 | \name{compare.ZVrel} 4 | \alias{compare.ZVrel} 5 | \title{Comparisons of Effect Sizes from Overall Integration Analyses} 6 | \usage{ 7 | compare.ZVrel(..., two.tailed = TRUE) 8 | } 9 | \arguments{ 10 | \item{...}{saved analyses of class rel.eig} 11 | 12 | \item{two.tailed}{A logical value to indicate whether a two-tailed test (typical and default) should be performed.} 13 | } 14 | \value{ 15 | An object of class compare.rel.eig, returns a list of the following 16 | 17 | \item{sample.Re.obs}{A vector of observed Vrel for each sample.} 18 | \item{sample.Z.obs}{A vector of effect sizes for each sample.} 19 | \item{sample.Z.var}{A vector of variances for each effect size.} 20 | \item{pairwise.z}{A matrix of pairwise, two-sample z scores between all pairs of effect sizes.} 21 | \item{pairwise.p}{A matrix of corresponding P-values.} 22 | } 23 | \description{ 24 | Function performs an analysis to compare the effect sizes of two or more Vrel effects 25 | } 26 | \details{ 27 | The function statistically compares the effect sizes of two or more Vrel analyses. Typically, this 28 | function might be used to compare the strength of integration in one dataset as compared with another 29 | (see Conaway and Adams 2022). 30 | 31 | The analysis performs two-sample z-tests based on effect sizes (Z-scores) of Vrel. The method 32 | follows that of Conaway Adams (2022) used to compare the strength of integration across datasets. 33 | 34 | To use this function, simply perform \code{\link{integration.Vrel}} on as many samples or as desired. 35 | Any number of objects of class rel.eig can be input. One may perform the comparison as either a 36 | one-tailed or a two-tailed (default) test. 37 | } 38 | \examples{ 39 | \dontrun{ 40 | data("plethodon") 41 | Y.gpa <- gpagen(plethodon$land) 42 | 43 | coords.gp <- coords.subset(Y.gpa$coords, plethodon$species) 44 | Vrel.gp <- Map(function(x) integration.Vrel(x), coords.gp) 45 | 46 | out <- compare.ZVrel(Vrel.gp$Jord, Vrel.gp$Teyah) 47 | 48 | summary(out) 49 | } 50 | } 51 | \references{ 52 | Conaway, M.A., and D.C. Adams. 2022. An effect size for comparing the strength of 53 | morphological integration across studies. Evolution. 76: 2244-2259. 54 | } 55 | \author{ 56 | Dean Adams 57 | } 58 | \keyword{analysis} 59 | -------------------------------------------------------------------------------- /man/arrayspecs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/arrayspecs.r 3 | \name{arrayspecs} 4 | \alias{arrayspecs} 5 | \title{Convert landmark data matrix into array (p x k x n)} 6 | \usage{ 7 | arrayspecs(A, p, k, sep = NULL) 8 | } 9 | \arguments{ 10 | \item{A}{A matrix containing landmark coordinates for a set of specimens} 11 | 12 | \item{p}{Number of landmarks} 13 | 14 | \item{k}{Number of dimensions (2 or 3)} 15 | 16 | \item{sep}{An optional argument to attempt to separate variable names into 17 | landmark dimension 18 | and landmark number variables. For example, X.1, Y.1, Z.1, X.2, Y.2, Z.2, 19 | ..., can be separated 20 | with sep = ".", such that rows of landmark configurations are labeled 1, 2, 21 | 3, ..., and columns 22 | are labeled X, Y, Z. Note, for variables, X1, Y1, Z1, X2, Y2, Z2, ..., 23 | where no separator is evident, use sep = "". Any illogical separation 24 | argument will result in unlabeled 25 | variables. If sep = NULL (the default), unlabeled variables are forced. 26 | This is a good idea if the original matrix 27 | has landmarks out of order (as the the landmark labels might not sort as 28 | expected).} 29 | } 30 | \value{ 31 | Function returns a 3D array (p x k x n), where p is the number of 32 | landmark points, k is the 33 | number of landmark dimensions (2 or 3), and n is the number of specimens. 34 | The third dimension of 35 | this array contains names for each specimen if specified in the original 36 | input matrix. 37 | } 38 | \description{ 39 | Convert a matrix of landmark coordinates into a three-dimensional array 40 | } 41 | \details{ 42 | This function converts a matrix of landmark coordinates into a 3D array (p x 43 | k x n), 44 | which is the required input format for many functions in geomorph. 45 | The input matrix can be arranged such that the coordinates 46 | of each landmark are found on a separate row, or that each row contains all 47 | landmark 48 | coordinates for a single specimen. 49 | } 50 | \examples{ 51 | \dontrun{ 52 | 53 | x <- matrix(rnorm(18), nrow = 3) # Random triangles (all coordinates on same 54 | # row for each triangle) 55 | arrayspecs(x, 3, 2) 56 | 57 | x2 <- matrix(rnorm(18), ncol = 2) # Random triangles (each landmark on its 58 | # own row) 59 | arrayspecs(x2, 3, 2) 60 | } 61 | } 62 | \seealso{ 63 | \code{\link{two.d.array}} 64 | } 65 | \author{ 66 | Dean Adams & Mike Collyer 67 | } 68 | \keyword{utilities} 69 | -------------------------------------------------------------------------------- /R/readmulti.nts.r: -------------------------------------------------------------------------------- 1 | #' Read and combine multiple nts files 2 | #' 3 | #' Read multiple nts (or .dta) files to obtain landmark coordinates and combine them into a single array 4 | #' 5 | #' This is a wrapper of \code{\link{readland.nts}} to allow reading landmark coordinates, in 2D or 3D, 6 | #' from several nts (or .dta) files, and compiling them into an array for proceeding with GM procedures. 7 | #' 8 | #' See \code{\link{readland.nts}} for adequately formatting NTS files and requirements that need to be met 9 | #' for that (and therefore this) function to work correctly. 10 | #' 11 | #' 12 | #' @param filelist A vector containing the file paths to all the nts files to be compiled 13 | #' @author Antigoni Kaliontzopoulou 14 | #' @return Function returns a 3D array (p x k x n), where p is the number of landmark points, k is 15 | #' the number of landmark dimensions (2 or 3), and n is the number of specimens. The third dimension 16 | #' of this array contains names for each specimen, which are retrieved from the nts specimen labels, 17 | #' if those are available. Specimens in nts files without labels are named as filename_# where # are consecutive 18 | #' numbers. 19 | #' @references Rohlf, F. J. 2012 NTSYSpc: Numerical taxonomy and multivariate analysis system. Version 20 | #' 2.2. Exeter Software, New York. 21 | #' @export 22 | 23 | 24 | readmulti.nts <- function(filelist){ 25 | nts.list <- filelist 26 | 27 | file.ext <- substr(nts.list, nchar(nts.list)-3, nchar(nts.list)) 28 | if(!all(file.ext%in%c(".nts", ".NTS", ".dta", ".DTA"))) 29 | stop("File list includes files in a format other than nts or dta, please ammend") 30 | 31 | dt.dims <- sapply(1:length(nts.list), function(x){ 32 | dim(readland.nts(nts.list[x])) 33 | }, simplify = T) 34 | p1 <- dt.dims[1, 1]; k1 <- dt.dims[2, 1]; n1 <- dt.dims[3, 1] 35 | 36 | if(any(dt.dims[1,]!=p1)) stop("Input tps files include different numbers of landmarks, please correct") 37 | if(any(dt.dims[2,]!=k1)) stop("Input tps files include landmarks in different dimensions (2D and 3D), please correct") 38 | 39 | all.lms <- NULL 40 | for(f in 1:length(nts.list)){ 41 | lms <- two.d.array(readland.nts(nts.list[f])) 42 | if(is.null(rownames(lms))) { 43 | rownames(lms) <- paste(nts.list[f], 1:nrow(lms), sep = "_") 44 | } 45 | all.lms <- rbind(all.lms, lms) 46 | } 47 | all.lms <- arrayspecs(all.lms, p1, k1) 48 | 49 | return(all.lms) 50 | } 51 | -------------------------------------------------------------------------------- /man/define.modules.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/define.modules.r 3 | \name{define.modules} 4 | \alias{define.modules} 5 | \title{Define modules (landmark partitions)} 6 | \usage{ 7 | define.modules(spec, nmodules) 8 | } 9 | \arguments{ 10 | \item{spec}{A p x k matrix containing landmark coordinates of a single specimen (2D or 3D)} 11 | 12 | \item{nmodules}{Number of modules to be defined} 13 | } 14 | \value{ 15 | Function returns a vector of which landmarks belong in which module (e.g. 1, 1, 1, 2, 2, 3, 3, 3, 2) to be used 16 | with \code{\link{modularity.test}} or \code{\link{integration.test}}. 17 | } 18 | \description{ 19 | An interactive function to define which landmarks should be assigned to each module (landmark partition). 20 | } 21 | \details{ 22 | Function takes a matrix of digitized landmark coordinates (e.g. from \code{\link{mshape}}) and allows the user to assign 23 | landmarks to each module. The output is a list of which 24 | landmarks belong in which partition, to be used by \code{\link{modularity.test}} or \code{\link{integration.test}}. 25 | 26 | \subsection{Selection in 2D}{ 27 | Choosing which landmarks will be included in each module involves landmark selection using a mouse in 28 | the plot window. The user is prompted to select each landmark in turn to be assigned to module 1: using the LEFT mouse button 29 | (or regular button for Mac users), click on the hollow circle to choose the landmark. Selected landmarks 30 | will be filled in. When all landmarks for module 1 are chosen, press 'esc', and then start selecting 31 | landmarks for module 2. Repeat until all modules are defined. 32 | } 33 | 34 | \subsection{Selection in 3D}{ 35 | Choosing which landmarks will be included in each module involves landmark selection using a mouse in 36 | the rgl plot window. The user is prompted to select one or more landmarks. To do so, use the RIGHT mouse button 37 | (or command + LEFT button for Mac users), draw a rectangle around landmarks to select. 38 | Selected landmarks will be colored yellow. Then type into the console a letter (e.g. 1, 2, 3...) to assign selected landmark(s) 39 | to this module. Repeat until all landmarks are assigned to modules. 40 | } 41 | } 42 | \seealso{ 43 | \code{\link{modularity.test}} and \code{\link{integration.test}} 44 | 45 | \code{\link[rgl]{rgl-package}} (used in 3D plotting) 46 | } 47 | \author{ 48 | Emma Sherratt 49 | } 50 | \keyword{utilities} 51 | -------------------------------------------------------------------------------- /man/integration.Vrel.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/integration.Vrel.r 3 | \name{integration.Vrel} 4 | \alias{integration.Vrel} 5 | \title{Quantify integration in a set of traits} 6 | \usage{ 7 | integration.Vrel(A, phy = NULL) 8 | } 9 | \arguments{ 10 | \item{A}{A 3D array (p x k x n) containing Procrustes shape variables for all specimens, or a matrix (n x variables)} 11 | 12 | \item{phy}{A phylogenetic tree of class = "phylo" - see \code{\link[ape]{read.tree}} in library ape} 13 | } 14 | \value{ 15 | Objects of class "rel.eig" from integration.Vrel return a list of the following: 16 | \item{Re.obs}{The observed relative eigenvalue index (Vrel).} 17 | \item{Z.obs}{The associated Z-score, which represents the effect size of Vrel.} 18 | \item{ZR}{The effect size translated to a positive scale (so that no integration is ZR = 0).} 19 | \item{ZR.var}{The variance of the effect size.} 20 | } 21 | \description{ 22 | Function quantifies the morphological integration in a set of traits 23 | } 24 | \details{ 25 | The function quantifies the strength of morphological integration in a set of variables. 26 | Here the set of traits are treated as a single unit, and the overall degree of covariation in them 27 | is quantified using the relative eigenvalue index: Vrel (Pavlicev et al. 2009). Following 28 | Conaway and Adams (2022), only the non-trivial dimensions of variation are used in the calculation of Vrel. 29 | The measure is then converted to an effect size (Z-score), based on the procedures in Conaway and Adams (2022). 30 | These may be used in subsequent comparisons of the strength of integration across datasets. 31 | Input for the analysis may be a 3D array of Procrustes coordinates, of a matrix of variables. If the observations 32 | are species related by a phylogeny, the phylogeny may also be included. 33 | } 34 | \examples{ 35 | \dontrun{ 36 | data(plethodon) 37 | Y.gpa <- gpagen(plethodon$land) #GPA-alignment 38 | integration.Vrel(Y.gpa$coords) 39 | } 40 | } 41 | \references{ 42 | Pavlicev, M., J. M. Cheverud, and G. P. Wagner. 2009. Measuring morphological 43 | integration using eigenvalue variance. Evolutionary Biology 36:157-170. 44 | 45 | Conaway, M.A., and D.C. Adams. 2022. An effect size for comparing the strength of 46 | morphological integration across studies. Evolution. 76: 2244-2259. 47 | } 48 | \seealso{ 49 | \code{\link{compare.ZVrel}} 50 | } 51 | \author{ 52 | Dean Adams 53 | } 54 | \keyword{analysis} 55 | -------------------------------------------------------------------------------- /man/plot.gm.prcomp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/geomorph.utils.r 3 | \name{plot.gm.prcomp} 4 | \alias{plot.gm.prcomp} 5 | \title{Plot Function for geomorph} 6 | \usage{ 7 | \method{plot}{gm.prcomp}( 8 | x, 9 | axis1 = 1, 10 | axis2 = 2, 11 | flip = NULL, 12 | phylo = FALSE, 13 | time.plot = FALSE, 14 | phylo.par = NULL, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{x}{An object of class \code{\link{gm.prcomp}}} 20 | 21 | \item{axis1}{A value indicating which PC axis should be displayed as the X-axis (default = PC1)} 22 | 23 | \item{axis2}{A value indicating which PC axis should be displayed as the Y-axis (default = PC2)} 24 | 25 | \item{flip}{An argument that if not NULL can be used to flip components in the plot. 26 | The values need to match axis1 or axis2. For example, if axis1 = 3 and axis2 = 4, flip = 1 will not 27 | change either axis; flip = 3 will flip only the horizontal axis; flip = c(3, 4) will flip both axes.} 28 | 29 | \item{phylo}{A logical value indicating whether the phylogeny should be projected to PC space} 30 | 31 | \item{time.plot}{A logical value indicating if a 3D plot with the phylogeny and time as the 32 | z-axis is desired} 33 | 34 | \item{phylo.par}{A list of plotting parameters for the inclusion of a phylogeny, including: logicals for 35 | whether features should be included (tip.labels, nodel.labels, anc.states), toggled as TRUE/FALSE; 36 | edge parameters (edge.color, edge.width, edge.lty); node parameters (node.bg, node.pch, node.cex); 37 | and label parameters (tip.txt.cex, tip.txt.col, tip.txt.adj, node.txt.cex, node.txt.col, node.txt.adj).} 38 | 39 | \item{...}{other arguments passed to plot. For plots with a phylogeny, these parameters pertain to 40 | the tip values.} 41 | } 42 | \value{ 43 | An object of class "plot.gm.prcomp" is a list with components 44 | that can be used in other plot functions, such as the type of plot, points, 45 | a group factor, and other information depending on the plot parameters used. A time plot 46 | is an addendum to the normal 2D plot, and does not add additional output. 47 | 48 | NOTE: To visualize shape variation across PC axes in 2d plots, use \code{\link{picknplot.shape}}. 49 | } 50 | \description{ 51 | Plot Function for geomorph 52 | } 53 | \seealso{ 54 | \code{\link{plotRefToTarget}} \code{\link{picknplot.shape}} 55 | } 56 | \author{ 57 | Antigoni Kaliontzopoulou, Michael Collyer 58 | } 59 | \keyword{utilities} 60 | \keyword{visualization} 61 | -------------------------------------------------------------------------------- /man/read.morphologika.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/read.morphologika.r 3 | \name{read.morphologika} 4 | \alias{read.morphologika} 5 | \title{Read landmark data from Morphologika file(s)} 6 | \usage{ 7 | read.morphologika(filelist) 8 | } 9 | \arguments{ 10 | \item{filelist}{The name of a Morphologika *.txt file containing two- or three-dimensional landmark data. 11 | Alternatively, a character vector of names of Morphologika *.txt file (such as made using \code{\link{list.files}})} 12 | } 13 | \value{ 14 | Function returns a (p x k x n) array of the coordinate data. If other optional headers are present in 15 | the file (e.g. "[labels]" or "[wireframe]") function returns a list containing the "coords" array, 16 | and data matrix of "labels" and or "wireframe". 17 | } 18 | \description{ 19 | Read Morphologika file (*.txt) to obtain landmark coordinates and specimen information 20 | } 21 | \details{ 22 | This function reads a *.txt file in the Morphologika format containing two- or three-dimensional 23 | landmark coordinates. Morphologika files are text files in one of the standard formats for 24 | geometric morphometrics (see O'Higgins and Jones 1998,2006). If multiple morphologika files 25 | are specified (containing the same number of landmarks for all specimens), function returns a single object for files. 26 | 27 | If the headers "labels", "labelvalues" and "groups" are present, then a data matrix containing all 28 | individual specimen information is returned. 29 | If the header "wireframe" is present, then a matrix of the landmark addresses for the wireframe is 30 | returned (see \code{\link{plotRefToTarget}} option 'links'). 31 | If the header "polygon" is present, then a matrix of the landmark addresses for the polygon wireframe is returned (see \code{\link[rgl]{polygon3d}} or \code{\link[graphics]{polygon}}). 32 | 33 | NOTE: For multiple morphologika files that each contain only a single specimen (such as those exported from 34 | Stratovan Checkpoint software), one can add specimen names to 35 | the returned 3D array by: dimnames(mydata)[[3]] <- gsub (".txt", "", filelist)). 36 | } 37 | \references{ 38 | O'Higgins P and Jones N (1998) Facial growth in Cercocebus torquatus: An application of three 39 | dimensional geometric morphometric techniques to the study of morphological variation. Journal of Anatomy. 40 | 193: 251-272 41 | 42 | O'Higgins P and Jones N (2006) Tools for statistical shape analysis. Hull York Medical School. 43 | } 44 | \author{ 45 | Emma Sherratt & Erik Otarola-Castillo 46 | } 47 | \keyword{IO} 48 | -------------------------------------------------------------------------------- /man/warpRefOutline.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/warpRefOutline.r 3 | \name{warpRefOutline} 4 | \alias{warpRefOutline} 5 | \title{Creates a 2D outline warped to the mean shape} 6 | \usage{ 7 | warpRefOutline(file, coord, ref) 8 | } 9 | \arguments{ 10 | \item{file}{A .txt or .csv file of the outline point coordinates, or a .TPS file with OUTLINES= or CURVES= elements} 11 | 12 | \item{coord}{A p x k matrix of 2D fixed landmark coordinates} 13 | 14 | \item{ref}{A p x k matrix of 2D coordinates made by \code{\link{mshape}}} 15 | } 16 | \value{ 17 | Function returns an outline object 18 | } 19 | \description{ 20 | A function to take an outline (defined by many points) and use thin-plate spline method to warp the outline 21 | into the estimated mean shape for a set of aligned specimens. 22 | } 23 | \details{ 24 | Function takes an outline (defined by many points) with a set of fixed landmark coordinates and uses the thin-plate spline method (Bookstein 1989) 25 | to warp the outline into the shape defined by a second set of landmark coordinates, usually those of the 26 | mean shape for a set of aligned specimens. It is highly recommended that the mean shape is used as the 27 | reference for warping (see Rohlf 1998). The workflow is as follows: 28 | \enumerate{ 29 | \item {Calculate the mean shape using \code{\link{mshape}}} 30 | \item{Choose an actual specimen to use for the warping. The specimen used as the template for this warping 31 | is recommended as one most similar in shape to the average of the sample, but can be any reasonable 32 | specimen - do this by eye, or use \code{\link{findMeanSpec}} } 33 | \item{Warp this specimen into the mean shape using \code{\link{warpRefOutline}} } 34 | \item{Use this average outline where it asks for a outline= in the analysis functions and visualization functions } 35 | } 36 | The returned outline object is for use in geomorph 37 | functions where shape deformations are plotted (\code{\link{picknplot.shape}}, 38 | \code{\link{two.b.pls}}, \code{\link{bilat.symmetry}}, and \code{\link{plotRefToTarget}}). 39 | } 40 | \references{ 41 | Bookstein, F. L. 1989 Principal Warps: Thin-Plate Splines and the Decomposition 42 | of Deformations. IEEE Transactions on Pattern Analysis and Machine Intelligence 11(6):567-585. 43 | 44 | Rohlf, F. J. 1998. On Applications of Geometric Morphometrics to Studies of Ontogeny and Phylogeny. Systematic Biology. 47:147-158. 45 | } 46 | \seealso{ 47 | \code{\link{findMeanSpec}} 48 | } 49 | \author{ 50 | Emma Sherratt 51 | } 52 | \keyword{utilities} 53 | \keyword{visualization} 54 | -------------------------------------------------------------------------------- /man/compare.physignal.z.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compare.physign.z.r 3 | \name{compare.physignal.z} 4 | \alias{compare.physignal.z} 5 | \title{Comparisons of Phylogenetic Signal Effect Sizes} 6 | \usage{ 7 | compare.physignal.z(..., two.tailed = TRUE) 8 | } 9 | \arguments{ 10 | \item{...}{saved analyses of class physignal.z} 11 | 12 | \item{two.tailed}{A logical value to indicate whether a two-tailed test (typical and default) should be performed.} 13 | } 14 | \value{ 15 | An object of class compare.physignal.z, returns a list of the following 16 | \item{sample.z}{A vector of effect sizes for each sample.} 17 | \item{sample.r.sd}{A vector of standard deviations for each sampling distribution (following Box-Cox transformation).} 18 | \item{pairwise.z}{A matrix of pairwise, two-sample z scores between all pairs of effect sizes.} 19 | \item{pairwise.p}{A matrix of corresponding P-values.} 20 | } 21 | \description{ 22 | Function performs an analysis to compare the effect sizes of two or more phylogenetic effect sizes 23 | } 24 | \details{ 25 | The function statistically compares the effect sizes of two or more \code{\link{physignal.z}} analyses. 26 | This can be performed on different traits from the same tree, same or different traits from different 27 | trees, or modules of landmark configurations. 28 | 29 | To use this function, perform \code{\link{physignal.z}} on as many samples as desired. 30 | Any number of objects of class physignal.z can be input. Note that some values of Z can be NaN, 31 | if the scaling parameter, lambda, is optimized at 0. In these cases, the standard error is also 0, 32 | and pairwise comparisons might not make sense. 33 | } 34 | \examples{ 35 | \dontrun{ 36 | 37 | # Example: Compare phylogenetic signal of head components in Plethodon 38 | 39 | data(plethspecies) 40 | Y.gpa <- gpagen(plethspecies$land) #GPA-alignment 41 | 42 | ## landmarks of the jaw and cranium 43 | jaw <- 1:5 44 | cranium <- 6:11 45 | 46 | PS.jaw <- physignal.z(A = Y.gpa$coords[jaw,,], phy = plethspecies$phy, 47 | lambda = "front", PAC.no = 7, iter=999) 48 | 49 | PS.cranium <- physignal.z(A = Y.gpa$coords[cranium,,], phy = plethspecies$phy, 50 | lambda = "front", PAC.no = 7, iter=999) 51 | 52 | PS.list <-list(PS.jaw, PS.cranium) 53 | names(PS.list) <- c("jaw", "cranium") 54 | 55 | PS.Z <- compare.physignal.z(PS.list) 56 | summary(PS.Z) 57 | } 58 | } 59 | \references{ 60 | Collyer, M.L., E.K. Baken, & D.C. Adams. 2022. A standardized effect size for evaluating 61 | and comparing the strength of phylogenetic signal. Methods in Ecology and Evolution. 13:367-382. 62 | } 63 | \author{ 64 | Michael Collyer 65 | } 66 | \keyword{analysis} 67 | -------------------------------------------------------------------------------- /man/make_ggplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/make_ggplot.r 3 | \name{make_ggplot} 4 | \alias{make_ggplot} 5 | \title{Convert geomorph plots to ggplot objects} 6 | \usage{ 7 | make_ggplot(object) 8 | } 9 | \arguments{ 10 | \item{object}{A plot object produced from \code{\link{plot.gm.prcomp}}, 11 | \code{\link{plot.pls}},\code{\link{plot.procD.lm}}, or \code{\link{plotAllometry}}. 12 | For \code{\link{plot.procD.lm}} objects, only types "PC" or "regression" 13 | should work.} 14 | } 15 | \description{ 16 | Function attempts to coerce plot information from a geomorph plot object to an 17 | amenable ggplot object. 18 | } 19 | \details{ 20 | This function will attempt to use the plot arguments from an geomorph plot object 21 | to make a ggplot that can be additionally updated, as desired. Not all plot 22 | characteristics might be converted. Nonetheless, a ggplot will be coerced and could 23 | be updated, according to user preference. 24 | 25 | This function assumes no responsibility for arguments made by \code{\link[ggplot2]{ggplot}}. 26 | It merely produces a ggplot object that should resemble a geomorph plot default. Any 27 | augmentation of ggplot objects can be done either by direct intervention of the ggplot 28 | produced or reformatting the initial geomorph plot produced. One should not expect direct 29 | correspondence between R base plot parameters and ggplot parameters. 30 | } 31 | \examples{ 32 | \dontrun{ 33 | 34 | ### PLS Example 35 | data(plethodon) 36 | Y.gpa <- gpagen(plethodon$land) #GPA-alignment 37 | landmarks on the skull and mandible assigned to partitions 38 | land.gps <- c("A","A","A","A","A","B","B","B","B","B","B","B") 39 | IT <- integration.test(Y.gpa$coords, partition.gp = land.gps, iter = 999) 40 | summary(IT) # Test summary 41 | P <- plot(IT) # PLS plot 42 | make_ggplot(P) # same plot in ggplot 43 | 44 | ### Allometry example 45 | 46 | data(plethodon) 47 | Y.gpa <- gpagen(plethodon$land, print.progress = FALSE) #GPA-alignment 48 | 49 | gdf <- geomorph.data.frame(Y.gpa, site = plethodon$site, 50 | species = plethodon$species) 51 | 52 | fit <- procD.lm(coords ~ Csize * species * site, data=gdf, iter=0, 53 | print.progress = FALSE) 54 | 55 | P <- plotAllometry(fit, size = gdf$Csize, logsz = TRUE, method = "PredLine", 56 | pch = 19, col = as.numeric(interaction(gdf$species, gdf$site))) 57 | 58 | make_ggplot(P) 59 | 60 | ### Tangent Space plot 61 | 62 | data(plethspecies) 63 | Y.gpa <- gpagen(plethspecies$land) #GPA-alignment 64 | 65 | PCA.w.phylo <- gm.prcomp(Y.gpa$coords, phy = plethspecies$phy) 66 | P <- plot(PCA.w.phylo, phylo = TRUE, main = "PCA.w.phylo") 67 | make_ggplot(P) 68 | } 69 | } 70 | \author{ 71 | Michael Collyer 72 | } 73 | \keyword{utilities} 74 | -------------------------------------------------------------------------------- /R/readmulti.tps.R: -------------------------------------------------------------------------------- 1 | #' Read and combine multiple tps files 2 | #' 3 | #' Read multiple tps files to obtain landmark coordinates and combine them into a single array 4 | #' 5 | #' This is a wrapper of \code{\link{readland.tps}} to allow reading landmark coordinates, in 2D or 3D, from several tps files , and compiling them into an array for proceeding with GM procedures. 6 | #' 7 | #' The arguments specID and negNA of \code{\link{readland.tps}} can be directly set through this function. 8 | #' 9 | #' 10 | #' @param filelist A vector containing the file paths to all the tps files to be compiled 11 | #' @param ... other arguments to be passed to \code{\link{readland.tps}} 12 | #' @author Antigoni Kaliontzopoulou 13 | #' @author Michael Collyer 14 | #' @return Function returns a (p x k x n) array, where p is the number of landmark points, k is the number 15 | #' of landmark dimensions (2 or 3), and n is the total number of specimens across all tps files included in the folder read. 16 | #' @export 17 | 18 | readmulti.tps <- function(filelist, ... ){ 19 | tps.list <- filelist 20 | readland.args <- list(...) 21 | if(is.null(readland.args$specID)) readland.args$specID <- "None" 22 | if(is.null(readland.args$negNA)) readland.args$negNA <- FALSE 23 | if(is.null(readland.args$readcurves)) 24 | readland.args$readcurves <- FALSE 25 | if(is.null(readland.args$warnmsg)) readland.args$warnmsg <- FALSE 26 | 27 | file.ext <- substr(tps.list, nchar(tps.list)-3, nchar(tps.list)) 28 | if(!all(file.ext%in%c(".tps", ".TPS"))) 29 | stop("\nFile list includes files in a format other than tps, please ammend", 30 | call. = FALSE) 31 | 32 | readland.args$file <- tps.list[[1]] 33 | all.lms <- lapply(1:length(tps.list), function(j){ 34 | readland.args$file <- tps.list[[j]] 35 | do.call(.readland.tps, readland.args) 36 | }) 37 | 38 | specnames <- unlist(lapply(all.lms, names)) 39 | if(readland.args$specID == "None") specnames <- 1:length(specnames) 40 | if(length(unique(specnames)) < length(specnames)) 41 | warning("\n\nInput files seem to include repeated specimen names.\n", 42 | call. = FALSE) 43 | 44 | lm.tab<- do.call(cbind, lapply(all.lms, function(x) sapply(x, dim))) 45 | lm.check <- apply(lm.tab, 1, unique) 46 | bad.lm <- is.list(lm.check) 47 | 48 | if(bad.lm) { 49 | lmo <- t(lm.tab) 50 | colnames(lmo) <- c("p", "k") 51 | } else { 52 | lmo <- unlist(all.lms, recursive = FALSE) 53 | names(lmo) <- specnames 54 | lmo <- simplify2array(lmo) 55 | } 56 | 57 | if(bad.lm) { 58 | cat("\nInput tps files include either different numbers of landmarks\n") 59 | cat("or different dimensions (2D or 3D) for some landmarks.\n\n") 60 | cat("A table of dimensions is returned rather than an array, so the issue can be investigated.\n\n") 61 | print(lmo) 62 | } 63 | 64 | return(lmo) 65 | } 66 | -------------------------------------------------------------------------------- /man/rotate.coords.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rotate.coords.R 3 | \name{rotate.coords} 4 | \alias{rotate.coords} 5 | \title{Rotate or flip landmark or coordinate configurations} 6 | \usage{ 7 | rotate.coords( 8 | A, 9 | type = c("flipX", "flipY", "rotateC", "rotateCC"), 10 | index = NULL 11 | ) 12 | } 13 | \arguments{ 14 | \item{A}{One of either an array of landmark coordinates (p, 2, n dimensions for n specimens and p 2D points), 15 | a class gpagen object, or a p x 2 matrix for a single specimen.} 16 | 17 | \item{type}{The type of rotation or flip to be performed. Specimens can be flipped with respect to x or y axes, 18 | or rotated clockwise (C) or counter-clockwise (CC).} 19 | 20 | \item{index}{An index to indicate which specimens should be rotated or flipped. If NULL (default) 21 | all specimens are rotated. A binary index (0 = do not rotate; 1 = rotate) as a vector with the same length as 22 | the number of specimens will direct which specimens are manipulated. A factor with two levels or a numeric vector with 23 | two any two values can also be used. 24 | The second level (or larger value) will be the level manipulated. For example, a factor with levels = c("a", "b") 25 | will rotate specimens matching level "b". This function might be useful for reflecting specimens with bilateral structures.} 26 | } 27 | \description{ 28 | Function to rotate or flip 2D landmark or coordinate configurations to re-orientate them, as desired. 29 | } 30 | \details{ 31 | This function will allow a user to rotate or flip one or several configurations of raw landmarks or 32 | Procrustes residuals from GPA, as desired. This function only works with two-dimensional configurations. 33 | This is a useful tool if importing coordinates or performing GPA produces undesired orientations (such as flipping 34 | configurations upside down, when aligning them to their PCs). It is not as useful with 3D coordinates, as the plotting tools 35 | for 3D coordinates already have built-in rotation capabilities. 36 | 37 | The function returns an object of the same class as input, after having rotated or flipped 38 | the coordinates of each specimen. If multiple steps are required, the function 39 | can be used in a recursive fashion. 40 | } 41 | \examples{ 42 | \dontrun{ 43 | data(plethodon) 44 | Y.gpa <- gpagen(plethodon$land) 45 | plot(Y.gpa) 46 | Y.gpa2 <- rotate.coords(Y.gpa, "flipX") 47 | plot(Y.gpa2) 48 | Y.gpa3 <- rotate.coords(Y.gpa2, "rotateCC") 49 | plot(Y.gpa3) 50 | 51 | spec1 <- Y.gpa$coords[,,1] 52 | plot(spec1, asp = 1) 53 | spec1 <- rotate.coords(spec1, "flipY") 54 | plot(spec1, asp = 1) 55 | 56 | specs1to3 <- Y.gpa$coords[,,1:3] 57 | plotAllSpecimens(specs1to3) 58 | specs1to3 <- rotate.coords(specs1to3, "rotateC") 59 | plotAllSpecimens(specs1to3) 60 | } 61 | } 62 | \author{ 63 | Michael Collyer 64 | } 65 | \keyword{utilities} 66 | -------------------------------------------------------------------------------- /man/readland.nts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/readland.nts.r 3 | \name{readland.nts} 4 | \alias{readland.nts} 5 | \title{Read landmark data matrix from nts file} 6 | \usage{ 7 | readland.nts(file) 8 | } 9 | \arguments{ 10 | \item{file}{the name of a *.nts file containing two- or three-dimensional landmark data to be read in} 11 | } 12 | \value{ 13 | Function returns a 3D array (p x k x n), where p is the number of landmark points, k is the number 14 | of landmark dimensions (2 or 3), and n is the number of specimens. The third dimension of this array 15 | contains names for each specimen, which are obtained from the names in the *.nts file (if included). 16 | } 17 | \description{ 18 | Read single *.nts file containing landmark coordinates for one or more specimens 19 | } 20 | \details{ 21 | Function reads a single *.nts file containing two- or three-dimensional landmark coordinates. 22 | 23 | NTS files are text files in one of the standard formats for geometric morphometrics (see Rohlf 2012). 24 | Multiple specimen format: 25 | The parameter line contains 5 or 6 elements, and must begin with a "1" to designate a rectangular 26 | matrix. The second and third values designate how many specimens (n) and how many total variables 27 | (p x k) are in the data matrix. The fourth value is a "0" if the data matrix is complete and a "1" 28 | if there are missing values. If missing values are present, the '1' is followed by the arbitrary 29 | numeric code used to represent missing values (e.g., -999). These values will be replaced with "NA" 30 | in the output array. Subsequent analyses requires a full complement of data, see \code{\link{estimate.missing}}. 31 | The final value of the parameter line denotes the dimensionality of the landmarks 32 | (2,3) and begins with "DIM=". If specimen and variable labels are included, these are designated placing 33 | an "L" immediately following the specimen or variable values in the parameter file. The labels then 34 | precede the data matrix. 35 | 36 | Missing data may also be represented by designating them using 'NA'. In 37 | this case, the standard NTSYS header is used with no numeric designation for missing data (i.e. the fourth value is '0'). 38 | The positions of missing landmarks may then be estimated using estimate.missing. 39 | 40 | Special NTS files: *.dta files in the written by IDAV Landmark Editor, 41 | and *.nts files written by Stratovan Checkpoint have incorrect 42 | header notation; every header is 1 n p-x-k 1 9999 Dim=3, rather than 1 n p-x-k 0 Dim=3, which denotes 43 | that missing data is in the file even when it is not. Users must change manually the header (in a text editor) before using this function 44 | } 45 | \references{ 46 | Rohlf, F. J. 2012 NTSYSpc: Numerical taxonomy and multivariate analysis system. Version 47 | 2.2. Exeter Software, New York. 48 | } 49 | \seealso{ 50 | \code{\link{readmulti.nts}} 51 | } 52 | \author{ 53 | Dean Adams & Emma Sherratt 54 | } 55 | \keyword{IO} 56 | -------------------------------------------------------------------------------- /man/plotspec.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotspec.r 3 | \name{plotspec} 4 | \alias{plotspec} 5 | \title{Plot 3D specimen, fixed landmarks and surface semilandmarks} 6 | \usage{ 7 | plotspec( 8 | spec, 9 | digitspec, 10 | fixed = NULL, 11 | fixed.pt.col = "red", 12 | fixed.pt.size = 10, 13 | mesh.ptsize = 1, 14 | centered = FALSE, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{spec}{An object of class shape3d/mesh3d, or matrix of 3D vertex coordinates.} 20 | 21 | \item{digitspec}{Name of data matrix containing 3D fixed and/or surface sliding coordinates.} 22 | 23 | \item{fixed}{Numeric The number of fixed template landmarks (listed first in digitspec)} 24 | 25 | \item{fixed.pt.col}{The color for plotting fixed template landmarks (if any)} 26 | 27 | \item{fixed.pt.size}{The size for plotting fixed template landmarks (if any)} 28 | 29 | \item{mesh.ptsize}{Numeric Size to plot the mesh points (vertices), e.g. 0.1 for dense meshes, 3 for sparse meshes} 30 | 31 | \item{centered}{Logical Whether the data matrix is in the surface mesh coordinate system (centered = "FALSE") or 32 | if the data were collected after the mesh was centered (centered = "TRUE")- see details.} 33 | 34 | \item{...}{additional parameters which will be passed to rgl-plot3d or 35 | rgl-points3d.} 36 | } 37 | \description{ 38 | A function to plot three-dimensional (3D) specimen along with its landmarks. 39 | } 40 | \details{ 41 | Function to plot 3D specimens along with their digitized "fixed" landmarks and semilandmarks 42 | "surface sliders" and "curve sliders". If specimen is a 3D surface (class shape3d/mesh3d) mesh is plotted. 43 | For visualization purposes, 3D coordinate data collected using \code{\link{digit.fixed}} or 44 | \code{\link{digitsurface}} and \code{\link{buildtemplate}} prior to build 1.1-6 were centered by default. 45 | Therefore use this function with centered = "TRUE". Data collected outside geomorph should be read using 46 | centered = "FALSE". The function assumes the fixed landmarks are listed at the beginning of 47 | the coordinate matrix (digitspec). 48 | 49 | This function is a wrapper for several functions in the \code{rgl} package. 50 | Although there is some allowance for arguments to be passed to \code{rgl} functions, 51 | some override of rgl-plot3d arguments is required. Errors that result from trying 52 | to pass rgl-plot3d or rgl-points3d arguments should inspire the user 53 | to find solutions with \code{rgl} core functions. 54 | } 55 | \examples{ 56 | \dontrun{ 57 | 58 | data(scallopPLY) 59 | ply <- scallopPLY$ply 60 | digitdat <- scallopPLY$coords 61 | plotspec(spec = ply, digitspec = digitdat, fixed = 16, 62 | centered = TRUE, fixed.pt.col = "red", 63 | fixed.pt.size = 15, col = "blue", size = 5) 64 | } 65 | } 66 | \seealso{ 67 | \code{\link{warpRefMesh}} 68 | 69 | \code{\link{read.ply}} 70 | 71 | \code{rgl} (used in 3D plotting) 72 | } 73 | \author{ 74 | Erik Otarola-Castillo, Emma Sherratt, Antigoni Kaliontzopoulou, & Michael Collyer 75 | } 76 | \keyword{visualization} 77 | -------------------------------------------------------------------------------- /R/globalIntegration.r: -------------------------------------------------------------------------------- 1 | #' Quantify global integration relative to self-similarity 2 | #' 3 | #' Function quantifies the overall level of morphological integration for a set of Procrustes shape variables 4 | #' 5 | #' The function quantifies the overall level of morphological integration for a set of 6 | #' Procrustes shape coordinates. It is assumed that the landmarks have previously been 7 | #' aligned using Generalized Procrustes Analysis (GPA) [e.g., with \code{\link{gpagen}}]. 8 | #' Based on the set of aligned specimens, the function estimates the set of bending energies at various 9 | #' spatial scales, and plots the log of the variance of the partial warps versus the log of their 10 | #' corresponding bending energies (Bookstein 2015). The slope of a regression of these data provides information 11 | #' regarding the degree of overall morphological integration (or lack thereof). 12 | #' 13 | #' A slope of negative one corresponds to self-similarity, implying that patterns of shape variation are 14 | #' similar across spatial scales. Steeper slopes (i.e., those more extreme than -1.0) correspond to data that are globally 15 | #' integrated, while shallower slopes (between -1 and 0) correspond to data that are 'disintegrated (see Bookstein 2015). Isotropic data 16 | #' will have an expected slope of zero. 17 | #' 18 | #' @param A 3D array (p1 x k x n) containing Procrustes shape variables 19 | #' @param ShowPlot A logical value indicating whether or not the plot should be returned 20 | #' @export 21 | #' @keywords analysis 22 | #' @author Dean Adams 23 | #' @references Bookstein, F. L. 2015. Integration, disintegration, and self-similarity: 24 | #' Characterizing the scales of shape variation in landmark data. Evol. Biol.42(4): 395-426. 25 | #' 26 | #' @examples 27 | #' \dontrun{ 28 | #' data(plethodon) 29 | #' Y.gpa <- gpagen(plethodon$land) #GPA-alignment 30 | #' 31 | #' globalIntegration(Y.gpa$coords) 32 | #' } 33 | 34 | globalIntegration<-function(A,ShowPlot=TRUE){ 35 | ref<-mshape(A) 36 | p<-dim(ref)[1]; k<-dim(ref)[2] 37 | Pdist<-as.matrix(dist(ref)) 38 | if(k==2){P<-Pdist^2*log(Pdist^2)}; if(k==3){P<- -Pdist} 39 | P[which(is.na(P))]<-0 40 | Q<-cbind(1, ref) 41 | L<-rbind(cbind(P,Q), cbind(t(Q),matrix(0,k+1,k+1))) 42 | Linv<-solve(L) 43 | L.be<-Linv[1:p,1:p] 44 | eig.L<-eigen(L.be, symmetric = TRUE) 45 | if(any(Im(eig.L$values)==0)) eig.L$values<-Re(eig.L$values) 46 | if(any(Im(eig.L$vectors)==0)) eig.L$vectors<-Re(eig.L$vectors) 47 | BE<-eig.L$values[1:(p-3)]; if(k==3){BE<-BE[1:(p-4)]} 48 | lambda <- zapsmall(eig.L$values) 49 | if(any(lambda == 0)){BE = lambda[lambda > 0]} 50 | Emat<- eig.L$vectors[,1:(length(BE))] 51 | BEval<-log(BE) 52 | Wmat<-NULL 53 | for (i in 1:dim(A)[[3]]){ 54 | Wvec<-matrix(t(t(A[,,i])%*%Emat),nrow=1) 55 | Wmat<-rbind(Wmat,Wvec) 56 | } 57 | Wvar<-diag(var(Wmat)) 58 | Tmpvar<-matrix(Wvar,nrow=k,byrow=T); PWvar<-log(apply(Tmpvar,2,sum)) 59 | start<-which.min(BEval) 60 | slope<-coef(lm(PWvar~BEval))[2] 61 | eq<-bquote(ObservedSlope [black] == .(slope)) 62 | if(ShowPlot==TRUE){ 63 | plot(BEval,PWvar,asp=1,main=eq) 64 | abline(lm(PWvar~BEval),lwd=2,col="black") 65 | lines(c(BEval[start],BEval[start]+10),c(PWvar[start],PWvar[start]-10),lty=3,lwd=2,col="red")} 66 | return(slope) 67 | } 68 | -------------------------------------------------------------------------------- /man/shapeHulls.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/shapeHulls.r 3 | \name{shapeHulls} 4 | \alias{shapeHulls} 5 | \title{Update Plots with Convex Hulls for Groups} 6 | \usage{ 7 | shapeHulls( 8 | x, 9 | groups = NULL, 10 | group.cols = NULL, 11 | group.lwd = NULL, 12 | group.lty = NULL 13 | ) 14 | } 15 | \arguments{ 16 | \item{x}{A \code{\link{plot.procD.lm}} or \code{\link{plot.gm.prcomp}} plot object.} 17 | 18 | \item{groups}{An optional vector or factor to define groups for hull. If NULL, only one hull will be generated for all points.} 19 | 20 | \item{group.cols}{An optional vector to define hull colors, arranged in the same order as factor levels. If NULL and if multiple groups 21 | exist, the general R color sequence (black, red, green, blue, etc.) will be used.} 22 | 23 | \item{group.lwd}{An optional vector equal in length to the number of group levels, and arranged in the order of group levels, 24 | to modify hull line width.} 25 | 26 | \item{group.lty}{An optional vector equal in length to the number of group levels, and arranged in the order of group levels, 27 | to modify hull line type.} 28 | } 29 | \description{ 30 | This function is used to update \code{\link{plot.procD.lm}} and \code{\link{plot.gm.prcomp}} ordination plot 31 | objects with convex hulls for different groups. If no groups are defined (groups is NULL) just a single 32 | convex hull will be returned. Groups do not need to be a factor in the original \code{\link{procD.lm}} fit. 33 | } 34 | \details{ 35 | This function is a wrapper for the \code{\link{points}} function. It is intentionally limited, so 36 | as to not interfere with other plot parameter adjustments. 37 | } 38 | \examples{ 39 | \dontrun{ 40 | # Via procD.lm and plot.procD.lm 41 | 42 | data("pupfish") 43 | gdf <- geomorph.data.frame(coords = pupfish$coords, Sex = pupfish$Sex, 44 | Pop = pupfish$Pop) 45 | fit <- procD.lm(coords ~ Pop * Sex, data = gdf, print.progress = FALSE) 46 | pc.plot <- plot(fit, type = "PC", pch = 19) 47 | shapeHulls(pc.plot) 48 | 49 | pc.plot <- plot(fit, type = "PC", pch = 19) 50 | groups <- interaction(gdf$Pop, gdf$Sex) 51 | 52 | shapeHulls(pc.plot, groups = groups, 53 | group.cols = c("dark red", "dark red", "dark blue", "dark blue"), 54 | group.lwd = rep(2, 4), group.lty = c(2, 1, 2, 1)) 55 | 56 | legend("topright", levels(groups), 57 | col = c("dark red", "dark red", "dark blue", "dark blue"), 58 | lwd = rep(2,4), lty = c(2, 1, 2, 1)) 59 | 60 | pc.plot <- plot(fit, type = "PC", pch = 19) 61 | shapeHulls(pc.plot, groups = gdf$Sex, group.cols = c("black", "black"), 62 | group.lwd = rep(2, 2), group.lty = c(2, 1)) 63 | legend("topright", levels(gdf$Sex), lwd = 2, lty = c(2, 1)) 64 | 65 | # Via gm.prcomp and plot.gm.prcomp 66 | 67 | data(plethspecies) 68 | Y.gpa <- gpagen(plethspecies$land) #GPA-alignment 69 | pleth.phylo <- gm.prcomp(Y.gpa$coords, phy = plethspecies$phy) 70 | summary(pleth.phylo) 71 | 72 | pc.plot <- plot(pleth.phylo, phylo = TRUE) 73 | gp <- factor(c(rep(1, 5), rep(2, 4))) 74 | shapeHulls(pc.plot, groups = gp, group.cols = 1:2, 75 | group.lwd = rep(2, 2), group.lty = c(2, 1)) 76 | legend("topright", c("P. cinereus clade", "P. hubrichti clade"), 77 | col = 1:2, lwd = 2, lty = c(2, 1)) 78 | } 79 | } 80 | \seealso{ 81 | \code{\link{procD.lm}} 82 | } 83 | \author{ 84 | Michael Collyer 85 | } 86 | \keyword{utilities} 87 | -------------------------------------------------------------------------------- /man/digit.curves.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/digit.curves.r 3 | \name{digit.curves} 4 | \alias{digit.curves} 5 | \title{Calculate semilandmarks along a curve} 6 | \usage{ 7 | digit.curves(start, curve, nPoints, closed = TRUE) 8 | } 9 | \arguments{ 10 | \item{start}{A numeric vector of x,y,(z) coordinates for the landmark defining the start of the curve (can be simply first point on open outline: curve[1,])} 11 | 12 | \item{curve}{A matrix (p x k) of 2D or 3D coordinates for a set of ordered points defining a curve} 13 | 14 | \item{nPoints}{Numeric how many semilandmarks to place equidistantly along the curve (not counting beginning and end points)} 15 | 16 | \item{closed}{Logical Whether the curve is closed (TRUE) or open (FALSE)} 17 | } 18 | \value{ 19 | Function returns a matrix of coordinates for nPoints equally spaced semilandmarks sampled along the curve (plus start and end if 'closed = F', or only including start if 'closed = T') 20 | } 21 | \description{ 22 | A function that "digitizes curves" by calculating equidistant two-dimensional or three-dimensional semilandmarks along 23 | a curve. These landmarks will be treated as "sliders" in Generalized Procrustes analysis \code{\link{gpagen}}. This 24 | type of semilandmark "slides" along curves lacking known landmarks (see Bookstein 1997 for algorithm details). Each 25 | sliding semilandmark ("sliders") will slide between two designated points, along a line tangent to the specified 26 | curvature, as specified by \code{\link{define.sliders}}. 27 | } 28 | \details{ 29 | The function is based upon tpsDig2 'resample curve by length' for 2D data by James Rohlf (Rohlf 2015). 30 | The start of the curve is a fixed landmark on the curve that is equivalent (homologous) in each specimen in the 31 | sample (and will be treated as a fixed point during Procrustes Superimposition using \code{\link{gpagen}}). Then 32 | nPoints are calculated along the curve at equidistant points from the start to the end. 33 | 34 | 'curve' is a p-x-k matrix of 2D or 3D coordinates for a set of ordered points defining a curve. This can be the pixels 35 | of an outline calculated in ImageJ (save xy coordinates) or any other reasonable way of obtaining ordered coordinates 36 | along a curve (including sampling by hand using \code{\link{digit.fixed}} or \code{\link{digitize2d}} - but note 37 | that there should be more points defining the curve than nPoints in order to accurately calculate the semilandmarks). 38 | 39 | If 'closed = T', the function returns the coordinates of the 'start' landmark plus nPoints. If 'closed = F', the 40 | function returns the coordinates of the 'start' landmark, plus nPoints and the end of the curve. 41 | 42 | If unsure if the points defining the curve are ordered, then plot and color them using the rainbow function, 43 | e.g. plot(curve, pch=19, cex=0.1, col=rainbow(nrow(outline))), and it should be easy to visualize. 44 | } 45 | \references{ 46 | Bookstein, F. J. 1997 Landmark Methods for Forms without Landmarks: Morphometrics of 47 | Group Differences in Outline Shape. Medical Image Analysis 1(3):225-243. 48 | 49 | Rohlf, F.J., 2015. The tps series of software. Hystrix 26(1):9-12. 50 | } 51 | \seealso{ 52 | \code{\link{digit.fixed}} \code{\link{digitize2d}} 53 | } 54 | \author{ 55 | Emma Sherratt and Michael Collyer 56 | } 57 | \keyword{digitizing} 58 | -------------------------------------------------------------------------------- /man/warpRefMesh.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/warpRefMesh.r 3 | \name{warpRefMesh} 4 | \alias{warpRefMesh} 5 | \title{Creates a mesh3d object warped to the mean shape} 6 | \usage{ 7 | warpRefMesh(mesh, mesh.coord, ref, color = NULL, centered = FALSE) 8 | } 9 | \arguments{ 10 | \item{mesh}{A mesh3d object (e.g. made by \code{\link{read.ply}})} 11 | 12 | \item{mesh.coord}{A p x k matrix of 3D coordinates digitized on the ply file.} 13 | 14 | \item{ref}{A p x k matrix of 3D coordinates made by \code{\link{mshape}}} 15 | 16 | \item{color}{Color to set the ply file $material. If the ply already has color, use NULL. 17 | For ply files without color, color=NULL will be plotted as gray.} 18 | 19 | \item{centered}{Logical If the data in mesh.coords were collected from a centered mesh (see details).} 20 | } 21 | \value{ 22 | Function returns a mesh3d object, which is a list of class mesh3d (see rgl for details) 23 | } 24 | \description{ 25 | A function that uses the thin-plate spline to warp a 3D mesh into a shape defined 26 | by a set of landmark coordinates. 27 | } 28 | \details{ 29 | Function takes a 3D mesh (class mesh3d or shape3d, e.g. from \code{\link{read.ply}}) and its digitized landmark coordinates 30 | and uses the thin-plate spline method (Bookstein 1989) to warp the mesh into the shape 31 | defined by a second set of landmark coordinates, usually those of the 32 | mean shape for a set of aligned specimens. It is highly recommended that the mean shape is used as the 33 | reference for warping (see Rohlf 1998). The workflow is as follows: 34 | \enumerate{ 35 | \item {Calculate the mean shape using \code{\link{mshape}}} 36 | \item{Choose an actual specimen to use for the warping. The specimen used as the template for this warping 37 | is recommended as one most similar in shape to the average of the sample, but can be any reasonable 38 | specimen - do this by eye, or use \code{\link{findMeanSpec}} } 39 | \item{Warp this specimen into the mean shape using \code{\link{warpRefMesh}} } 40 | \item{Use this average mesh where it asks for a mesh= in the analysis functions and visualization functions } 41 | } 42 | Users should ensure that their mesh and mesh.coord matrix are in the same scale (a common issue is that the mesh is in micrometers and coordinates are in mm or cm). Use range(mesh$vb[1:3,]) and range(mesh.coord) to check and adjust mesh.coord as necessary. 43 | 44 | For landmark coordinates digitized with geomorph digitizing functions, centered = TRUE. This refers to the 45 | specimen being centered prior to landmark acquisition in the RGL window. For landmark data collected outside 46 | of geomorph, centered=FALSE will usually be the case. The returned mesh3d object is for use in geomorph 47 | functions where shape deformations are plotted (\code{\link{picknplot.shape}}, 48 | \code{\link{two.b.pls}}, \code{\link{bilat.symmetry}}, and \code{\link{plotRefToTarget}}). 49 | } 50 | \references{ 51 | Bookstein, F. L. 1989 Principal Warps: Thin-Plate Splines and the Decomposition 52 | of Deformations. IEEE Transactions on Pattern Analysis and Machine Intelligence 11(6):567-585. 53 | 54 | Rohlf, F. J. 1998. On Applications of Geometric Morphometrics to Studies of Ontogeny and Phylogeny. Systematic Biology. 47:147-158. 55 | } 56 | \seealso{ 57 | \code{\link{findMeanSpec}} 58 | 59 | \code{\link[rgl]{rgl-package}} (used in 3D plotting) 60 | } 61 | \author{ 62 | Emma Sherratt 63 | } 64 | \keyword{utilities} 65 | \keyword{visualization} 66 | -------------------------------------------------------------------------------- /R/editTemplate.r: -------------------------------------------------------------------------------- 1 | #' Edit 3D template 2 | #' 3 | #' An interactive function to remove landmarks from a 3D template file. 4 | #' 5 | #' The function edits a 'template.txt' file made by \code{\link{buildtemplate}}, which must be in the current 6 | #' working directory, and which is overwritten. Use read.table("template.txt", header = T) to read in the template 7 | #' first. 8 | #' \subsection{Selection}{ 9 | #' Choosing which landmarks will be deleted involves landmark selection using a mouse in the rgl plot window. 10 | #' With a standard 3-button (PC) buildtemplate uses: 11 | #' \enumerate{ 12 | #' \item the RIGHT mouse button (primary) to choose points to be deleted, 13 | #' \item the LEFT mouse button (secondary) is used to rotate mesh, 14 | #' \item the mouse SCROLLER (third/middle) is used to zoom in and out. 15 | #' } 16 | #' NOTE: Digitizing functions on MACINTOSH computers using a standard 3-button mice works as specified. Macs using platform 17 | #' specific single button mice, XQuartz must be configured: go to Preferences > Input > tick "Emulate three button mouse": 18 | #' \enumerate{ 19 | #' \item press button to rotate 3D mesh, 20 | #' \item press button while pressing COMMAND key to select points to be deleted, 21 | #' \item press button while pressing OPTION key to adjust mesh perspective. 22 | #' \item the mouse SCROLLER or trackpad two finger scroll is used to zoom in an out. 23 | #' } 24 | #' } 25 | #' @param template Matrix of template 3D coordinates 26 | #' @param fixed Number of "fixed" landmark points (non surface sliding points) 27 | #' @param n Number of points to be removed 28 | #' @return Function returns a matrix containing the x,y,z coordinates of the new template landmarks. 29 | #' Function also writes to the working directory 'template.txt' containing the x,y,z coordinates of the updated template 30 | #' @export 31 | #' @keywords digitizing 32 | #' @author Erik Otarola-Castillo & Emma Sherratt 33 | #' @seealso \code{\link[rgl]{rgl-package}} (used in 3D plotting) 34 | editTemplate<-function(template, fixed, n){ 35 | if (is.null(dim(template))) stop ("File is not a matrix of 3D coordinates.") 36 | if (dim(template)[2]!=3) stop ("File is not a matrix of 3D coordinates.") 37 | spec.name<-deparse(substitute(template)) 38 | clear3d();ids <- plot3d(template,size=5,aspect=TRUE) 39 | points3d(template[-(1:fixed[1]),],size=7,col="blue") 40 | points3d(template[(1:fixed),],size=10,color="red") 41 | cat("Remove Template Points","\n") 42 | selected2<-NULL 43 | for (i in 1:n) { 44 | selected2.temp<-NULL 45 | keep<-NULL 46 | keep <- selectpoints3d(ids["data"], value= FALSE, button = "right")[2] 47 | cat( i, "of", n, "points have been removed" , "\n") 48 | selected2.temp<-keep 49 | selected2<-c(selected2,selected2.temp) 50 | points3d(template[selected2.temp,][1],template[selected2.temp,][2],template[selected2.temp,][3],size=12,color="yellow",add=TRUE) 51 | points3d(template[-(1:fixed[1]),],size=7,col="blue",add=TRUE) 52 | points3d(template[(1:fixed),],size=10,color="red",add=TRUE) 53 | } 54 | template<-cbind(template[-(selected2),][,1],template[-(selected2),][,2],template[-(selected2),][,3]) 55 | write.table(template,file="template.txt",col.names=TRUE) 56 | clear3d();plot3d(template,size=5,aspect=TRUE) 57 | points3d(template[-(1:fixed[1]),],size=7,col="blue") 58 | points3d(template[(1:fixed),],size=10,color="red") 59 | return(template) 60 | } 61 | -------------------------------------------------------------------------------- /man/fixed.angle.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fixed.angle.r 3 | \name{fixed.angle} 4 | \alias{fixed.angle} 5 | \title{Rotate a subset of 2D landmarks to common articulation angle} 6 | \usage{ 7 | fixed.angle( 8 | A, 9 | art.pt = NULL, 10 | angle.pts.1, 11 | angle.pts.2, 12 | rot.pts = NULL, 13 | angle = 0, 14 | degrees = FALSE 15 | ) 16 | } 17 | \arguments{ 18 | \item{A}{A 3D array (p x k x n) containing landmark coordinates for a set of specimens} 19 | 20 | \item{art.pt}{A number specifying which landmark is the articulation point between the two landmark subsets} 21 | 22 | \item{angle.pts.1}{A vector or single value specifying the angle point of one subset. If more that one value 23 | is provided, the centroid of the landmarks described by the vector will be used; a single value 24 | identifies a specific landmark to use.} 25 | 26 | \item{angle.pts.2}{A vector or single value specifying the angle point of the second subset. This could be 27 | the entire set of points of an articulated structure to be rotated.} 28 | 29 | \item{rot.pts}{A vector containing numbers specifying which landmarks are in the subset to be rotated. If NULL, 30 | it is assumed that the points to be rotated are the same as those in angle.pts.2.} 31 | 32 | \item{angle}{An optional value specifying the additional amount by which the rotation should be augmented (in radians). 33 | It might be essential to use a negative angle if centroids from multiple points are used for angle points. It should be 34 | clear if this is the case, upon plotting results.} 35 | 36 | \item{degrees}{A logical value specifying whether the additional rotation angle is expressed in degrees or radians (radians is default)} 37 | } 38 | \value{ 39 | Function returns a (p x k x n) array of landmark coordinates. 40 | } 41 | \description{ 42 | A function for rotating a subset of landmarks so that the articulation angle between subsets is constant 43 | } 44 | \details{ 45 | This function standardizes the angle between two subsets of landmarks for a set of specimens. The approach 46 | assumes a simple hinge-point articulation between the two subsets, and rotates all specimens such that the 47 | angle between landmark subsets is equal across specimens (see Adams 1999). As a default, the mean angle is 48 | used, though the user may specify an additional amount by which this may be augmented. To quantify the angle, 49 | users may specify a single landmark in each subset as angle endpoints, or may specify a set of landmarks. 50 | If the latter, the centroid of those points is used. 51 | 52 | Presently, the function is only implemented for two-dimensional landmark data. 53 | } 54 | \examples{ 55 | \dontrun{ 56 | #Example using Plethodon 57 | #Articulation point is landmark 1, rotate mandibular landmarks (2-5) 58 | # relative to cranium 59 | 60 | data(plethspecies) 61 | # Using specific points: 62 | newLM1 <- fixed.angle(plethspecies$land, 63 | art.pt = 1, angle.pts.1 = 5, 64 | angle.pts.2 = 6, rot.pts = c(2,3,4,5)) 65 | Y.gpa1 <- gpagen(newLM1) 66 | plot(Y.gpa1, mean = FALSE) 67 | 68 | # Using centroids from subsets 69 | newLM2 <- fixed.angle(plethspecies$land, art.pt = 1, 70 | angle.pts.1 = c(1, 6:11), 71 | angle.pts.2 = 2:5, 72 | rot.pts = NULL, angle = 20, 73 | degrees = TRUE) # rotated points same as second partition 74 | Y.gpa2 <- gpagen(newLM2) 75 | plot(Y.gpa2, mean = FALSE) 76 | } 77 | } 78 | \references{ 79 | Adams, D. C. 1999. Methods for shape analysis of landmark data from articulated structures. Evolutionary Ecology Research. 1:959-970. 80 | } 81 | \author{ 82 | Dean Adams and Michael Collyer 83 | } 84 | \keyword{utilities} 85 | -------------------------------------------------------------------------------- /R/compare.ZVrel.R: -------------------------------------------------------------------------------- 1 | #' Comparisons of Effect Sizes from Overall Integration Analyses 2 | #' 3 | #' Function performs an analysis to compare the effect sizes of two or more Vrel effects 4 | #' 5 | #' The function statistically compares the effect sizes of two or more Vrel analyses. Typically, this 6 | #' function might be used to compare the strength of integration in one dataset as compared with another 7 | #' (see Conaway and Adams 2022). 8 | #' 9 | #' The analysis performs two-sample z-tests based on effect sizes (Z-scores) of Vrel. The method 10 | #' follows that of Conaway Adams (2022) used to compare the strength of integration across datasets. 11 | #' 12 | #' To use this function, simply perform \code{\link{integration.Vrel}} on as many samples or as desired. 13 | #' Any number of objects of class rel.eig can be input. One may perform the comparison as either a 14 | #' one-tailed or a two-tailed (default) test. 15 | #' 16 | #' @param ... saved analyses of class rel.eig 17 | #' @param two.tailed A logical value to indicate whether a two-tailed test (typical and default) should be performed. 18 | #' @keywords analysis 19 | #' @export 20 | #' @author Dean Adams 21 | #' @return An object of class compare.rel.eig, returns a list of the following 22 | #' 23 | #' \item{sample.Re.obs}{A vector of observed Vrel for each sample.} 24 | #' \item{sample.Z.obs}{A vector of effect sizes for each sample.} 25 | #' \item{sample.Z.var}{A vector of variances for each effect size.} 26 | #' \item{pairwise.z}{A matrix of pairwise, two-sample z scores between all pairs of effect sizes.} 27 | #' \item{pairwise.p}{A matrix of corresponding P-values.} 28 | #' @references Conaway, M.A., and D.C. Adams. 2022. An effect size for comparing the strength of 29 | #' morphological integration across studies. Evolution. 76: 2244-2259. 30 | #' @examples 31 | #' \dontrun{ 32 | #' data("plethodon") 33 | #' Y.gpa <- gpagen(plethodon$land) 34 | #' 35 | #' coords.gp <- coords.subset(Y.gpa$coords, plethodon$species) 36 | #' Vrel.gp <- Map(function(x) integration.Vrel(x), coords.gp) 37 | #' 38 | #' out <- compare.ZVrel(Vrel.gp$Jord, Vrel.gp$Teyah) 39 | #' 40 | #' summary(out) 41 | #' } 42 | compare.ZVrel <- function(...,two.tailed = TRUE){ 43 | dots <- list(...) 44 | tails <- if(two.tailed) 2 else 1 45 | if(length(dots) < 2) stop("At least two objects of class rel.eig are needed") 46 | is.rel.eig <- function(x) class(x) == "rel.eig" 47 | list.check <- sapply(1:length(dots), function(j) any(is.rel.eig(dots[[j]]))) 48 | if(any(list.check == FALSE)) stop("Not all objects are class rel.eig") 49 | k <- length(list.check) 50 | list.names <- as.list(substitute(list(...)))[-1L] 51 | k.combn <- combn(k,2) 52 | list.re.obs <- sapply(1:k, function(j) dots[[j]]$Re.obs) 53 | list.ZRs <- sapply(1:k, function(j) dots[[j]]$Z.obs) 54 | list.vars <- sapply(1:k, function(j) dots[[j]]$ZR.var) 55 | z12 <- sapply(1:ncol(k.combn), function(j){ 56 | a <- k.combn[1,j]; b <- k.combn[2,j] 57 | r1 <- list.ZRs[a]; r2 <- list.ZRs[b]; var1 <- list.vars[a]; var2 <- list.vars[b] 58 | abs(r1-r2)/sqrt( var1+var2) 59 | }) 60 | z12.p <- sapply(1:length(z12), function(j) pnorm(abs(z12[[j]]), lower.tail = FALSE) * tails) 61 | d <- rep(0,k); names(d) <- list.names 62 | D <-dist(d) 63 | z12.pw <- p12.pw <- D 64 | for(i in 1:length(z12)) z12.pw[i] <-z12[i] 65 | for(i in 1:length(z12)) p12.pw[i] <-z12.p[i] 66 | names(list.ZRs) <-list.names 67 | pairwise.z <- as.matrix(z12.pw) 68 | pairwise.P <- as.matrix(p12.pw) 69 | diag(pairwise.P) <- 1 70 | out <- list(sample.Re.obs = list.re.obs, sample.Z.obs = list.ZRs, 71 | sample.Z.var = list.vars, 72 | pairwise.z = pairwise.z, 73 | pairwise.P = pairwise.P) 74 | class(out) <- "compare.ZVrel" 75 | out 76 | } -------------------------------------------------------------------------------- /man/plotOutliers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotOutliers.r 3 | \name{plotOutliers} 4 | \alias{plotOutliers} 5 | \title{Find potential outliers} 6 | \usage{ 7 | plotOutliers(A, groups = NULL, PC = NULL, inspect.outliers = FALSE) 8 | } 9 | \arguments{ 10 | \item{A}{A 3D array (p x k x n) containing Procrustes shape variables for a set of specimens} 11 | 12 | \item{groups}{An optional factor defining groups} 13 | 14 | \item{PC}{A single number or range of principal components that can be used to check for outliers. If 15 | NULL, all shape dimensions are used. This argument might be useful for investigating subtle but 16 | important aspects of shape that would not elucidate outliers in all dimensions.} 17 | 18 | \item{inspect.outliers}{A logical value indicating whether to plot outlier shape configurations as compared to the consensus} 19 | } 20 | \value{ 21 | Function returns the landmark addresses of all specimens ordered as in the plot. If groups are used, function returns 22 | a list structure and a plot for each level in groups. 23 | } 24 | \description{ 25 | Function plots all specimens ordered by distance from the mean. 26 | } 27 | \details{ 28 | The function creates a plot of all specimens ordered by their distance from the mean shape. There 29 | is an option for using specified principal components (PC) of shape. If all shape dimensions are used 30 | then distances are equal to Procrustes distances or distances in the tangent space of shape space that 31 | resemble Procrustes distances, depending on whether the projection was performed with generalized 32 | Procrustes analysis (GPA). Once distances are calculated, a power-transformation is perfomed to 33 | normalize the distances. From these data, an upper limit is estimated following Tukey's box-plot rule, 34 | as \eqn{Q_3 + 1.5 \times (Q_3 - Q_1)}, where \eqn{Q} refers to quartile. This upper limit is back-transformed 35 | to distance, and any distances greater than this limit are colored red. (Note: These shapes could 36 | be considered outliers but their red color does not mean they are necessarily outliers. ) 37 | 38 | The user may optionally 39 | also inspect the shapes of identified configurations as compared to the consensus, in order 40 | to identify potential digitization errors or other data issues. The addresses of all specimens are 41 | returned in the order displayed in the plot for further inspection by \code{\link{plotRefToTarget}}. 42 | 43 | If the data have strong group structure and there is reasonable belief that the whole sample mean should not be used, 44 | then a factor defining the groups can be used. 45 | } 46 | \examples{ 47 | \dontrun{ 48 | data(plethodon) 49 | # let's make some outliers 50 | newland <- plethodon$land 51 | newland[c(1,8),,2] <- newland[c(8,1),,2] 52 | newland[c(3,11),,26] <- newland[c(11,3),,2] 53 | Y <- gpagen(newland) # GPA 54 | out <- plotOutliers(Y$coords) # function returns dimnames and address 55 | out 56 | # of all specimens ordered 57 | plotOutliers(Y$coords, inspect.outliers = TRUE) # function also produces 58 | # plots of identified outlier specimens compared to the mean shape 59 | 60 | # example with groups 61 | plotOutliers(Y$coords, groups = plethodon$species, 62 | inspect.outliers = TRUE) 63 | 64 | # previous example using first three PCs of shape 65 | plotOutliers(Y$coords, groups = plethodon$species, 66 | PC = 1:3, inspect.outliers = TRUE) 67 | 68 | # previous example using just the first PC of shape 69 | plotOutliers(Y$coords, groups = plethodon$species, 70 | PC = 1, inspect.outliers = TRUE) 71 | } 72 | } 73 | \seealso{ 74 | \code{\link{gpagen}} 75 | 76 | \code{\link{plotAllSpecimens}} 77 | } 78 | \author{ 79 | Emma Sherratt, Antigoni Kaliontzopoulou, & Michael Collyer 80 | } 81 | \keyword{utilities} 82 | -------------------------------------------------------------------------------- /man/readland.tps.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/readland.tps.r 3 | \name{readland.tps} 4 | \alias{readland.tps} 5 | \title{Read landmark data from tps file} 6 | \usage{ 7 | readland.tps( 8 | file, 9 | specID = c("None", "ID", "imageID"), 10 | negNA = FALSE, 11 | readcurves = FALSE, 12 | warnmsg = TRUE 13 | ) 14 | } 15 | \arguments{ 16 | \item{file}{A *.tps file containing two- or three-dimensional landmark data} 17 | 18 | \item{specID}{a character specifying whether to extract the specimen ID names from the ID or IMAGE lines (default is "None").} 19 | 20 | \item{negNA}{A logical value indicating whether negative landmark coordinates in the tps file should be imported as missing 21 | values and coded as 'NA' (TRUE), or imported as such.} 22 | 23 | \item{readcurves}{A logical value stating whether CURVES= field and associated coordinate data will be read as semilandmarks (TRUE) 24 | or ignored (FALSE).} 25 | 26 | \item{warnmsg}{A logical value stating whether warnings should be printed} 27 | } 28 | \value{ 29 | Function returns a (p x k x n) array, where p is the number of landmark points, k is the number 30 | of landmark dimensions (2 or 3), and n is the number of specimens. The third dimension of this array 31 | contains names for each specimen, which are obtained from the image names in the *.tps file. 32 | } 33 | \description{ 34 | Read *.tps file to obtain landmark coordinates 35 | } 36 | \details{ 37 | This function reads a *.tps file containing two- or three-dimensional landmark coordinates. 38 | Tps files are text files in one of the standard formats for geometric morphometrics (see Rohlf 2010). 39 | Two-dimensional landmarks coordinates are designated by the identifier "LM=", while three-dimensional 40 | data are designated by "LM3=". Landmark coordinates are multiplied by their scale factor if this is 41 | provided for all specimens. If one or more specimens are missing the scale factor, landmarks are treated 42 | in their original units. 43 | 44 | Missing data may be present in the file. If data were digitized in geomorph or StereoMorph, these are 45 | automatically identified. If, instead, data digitizing took place in a software package that records missing 46 | values as negative coordinates (e.g. tpsDig), the user needs to specify whether negative values should be 47 | transformed to 'NAs' through the argument neg.NA = TRUE. The positions of missing landmarks may 48 | then be estimated using \code{\link{estimate.missing}}. 49 | 50 | The user may specify whether specimen names are to be extracted from the 'ID=' field or 'IMAGE=' field 51 | and included in the resulting 3D array. 52 | e.g., for 'ID=' use (file, specID = "ID") and for 'IMAGE=' use (file, specID = "imageID"). 53 | The default is specID="None". 54 | 55 | If there are curves defined in the file (i.e., CURVES= fields), the option 'readcurves' should be used. 56 | When readcurves = TRUE, the coordinate data for the curves will be returned as semilandmarks and will be appended to 57 | the fixed landmark data. Then the user needs to use \code{\link{define.sliders}} or \code{\link{define.sliders}} 58 | to create a matrix designating how the curve points will slide (used by 'curves=' in \code{\link{gpagen}}). 59 | When readcurves = FALSE, only the landmark data are returned. 60 | 61 | NOTE: At present, all other information that can be contained in tps files (comments, variables, radii, etc.) 62 | is ignored. 63 | } 64 | \references{ 65 | Rohlf, F. J. 2010. tpsRelw: Relative warps analysis. Version 1.49. Department of Ecology 66 | and Evolution, State University of New York at Stony Brook, Stony Brook, NY. 67 | } 68 | \author{ 69 | Dean Adams, Emma Sherratt, Michael Collyer & Antigoni Kaliontzopoulou 70 | } 71 | \keyword{IO} 72 | -------------------------------------------------------------------------------- /R/geomorph.data.frame.r: -------------------------------------------------------------------------------- 1 | #' Create a data frame with shape data 2 | #' 3 | #' A list similar to a data frame to facilitate analysis of shape data. 4 | #' 5 | #' This function produces a list that can be used like a data frame in other analytical functions. 6 | #' The purpose is similar to the function, \code{\link[base]{data.frame}}, but without the constraint that 7 | #' data must conform to an n (observations) x p (variables) matrix. Rather, the list produced is 8 | #' constrained only by n. List objects can be Procrustes shape variables, matrices, variables, 9 | #' distance matrices, and phylogenetic trees. Results from \code{\link{gpagen}} can be directly 10 | #' imported into a geomorph.data.frame to utilize the coordinates and centroid size as variables. (See Examples) 11 | #' @param ... a list of objects to include in the data frame. 12 | #' @export 13 | #' @author Michael Collyer 14 | #' @keywords utilities 15 | #' @examples 16 | #' \dontrun{ 17 | #' data(plethodon) 18 | #' Y.gpa <- gpagen(plethodon$land, PrinAxes = FALSE) 19 | #' gdf <- geomorph.data.frame(Y.gpa) 20 | #' attributes(gdf) 21 | #' 22 | #' gdf <- geomorph.data.frame(Y.gpa, species = plethodon$species, 23 | #' site = plethodon$site) 24 | #' attributes(gdf) 25 | #' 26 | #' # Using geomorph.data.frame to facilitate analysis 27 | #' anova(procD.lm(coords ~ Csize + species * site, data = gdf)) 28 | #' } 29 | geomorph.data.frame <- function(...){ 30 | dots <- list(...) 31 | list.check0 <- sapply(1:length(dots), function(j) any(is.geomorph.data.frame(dots[[j]]))) 32 | list.check00 <- sapply(1:length(dots), function(j) any(is.data.frame(dots[[j]]))) 33 | dots0 <- unlist(dots[list.check0], recursive=FALSE) 34 | dots00 <- unlist(dots[list.check00], recursive=FALSE) 35 | dots.updated <- dots[!list.check0 & !list.check00] 36 | if(length(dots.updated) > 0) { 37 | list.check1 <- sapply(1:length(dots.updated), function(j) is.gpagen(dots.updated[[j]])) 38 | dots1 <- dots.updated[list.check1] 39 | } else dots1 <- NULL 40 | if(length(dots1) > 0){ 41 | dots2 <- lapply(1:length(dots1), function(j){ 42 | x <- unlist(dots1[j], recursive = FALSE) 43 | list(x$coords, x$Csize) 44 | }) 45 | dots2 <- unlist(dots2, recursive = FALSE) 46 | dots2.names <- rep(c("coords", "Csize"), length(dots1)) 47 | names(dots2) <- dots2.names 48 | dots.updated <- dots.updated[!list.check1] 49 | } else { 50 | dots2 <- NULL 51 | } 52 | if(length(dots.updated) > 0){ 53 | list.check2 <- sapply(1:length(dots.updated), function(j) is.phylo(dots.updated[[j]])) 54 | dots3 <- dots.updated[list.check2] 55 | dots4 <- dots.updated[!list.check2] 56 | } else { 57 | dots3 <- NULL 58 | dots4 <- NULL 59 | } 60 | if(length(dots3) == 0) dots3 <- NULL 61 | if(length(dots4) == 0) dots4 <- NULL 62 | dots <- c(dots0,dots00,dots2, dots3,dots4) 63 | N <- length(dots) 64 | dots.ns <- array(NA,N) 65 | for(i in 1:N){ 66 | if(is.array(dots[[i]])) { 67 | if(length(dim(dots[[i]])) == 3) dots.ns[i] <- dim(dots[[i]])[[3]] 68 | if(length(dim(dots[[i]])) == 2) dots.ns[i] <- dim(dots[[i]])[[2]] 69 | if(length(dim(dots[[i]])) == 1) dots.ns[i] <- dim(dots[[i]])[[1]] 70 | } 71 | if(is.matrix(dots[[i]])) dots.ns[i] <- dim(dots[[i]])[[1]] 72 | if(inherits(dots[[i]], "dist")) dots.ns[i] <- attr(dots[[i]], "Size") 73 | if(inherits(dots[[i]], "phylo")) dots.ns[i] <- length(dots[[i]]$tip.label) 74 | if(is.data.frame(dots[[i]])) dots.ns[i] <- dim(dots[[i]])[[2]] 75 | if(is.vector(dots[[i]])) dots.ns[i] <- length(dots[[i]]) 76 | if(is.factor(dots[[i]])) dots.ns[i] <- length(dots[[i]]) 77 | if(is.logical(dots[[i]])) dots.ns[i] <- length(dots[[i]]) 78 | } 79 | if(any(is.na(dots.ns))) stop("Some input is either dimensionless or inappropriate for data frames") 80 | if(length(unique(dots.ns)) > 1) stop("Inputs have different numbers of observations") 81 | class(dots) <- c("geomorph.data.frame") 82 | dots 83 | } 84 | 85 | -------------------------------------------------------------------------------- /man/digit.fixed.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/digit.fixed.r 3 | \name{digit.fixed} 4 | \alias{digit.fixed} 5 | \title{Digitize 3D landmarks on mesh3d object} 6 | \usage{ 7 | digit.fixed(spec, fixed, index = FALSE, ptsize = 1, center = TRUE) 8 | } 9 | \arguments{ 10 | \item{spec}{An object of class shape3d/mesh3d, or matrix of 3D vertex coordinates} 11 | 12 | \item{fixed}{The number of landmarks to be digitized (fixed, and curve sliders if desired)} 13 | 14 | \item{index}{Whether selected landmark addresses should be returned (internal use only)} 15 | 16 | \item{ptsize}{Size of mesh points (vertices), e.g. 0.1 for dense meshes, 3 for sparse meshes} 17 | 18 | \item{center}{Should the object 'spec' be centered prior to digitizing?} 19 | } 20 | \value{ 21 | Function returns (if assigned to an object) and writes to the working directory an NTS 22 | file, containing the landmark coordinates. The file name corresponds to the name of the specimen. 23 | If index=FALSE function returns to the console an n x 3 matrix containing the x,y,z coordinates of the digitized landmarks. 24 | If index=TRUE, function returns a list: 25 | \item{selected}{a matrix containing the x,y,z coordinates of the digitized landmarks} 26 | \item{fix}{a matrix of addresses for landmarks that are "fixed" (for internal use)} 27 | } 28 | \description{ 29 | An interactive function to digitize three-dimensional (3D) landmarks. 30 | Input for the function is either a matrix of vertex coordinates defining a 3D surface object 31 | or a mesh3d object as obtained from \code{\link{read.ply}}. 32 | } 33 | \details{ 34 | Function for digitizing fixed three-dimensional landmarks. The user can later designate some 35 | as curve sliding semilandmarks, using the function \code{\link{define.sliders}} or through 36 | a semilandmark definition matrix. 37 | 38 | To digitize 3D surface sliding semilandmarks the function \code{\link{digitsurface}} should be used instead. 39 | 40 | For details on the full procedure for digitizing fixed 3D landmarks and surface 41 | sliding semilandmarks, see the relevant vignette by running \code{vignette("geomorph.digitize3D")}. 42 | 43 | NOTE: The function centers the mesh before digitizing by default (center = TRUE). If one chooses not to center, 44 | specimen may be difficult to manipulate in rgl window. 45 | 46 | \subsection{Digitizing}{ 47 | Digitizing is interactive. Once a point is selected, the user is asked if the system should keep or discard the 48 | selection (y/n). If "y", the user is asked to continue to select the next landmark. If "n" the removes the last chosen 49 | landmark, and the user is asked to select it again. This can be repeated until the user is comfortable with the 50 | landmark chosen. 51 | 52 | To digitize with a standard 3-button mouse (PC): 53 | \enumerate{ 54 | \item the RIGHT mouse button (primary) to select points to be digitized, 55 | \item the LEFT mouse button (secondary) is used to rotate mesh, 56 | \item the mouse SCROLLER (third/middle) is used to zoom in and out. 57 | } 58 | NOTE: Digitizing functions on MACINTOSH computers using a standard 3-button mice works as specified. Macs using platform 59 | specific single button mice, XQuartz must be configured: go to Preferences > Input > tick "Emulate three button mouse": 60 | \enumerate{ 61 | \item press button to rotate 3D mesh, 62 | \item press button while pressing COMMAND key to select vertex to be used as a landmark, 63 | \item press button while pressing OPTION key to adjust mesh perspective. 64 | \item the mouse SCROLLER or trackpad two finger scroll is used to zoom in an out. 65 | } 66 | 67 | NOTE: there is no pan (translate) functionality in rgl library for all platforms at this time. 68 | } 69 | } 70 | \seealso{ 71 | \code{\link{read.ply}} 72 | 73 | \code{\link[rgl]{rgl-package}} (used in 3D plotting) 74 | } 75 | \author{ 76 | Erik Otarola-Castillo & Emma Sherratt 77 | } 78 | \keyword{digitizing} 79 | -------------------------------------------------------------------------------- /R/arrayspecs.r: -------------------------------------------------------------------------------- 1 | #' Convert landmark data matrix into array (p x k x n) 2 | #' 3 | #' Convert a matrix of landmark coordinates into a three-dimensional array 4 | #' 5 | #' This function converts a matrix of landmark coordinates into a 3D array (p x 6 | #' k x n), 7 | #' which is the required input format for many functions in geomorph. 8 | #' The input matrix can be arranged such that the coordinates 9 | #' of each landmark are found on a separate row, or that each row contains all 10 | #' landmark 11 | #' coordinates for a single specimen. 12 | #' 13 | #' @param A A matrix containing landmark coordinates for a set of specimens 14 | #' @param p Number of landmarks 15 | #' @param k Number of dimensions (2 or 3) 16 | #' @param sep An optional argument to attempt to separate variable names into 17 | #' landmark dimension 18 | #' and landmark number variables. For example, X.1, Y.1, Z.1, X.2, Y.2, Z.2, 19 | #' ..., can be separated 20 | #' with sep = ".", such that rows of landmark configurations are labeled 1, 2, 21 | #' 3, ..., and columns 22 | #' are labeled X, Y, Z. Note, for variables, X1, Y1, Z1, X2, Y2, Z2, ..., 23 | #' where no separator is evident, use sep = "". Any illogical separation 24 | #' argument will result in unlabeled 25 | #' variables. If sep = NULL (the default), unlabeled variables are forced. 26 | #' This is a good idea if the original matrix 27 | #' has landmarks out of order (as the the landmark labels might not sort as 28 | #' expected). 29 | #' @export 30 | #' @keywords utilities 31 | #' @author Dean Adams & Mike Collyer 32 | #' @seealso \code{\link{two.d.array}} 33 | #' @return Function returns a 3D array (p x k x n), where p is the number of 34 | #' landmark points, k is the 35 | #' number of landmark dimensions (2 or 3), and n is the number of specimens. 36 | #' The third dimension of 37 | #' this array contains names for each specimen if specified in the original 38 | #' input matrix. 39 | #' @examples 40 | #' \dontrun{ 41 | #' 42 | #' x <- matrix(rnorm(18), nrow = 3) # Random triangles (all coordinates on same 43 | #' # row for each triangle) 44 | #' arrayspecs(x, 3, 2) 45 | #' 46 | #' x2 <- matrix(rnorm(18), ncol = 2) # Random triangles (each landmark on its 47 | #' # own row) 48 | #' arrayspecs(x2, 3, 2) 49 | #' } 50 | 51 | arrayspecs<-function(A, p, k, sep = NULL){ 52 | if(!is.matrix(A) && !is.data.frame(A)) stop("A must be a data frame or matrix") 53 | dnames <- dimnames(A) 54 | n <- length(unlist(A))/(p * k) 55 | if(k < 2 ) stop("One-dimensional data cannot be used") 56 | if(all(is.na(match(c(n, n*p), NROW(A))))) stop("Matrix dimensions do not match input") 57 | specimens <- aperm(array(t(A), c(k,p,n)), c(2,1,3)) 58 | dimnames(specimens)[[3]] <- dnames[[1]] 59 | col.names <- dnames[[2]] 60 | if(is.null(sep)) col.names <- NULL 61 | if(!is.null(col.names)){ 62 | if(sep == ""){ 63 | options(warn = -1) 64 | split.lab <-sort(unique(unlist(strsplit(col.names, split="")))) 65 | split.lab <- split.lab[length(split.lab)] 66 | a <- strsplit(col.names, split = split.lab) 67 | a <- a[sapply(a, length) == 2] 68 | a <- na.omit(as.numeric(unlist(a))) 69 | if(length(unlist(a)) == p){ 70 | split.no <- as.character(a[length(a)]) 71 | b <- strsplit(col.names, split = split.no) 72 | no.char <- sapply(b, nchar) 73 | dim.tag <- which(no.char == min(no.char)) 74 | b <- unlist(b[dim.tag]) 75 | rn <- a 76 | cn <- b 77 | } else rn <- cn <- NULL 78 | options(warn = 0) 79 | } else{ 80 | sep = paste("[", noquote(sep), "]") 81 | a <- strsplit(col.names, split = sep) 82 | if(length(unlist(a)) == 2*k*p){ 83 | b <- simplify2array(a) 84 | rn <- unique(b[1,]) 85 | cn <- unique(b[2,]) 86 | if(length(rn) < length(cn)) {tmp <- cn; cn <- rn; rn <- tmp} 87 | } 88 | else rn <- cn <- NULL 89 | } 90 | dnames2 <- list(rn=rn, cn = cn) 91 | } 92 | if(!is.null(sep)) dimnames(specimens)[1:2] <- dnames2 93 | return(specimens) 94 | } 95 | -------------------------------------------------------------------------------- /R/interlmkdist.r: -------------------------------------------------------------------------------- 1 | #' Calculate linear distances between landmarks 2 | #' 3 | #' A function to calculate linear distances between a set of landmark coordinates (interlandmark distances) 4 | #' 5 | #' Function takes a 3D array of landmark coordinates from a set of specimens and the addresses for the start 6 | #' and end landmarks defining linear measurements and then 7 | #' calculates the interlandmark distances. The function returns a matrix of linear distances for all specimens. 8 | #' If the 'lmks' matrix has row or column names defining the name of the linear measurements, the returned matrix will use 9 | #' these for column names (see example). If only two interlandmark distances, 'lmks' input must be m x 2. 10 | #' 11 | #' @param A A 3D array (p x k x n) containing landmark coordinates for a set of specimens 12 | #' @param lmks A matrix or dataframe of landmark addresses for the start and end landmarks defining m linear measurements (can be either 2-x-m or m-x-2). 13 | #' Either the rows or the columns should have names 'start' and 'end' to define landmarks. 14 | #' @export 15 | #' @keywords utilities 16 | #' @author Emma Sherratt & Michael Collyer 17 | #' @return Function returns a matrix (n x m) of m linear distances for n specimens 18 | #' @examples 19 | #' \dontrun{ 20 | #' data(plethodon) 21 | #' # Make a matrix defining three interlandmark distances 22 | #' lmks <- matrix(c(8,9,6,12,4,2), ncol=2, byrow=TRUE, 23 | #' dimnames = list(c("eyeW", "headL", "mouthL"),c("start", "end"))) 24 | #' 25 | #' # where 8-9 is eye width; 6-12 is head length; 4-2 is mouth length 26 | #' # or alternatively 27 | #' 28 | #' lmks <- data.frame(eyeW = c(8,9), headL = c(6,12), mouthL = c(4,2), 29 | #' row.names = c("start", "end")) 30 | #' 31 | #' A <- plethodon$land 32 | #' lineardists <- interlmkdist(A, lmks) 33 | #' } 34 | 35 | interlmkdist <- function(A, lmks){ 36 | if(is.matrix(A)) A <- array(A, c(NROW(A), NCOL(A), 1)) 37 | dims <- dim(A); n <- dims[[3]]; p <- dims[[1]]; k <- dims[[2]] 38 | if(k < 2 || k > 3) stop("Landmarks must be 2 or 3 dimensions\n") 39 | if(!is.array(A)) { 40 | stop("Data matrix not a 3D array (see 'arrayspecs').") } 41 | lmks <- as.matrix(lmks) 42 | if(ncol(lmks) != 2 && nrow(lmks) != 2) 43 | stop("Only one start and one end point are required to calculate distances") 44 | row.match <- match(c("start", "end"), rownames(lmks)) 45 | col.match <- match(c("start", "end"), colnames(lmks)) 46 | if(any(is.na(col.match)) && all(!is.na(row.match))) { 47 | lmks <- t(lmks) 48 | lmks <- lmks[,order(colnames(lmks), decreasing = TRUE)] 49 | } 50 | if(any(is.na(col.match)) && any(is.na(row.match))) { 51 | if(ncol(lmks) != 2 && nrow(lmks) == 2) { 52 | lmks <- t(lmks) 53 | cat("\nNo 'start' and 'end' points were defined.", 54 | "\nIt is assumed that matrix rows are appropriately ordered.\n","\n") 55 | } 56 | if(ncol(lmks) == 2 && nrow(lmks) == 2) { 57 | if(is.null(rownames(lmks)) && is.null(colnames(lmks))) 58 | cat("\nNo 'start' and 'end' points were defined.", 59 | "\nNo names for distances were provided.", 60 | "\n'lmks' input assumed to be m x 2","\n\n") 61 | if(!is.null(rownames(lmks)) && is.null(colnames(lmks))) { 62 | cat("\nNo 'start' and 'end' points were defined.", 63 | "\nIt is assumed that matrix columns are appropriately ordered.","\n\n") 64 | } 65 | if(is.null(rownames(lmks)) && !is.null(colnames(lmks))) { 66 | lmks <- t(lmks) 67 | cat("\nNo 'start' and 'end' points were defined.", 68 | "\nIt is assumed that matrix rows are appropriately ordered.","\n\n") 69 | } 70 | } 71 | } 72 | lindist <- matrix(NA, ncol=nrow(lmks), nrow=dim(A)[3]) 73 | if(!is.null(rownames(lmks))) colnames(lindist) <- rownames(lmks) 74 | if(!is.null(dimnames(A)[[3]])) rownames(lindist) <- dimnames(A)[[3]] 75 | for(i in 1:nrow(lmks)){ 76 | if (n > 1) res <- apply(A[lmks[i,],,], 3, dist) else 77 | res <- dist(A[lmks[i,],,]) 78 | lindist[,i] <- res 79 | } 80 | return(lindist) 81 | } 82 | -------------------------------------------------------------------------------- /man/picknplot.shape.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/picknplot.shape.r 3 | \name{picknplot.shape} 4 | \alias{picknplot.shape} 5 | \title{Pick points in geomorph scatterplots to visualize shape variation} 6 | \usage{ 7 | picknplot.shape(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{a geomorph plot object of class plot.gm.prcomp, plot.procD.lm, plot.pls, or plotAllometry} 11 | 12 | \item{...}{other arguments passed to \code{\link{plotRefToTarget}}} 13 | } 14 | \value{ 15 | A list with the following components: 16 | \item{points}{A list with the xy coordinates of the selected points.} 17 | \item{shapes}{A list with the corresponding estimated shapes.} 18 | } 19 | \description{ 20 | Function plots the shape corresponding to a clicked point in the area of a geomorph plot 21 | } 22 | \details{ 23 | THIS FUNCTION IS A BIT EXPERIMENTAL! 24 | 25 | This function recycles plots generated by \code{\link{plot.gm.prcomp}}, \code{\link{plot.procD.lm}}, 26 | \code{\link{plot.pls}}, or \code{\link{plotAllometry}}, and makes them interactive to visualize shape variation by selecting one or more points in morphospace. 27 | The function uses \code{\link{shape.predictor}} 28 | to estimate the shape corresponding to the selected point(s) based on the prediction underlying the scatterplot, and it plots the estimated 29 | shape as compared to the consensus landmark configuration using \code{\link{plotRefToTarget}}. The user is then prompted as to whether the plotted 30 | shape is to be saved as a png file, in which case the name of the file needs to be provided (without quotation marks). 31 | Interactive plots are at present available for plots produced by \code{\link{plot.gm.prcomp}}. The function is limited in terms of the options for 32 | \code{\link{plotRefToTarget}} (because of the complexity of graphics); using \code{\link{shape.predictor}} and \code{\link{plotRefToTarget}}, directly, 33 | will always offer more flexibility. 34 | 35 | IF YOU EXPERIENCE AN ERROR, please use \code{\link{shape.predictor}} and \code{\link{plotRefToTarget}}, directly. (But please alert the 36 | geomorph package maintainer.) 37 | } 38 | \examples{ 39 | \dontrun{ 40 | 41 | ### Because picknplot requires user decisions, the following examples 42 | ### are not run. 43 | 44 | # 2d 45 | data(plethodon) 46 | Y.gpa <- gpagen(plethodon$land) 47 | pleth.pca <- gm.prcomp(Y.gpa$coords) 48 | pleth.pca.plot <- plot(pleth.pca) 49 | picknplot.shape(pleth.pca.plot) 50 | # May change arguments for plotRefToTarget 51 | picknplot.shape(plot(pleth.pca), method = "points", mag = 3, 52 | links = plethodon$links) 53 | 54 | # 2d with phylogeny 55 | data(plethspecies) 56 | Y.gpa.s <- gpagen(plethspecies$land) 57 | gps <- as.factor(c(rep("gp1", 5), rep("gp2", 4))) # Two random groups 58 | pleth.phylo <- gm.prcomp(Y.gpa.s$coords, plethspecies$phy) 59 | pleth.phylomorphospace <- plot(pleth.phylo, phylo = TRUE, cex = 2, 60 | pch = 22, bg = gps, phylo.par = list(edge.color = "blue", 61 | edge.width = 2, 62 | node.pch = 22, node.bg = "black")) 63 | links.species <- plethodon$links[-11,] 64 | links.species[11, 1] <- 11 65 | picknplot.shape(pleth.phylomorphospace, method = "points", 66 | links = links.species) 67 | 68 | # 2d allometry 69 | gdf <- geomorph.data.frame(Y.gpa, site = plethodon$site, 70 | species = plethodon$species) 71 | fit <- procD.lm(coords ~ log(Csize), data=gdf, 72 | print.progress = FALSE) 73 | # Predline 74 | PA <- plotAllometry(fit, size = gdf$Csize, logsz = TRUE, 75 | method = "PredLine", pch = 19) 76 | picknplot.shape(PA) 77 | 78 | # 3d and two-b-pls 79 | data("scallops") 80 | Y.gpa <- gpagen(scallops$coorddata, curves = scallops$curvslide, 81 | surfaces = scallops$surfslide) 82 | PLS <- two.b.pls(Y.gpa$coords, Y.gpa$Csize) 83 | PLS.plot = plot(PLS) 84 | picknplot.shape(PLS.plot) 85 | } 86 | } 87 | \seealso{ 88 | \code{\link{shape.predictor}}, \code{\link{plotRefToTarget}} 89 | 90 | \code{\link[rgl]{rgl-package}} (used in 3D plotting) 91 | } 92 | \author{ 93 | Antigoni Kaliontzopoulou, Emma Sherratt, & Michael Collyer 94 | } 95 | \keyword{visualization} 96 | -------------------------------------------------------------------------------- /R/digit.curves.r: -------------------------------------------------------------------------------- 1 | #' Calculate semilandmarks along a curve 2 | #' 3 | #' A function that "digitizes curves" by calculating equidistant two-dimensional or three-dimensional semilandmarks along 4 | #' a curve. These landmarks will be treated as "sliders" in Generalized Procrustes analysis \code{\link{gpagen}}. This 5 | #' type of semilandmark "slides" along curves lacking known landmarks (see Bookstein 1997 for algorithm details). Each 6 | #' sliding semilandmark ("sliders") will slide between two designated points, along a line tangent to the specified 7 | #' curvature, as specified by \code{\link{define.sliders}}. 8 | #' 9 | #' The function is based upon tpsDig2 'resample curve by length' for 2D data by James Rohlf (Rohlf 2015). 10 | #' The start of the curve is a fixed landmark on the curve that is equivalent (homologous) in each specimen in the 11 | #' sample (and will be treated as a fixed point during Procrustes Superimposition using \code{\link{gpagen}}). Then 12 | #' nPoints are calculated along the curve at equidistant points from the start to the end. 13 | #' 14 | #' 'curve' is a p-x-k matrix of 2D or 3D coordinates for a set of ordered points defining a curve. This can be the pixels 15 | #' of an outline calculated in ImageJ (save xy coordinates) or any other reasonable way of obtaining ordered coordinates 16 | #' along a curve (including sampling by hand using \code{\link{digit.fixed}} or \code{\link{digitize2d}} - but note 17 | #' that there should be more points defining the curve than nPoints in order to accurately calculate the semilandmarks). 18 | #' 19 | #' If 'closed = T', the function returns the coordinates of the 'start' landmark plus nPoints. If 'closed = F', the 20 | #' function returns the coordinates of the 'start' landmark, plus nPoints and the end of the curve. 21 | #' 22 | #' If unsure if the points defining the curve are ordered, then plot and color them using the rainbow function, 23 | #' e.g. plot(curve, pch=19, cex=0.1, col=rainbow(nrow(outline))), and it should be easy to visualize. 24 | #' 25 | #' @param start A numeric vector of x,y,(z) coordinates for the landmark defining the start of the curve (can be simply first point on open outline: curve[1,]) 26 | #' @param curve A matrix (p x k) of 2D or 3D coordinates for a set of ordered points defining a curve 27 | #' @param nPoints Numeric how many semilandmarks to place equidistantly along the curve (not counting beginning and end points) 28 | #' @param closed Logical Whether the curve is closed (TRUE) or open (FALSE) 29 | #' @return Function returns a matrix of coordinates for nPoints equally spaced semilandmarks sampled along the curve (plus start and end if 'closed = F', or only including start if 'closed = T') 30 | #' @seealso \code{\link{digit.fixed}} \code{\link{digitize2d}} 31 | #' @export 32 | #' @keywords digitizing 33 | #' @author Emma Sherratt and Michael Collyer 34 | #' @references Bookstein, F. J. 1997 Landmark Methods for Forms without Landmarks: Morphometrics of 35 | #' Group Differences in Outline Shape. Medical Image Analysis 1(3):225-243. 36 | #' @references Rohlf, F.J., 2015. The tps series of software. Hystrix 26(1):9-12. 37 | 38 | digit.curves <- function(start, curve, nPoints, closed=TRUE){ 39 | nPoints <- nPoints+2 40 | if(!is.matrix(curve)) stop("Input must be a p-x-k matrix of curve coordinates") 41 | nCurvePoints = NROW(curve) 42 | if(nCurvePoints < 2) stop("curve matrix does not have enough points to estimate any interior points") 43 | if(nPoints > (nCurvePoints - 1)) { 44 | if((nCurvePoints - 1) == 1) nPoints = 1 45 | if((nCurvePoints - 1) > 1) nPoints = nCurvePoints - 2 46 | 47 | warning( 48 | paste( 49 | "\nThis is not an error! It is a friendly warning.\n", 50 | "\nBecause the number of desired points exceeds the number of curve points,", 51 | "\nthe number of points will be truncated to", nPoints, "points.\n", 52 | "\nUse options(warn = -1) to turn off these warnings. \n\n", sep = " "), 53 | noBreaks. = TRUE, call. = FALSE, immediate. = TRUE) 54 | } 55 | 56 | start <- as.numeric(start) 57 | if(!setequal(start, curve[1,])) curve <- rbind(start, curve) 58 | if(closed) curve <- rbind(curve, curve[1,]) 59 | res <- evenPts(curve, nPoints) 60 | if(closed) res <- res[-NROW(res),] 61 | res 62 | } 63 | -------------------------------------------------------------------------------- /R/integration.Vrel.r: -------------------------------------------------------------------------------- 1 | #' Quantify integration in a set of traits 2 | #' 3 | #' Function quantifies the morphological integration in a set of traits 4 | #' 5 | #' The function quantifies the strength of morphological integration in a set of variables. 6 | #' Here the set of traits are treated as a single unit, and the overall degree of covariation in them 7 | #' is quantified using the relative eigenvalue index: Vrel (Pavlicev et al. 2009). Following 8 | #' Conaway and Adams (2022), only the non-trivial dimensions of variation are used in the calculation of Vrel. 9 | #' The measure is then converted to an effect size (Z-score), based on the procedures in Conaway and Adams (2022). 10 | #' These may be used in subsequent comparisons of the strength of integration across datasets. 11 | #' Input for the analysis may be a 3D array of Procrustes coordinates, of a matrix of variables. If the observations 12 | #' are species related by a phylogeny, the phylogeny may also be included. 13 | #' 14 | #' @param A A 3D array (p x k x n) containing Procrustes shape variables for all specimens, or a matrix (n x variables) 15 | #' @param phy A phylogenetic tree of class = "phylo" - see \code{\link[ape]{read.tree}} in library ape 16 | #' @export 17 | #' @keywords analysis 18 | #' @author Dean Adams 19 | #' @return Objects of class "rel.eig" from integration.Vrel return a list of the following: 20 | #' \item{Re.obs}{The observed relative eigenvalue index (Vrel).} 21 | #' \item{Z.obs}{The associated Z-score, which represents the effect size of Vrel.} 22 | #' \item{ZR}{The effect size translated to a positive scale (so that no integration is ZR = 0).} 23 | #' \item{ZR.var}{The variance of the effect size.} 24 | #' @references Pavlicev, M., J. M. Cheverud, and G. P. Wagner. 2009. Measuring morphological 25 | #' integration using eigenvalue variance. Evolutionary Biology 36:157-170. 26 | #' @references Conaway, M.A., and D.C. Adams. 2022. An effect size for comparing the strength of 27 | #' morphological integration across studies. Evolution. 76: 2244-2259. 28 | 29 | #' @seealso \code{\link{compare.ZVrel}} 30 | #' @examples 31 | #' \dontrun{ 32 | #' data(plethodon) 33 | #' Y.gpa <- gpagen(plethodon$land) #GPA-alignment 34 | #' integration.Vrel(Y.gpa$coords) 35 | #' } 36 | 37 | integration.Vrel <- function(A,phy = NULL){ 38 | if(length(dim(A))==3){ 39 | A <- two.d.array(A) 40 | } 41 | n <- nrow(A) 42 | if (!is.null(phy)) { 43 | 44 | if (!inherits(phy, "phylo")) 45 | stop("phy must be of class 'phylo.'") 46 | namesA <- rownames(A) 47 | 48 | if (is.null(namesA)) 49 | stop("\nNo specimen names in data matrix. Please assign specimen names.", call. = FALSE) 50 | 51 | num.taxa <- length(phy$tip.label) 52 | num.obs <- length(namesA) 53 | 54 | if(num.obs < num.taxa) 55 | stop("\nTree contains some taxa not present in present in the data matrix", call. = FALSE) 56 | 57 | if(num.obs > num.taxa) 58 | stop("\nTree is missing some taxa present in the data matrix", call. = FALSE) 59 | 60 | if(length(unique(c(namesA, phy$tip.label))) > num.taxa) 61 | stop("\n The data names and taxa names do not match exactly. Check for discrepancies.", 62 | call. = FALSE) 63 | 64 | phy.parts <- phylo.mat(A, phy) 65 | Ptrans <- phy.parts$D.mat %*% (diag(n) - matrix(1, n) %*% 66 | crossprod(matrix(1, n), phy.parts$invC)/sum(phy.parts$invC)) 67 | A <- Ptrans %*% A 68 | } 69 | eig.obs <- eigen(cov(A))$values 70 | eig.obs <- eig.obs[which(zapsmall(eig.obs)>0)] 71 | p <- length(eig.obs) 72 | VNull <- (p+2)/((p*(n-1))+2) 73 | Vtrans <- 2*VNull-1 74 | ZN <- 0.5*log((1+Vtrans) / (1-Vtrans)) 75 | Re.obs <- var(eig.obs) / (mean(eig.obs)^2*p) 76 | Re.obs.trans <- ((2*Re.obs)-1) 77 | if(Re.obs.trans==1){Re.obs.trans=0.999} 78 | if(Re.obs.trans==-1){Re.obs.trans=-0.999} 79 | Z.obs <- 0.5*log((1+Re.obs.trans) / (1-Re.obs.trans)) 80 | ZR <- Z.obs + abs(ZN) 81 | if (ZR < 0) warning("ZR less than zero (likely because p>N). Use Z.obs for interpretation.") 82 | ZR.var <- 1/(n-3) 83 | out <- list(Re.obs = Re.obs, Z.obs = Z.obs, ZR = ZR, ZR.var = ZR.var) 84 | class(out) <- "rel.eig" 85 | out 86 | } -------------------------------------------------------------------------------- /R/read.ply.r: -------------------------------------------------------------------------------- 1 | #' Read mesh data (vertices and faces) from ply files 2 | #' 3 | #' A function to read ply files, which can be used for digitizing landmark coordinates or for shape warps. 4 | #' 5 | #' Function reads three-dimensional surface data in the form of a single ply file 6 | #' (Polygon File Format; ASCII format only, from 3D scanners such as NextEngine and David scanners). 7 | #' Vertices of the surface may then be used to digitize three-dimensional points, 8 | #' and semilandmarks on curves and surfaces. The surface may also be used as a mesh for visualizing 3D deformations (\code{\link{warpRefMesh}}). 9 | #' The function opens the ply file and plots the mesh, 10 | #' with faces rendered if file contains faces, and colored if the file contains vertex color. 11 | #' Vertex normals allow better visualization and more accurate digitizing with \code{\link{digit.fixed}}. 12 | #' 13 | #' @param file An ASCII ply file 14 | #' @param ShowSpecimen logical Indicating whether or not the ply file should be displayed 15 | #' @param addNormals logical Indicating whether or not the normals of each vertex should be calculated (using \code{\link[rgl]{addNormals}}) 16 | #' @export 17 | #' @keywords IO 18 | #' @author Dean Adams & Emma Sherratt 19 | #' @seealso \code{\link[rgl]{rgl-package}} (used in 3D plotting) 20 | #' @return Function returns the following components: 21 | #' \item{mesh3d}{list of class mesh3d- see rgl for details} 22 | #' @examples 23 | #' \dontrun{ 24 | #' # If the file has no mesh color, or color is undesirable, user can 25 | #' # assign this as follows: 26 | #' # Using the example scallop PLY 27 | #' data(scallopPLY) 28 | #' myply <- scallopPLY$ply 29 | #' myply$material$color <- "gray" # using color word 30 | #' myply$material$color <- "#FCE6C9" # using RGB code 31 | #' } 32 | read.ply <- function (file, ShowSpecimen = TRUE, addNormals = TRUE) 33 | { 34 | plyfile <- scan(file = file, what = "char", sep = "\n", strip.white = TRUE, 35 | quiet = TRUE) 36 | is.ply <- grep("ply", plyfile) 37 | if ((length(is.ply) ==0) ) stop ("File is not a PLY file") 38 | format <- unlist(strsplit(grep(c("format "), plyfile, value = TRUE), " ")) 39 | if (format[2] != "ascii") 40 | stop("PLY file is not ASCII format: ","format = ", format[2:length(format)]) 41 | face <- NULL 42 | material <- NULL 43 | xline <- unlist(strsplit(grep(c("element vertex "), plyfile, value = TRUE), " ")) 44 | nvertices <- as.numeric(xline[grep(c("vertex"), xline) + 1]) 45 | yline <- unlist(strsplit(grep(c("element face"), plyfile, value = TRUE), " ")) 46 | nface <- as.numeric(yline[grep(c("face"), yline) + 1]) 47 | headerend <- grep(c("end_header"), plyfile) 48 | ncolpts <- (length(grep(c("property float"), plyfile))) 49 | cols <- grep(c("property float"), plyfile, value = TRUE) 50 | x <- grep(c(" x"), cols) 51 | y <- grep(c(" y"), cols) 52 | z <- grep(c(" z"), cols) 53 | nuchar <- (length(grep(c("property uchar"), plyfile))) 54 | points <- as.matrix(as.numeric(unlist(strsplit(plyfile[(headerend + 55 | 1):(headerend + nvertices)], " ")))) 56 | points <- matrix(points, nrow = nvertices, byrow = T) 57 | xpts <- points[,x] 58 | ypts <- points[,y] 59 | zpts <- points[,z] 60 | vertices <- rbind(xpts, ypts, zpts, 1) 61 | if (yline[3] == 0) {cat("Object has zero faces")} 62 | if (yline[3] != 0) { 63 | face <- as.matrix(as.numeric(unlist(strsplit(plyfile[(headerend + 64 | nvertices + 1):(headerend + nvertices + nface)], " ")))) 65 | face <- t(matrix(face, nrow = nface, byrow = T)) 66 | face <- face[2:4,] 67 | face = face +1 68 | } 69 | if (nuchar !=0) { 70 | color <- rgb(points[,4], points[,5], points[,6], maxColorValue = 255) 71 | material$color <- matrix(color[face], dim(face))} 72 | 73 | mesh <- list(vb = vertices, it = face, primitivetype = "triangle", 74 | material = material) 75 | class(mesh) <- c("mesh3d", "shape3d") 76 | if(addNormals==TRUE){ mesh <- addNormals(mesh)} 77 | if(ShowSpecimen==TRUE){ 78 | clear3d() 79 | if (length(face) == 0) { dot3d(mesh) } 80 | if (length(material) != 0){ shade3d(mesh, meshColor="legacy") } 81 | shade3d(mesh, meshColor="legacy") } 82 | return(mesh) 83 | } 84 | -------------------------------------------------------------------------------- /R/readland.tps.r: -------------------------------------------------------------------------------- 1 | #' Read landmark data from tps file 2 | #' 3 | #' Read *.tps file to obtain landmark coordinates 4 | #' 5 | #' This function reads a *.tps file containing two- or three-dimensional landmark coordinates. 6 | #' Tps files are text files in one of the standard formats for geometric morphometrics (see Rohlf 2010). 7 | #' Two-dimensional landmarks coordinates are designated by the identifier "LM=", while three-dimensional 8 | #' data are designated by "LM3=". Landmark coordinates are multiplied by their scale factor if this is 9 | #' provided for all specimens. If one or more specimens are missing the scale factor, landmarks are treated 10 | #' in their original units. 11 | #' 12 | #' Missing data may be present in the file. If data were digitized in geomorph or StereoMorph, these are 13 | #' automatically identified. If, instead, data digitizing took place in a software package that records missing 14 | #' values as negative coordinates (e.g. tpsDig), the user needs to specify whether negative values should be 15 | #' transformed to 'NAs' through the argument neg.NA = TRUE. The positions of missing landmarks may 16 | #' then be estimated using \code{\link{estimate.missing}}. 17 | #' 18 | #' The user may specify whether specimen names are to be extracted from the 'ID=' field or 'IMAGE=' field 19 | #' and included in the resulting 3D array. 20 | #' e.g., for 'ID=' use (file, specID = "ID") and for 'IMAGE=' use (file, specID = "imageID"). 21 | #' The default is specID="None". 22 | #' 23 | #' If there are curves defined in the file (i.e., CURVES= fields), the option 'readcurves' should be used. 24 | #' When readcurves = TRUE, the coordinate data for the curves will be returned as semilandmarks and will be appended to 25 | #' the fixed landmark data. Then the user needs to use \code{\link{define.sliders}} or \code{\link{define.sliders}} 26 | #' to create a matrix designating how the curve points will slide (used by 'curves=' in \code{\link{gpagen}}). 27 | #' When readcurves = FALSE, only the landmark data are returned. 28 | #' 29 | #' NOTE: At present, all other information that can be contained in tps files (comments, variables, radii, etc.) 30 | #' is ignored. 31 | #' 32 | #' @param file A *.tps file containing two- or three-dimensional landmark data 33 | #' @param specID a character specifying whether to extract the specimen ID names from the ID or IMAGE lines (default is "None"). 34 | #' @param negNA A logical value indicating whether negative landmark coordinates in the tps file should be imported as missing 35 | #' values and coded as 'NA' (TRUE), or imported as such. 36 | #' @param readcurves A logical value stating whether CURVES= field and associated coordinate data will be read as semilandmarks (TRUE) 37 | #' or ignored (FALSE). 38 | #' @param warnmsg A logical value stating whether warnings should be printed 39 | #' @export 40 | #' @keywords IO 41 | #' @author Dean Adams, Emma Sherratt, Michael Collyer & Antigoni Kaliontzopoulou 42 | #' @return Function returns a (p x k x n) array, where p is the number of landmark points, k is the number 43 | #' of landmark dimensions (2 or 3), and n is the number of specimens. The third dimension of this array 44 | #' contains names for each specimen, which are obtained from the image names in the *.tps file. 45 | #' 46 | #' @references Rohlf, F. J. 2010. tpsRelw: Relative warps analysis. Version 1.49. Department of Ecology 47 | #' and Evolution, State University of New York at Stony Brook, Stony Brook, NY. 48 | 49 | readland.tps <- function (file, specID = c("None", "ID", "imageID"), negNA = FALSE, 50 | readcurves = FALSE, warnmsg = TRUE) { 51 | lmi <- .readland.tps(file, specID, negNA, readcurves, warnmsg) 52 | tbl <- data.frame(id = names(lmi), 53 | p = sapply(lmi, NROW), 54 | k = sapply(lmi, NCOL)) 55 | rownames(tbl) <- NULL 56 | 57 | lm.check <- apply(tbl[, -1], 2, unique) 58 | 59 | if(is.list(lm.check)){ 60 | cat("\nEither the number of landmarks (p) or the landmark dimensions (k) differ\n") 61 | cat("among specimens. An array is not returned but the following table is\n") 62 | cat("provided so that discrepencies can be investigated.\n\n") 63 | 64 | print(tbl) 65 | lmo <- tbl 66 | 67 | } else { 68 | lmo <- simplify2array(lmi) 69 | } 70 | 71 | invisible(lmo) 72 | 73 | } 74 | -------------------------------------------------------------------------------- /man/compare.CR.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compare.CR.R 3 | \name{compare.CR} 4 | \alias{compare.CR} 5 | \title{Comparisons of Effect Sizes from Modularity Analyses} 6 | \usage{ 7 | compare.CR(..., CR.null = TRUE, two.tailed = TRUE) 8 | } 9 | \arguments{ 10 | \item{...}{saved analyses of class CR} 11 | 12 | \item{CR.null}{A logical value to indicate whether a Null CR model (no modularity) should also be included in analysis.} 13 | 14 | \item{two.tailed}{A logical value to indicate whether a two-tailed test (typical and default) should be performed.} 15 | } 16 | \value{ 17 | An object of class compare.CR, returns a list of the following 18 | \item{sample.z}{A vector of effect sizes for each sample.} 19 | \item{sample.r.sd}{A vector of standard deviations for each sampling distribution (following Box-Cox transformation).} 20 | \item{pairwise.z}{A matrix of pairwise, two-sample z scores between all pairs of effect sizes.} 21 | \item{pairwise.p}{A matrix of corresponding P-values.} 22 | } 23 | \description{ 24 | Function performs an analysis to compare the effect sizes of two or more CR effects 25 | } 26 | \details{ 27 | The function statistically compares the effect sizes of two or more CR analyses. Typically, this 28 | function might be used to compare levels of modularity between two or more samples, each measuring the degree 29 | of morphological modularity in each. Alternatively, the approach can compare the degree of modular signal as 30 | expressed by alternative modular hypotheses for the same dataset. 31 | 32 | The analysis calculates effect sizes as standard deviates, z, and performs two-sample z-tests, using the pooled 33 | standard error from the sampling distributions of the CR analyses. The method follows that of Adams and Collyer (2019) used 34 | to compare patterns of modularity across datasets. 35 | 36 | To use this function, simply perform \code{\link{modularity.test}}, or \code{\link{phylo.modularity}} on as many samples or 37 | alternative modular hypotheses as desired. Any number of objects of class CR can be input. For the case of the latter, one may wish to 38 | include the null hypothesis of no modularity (i.e., that all variables belong to a single module). For this, the CR.null = TRUE option 39 | should be specified. Finally, one may perform the comparison as either a one-tailed or a two-tailed (default) test. 40 | } 41 | \examples{ 42 | \dontrun{ 43 | 44 | # Example 1: Compare modular signal across datasets 45 | 46 | data(pupfish) 47 | Y.gpa<-gpagen(pupfish$coords, print.progress = FALSE) #GPA-alignment 48 | 49 | ## landmarks on the body and operculum 50 | land.gps<-rep('a',56); land.gps[39:48]<-'b' 51 | 52 | group <- factor(paste(pupfish$Pop, pupfish$Sex, sep = ".")) 53 | levels(group) 54 | 55 | coords.gp <- coords.subset(Y.gpa$coords, group) 56 | 57 | modul.tests <- Map(function(x) modularity.test(x, land.gps,iter=999, 58 | print.progress = FALSE), coords.gp) 59 | 60 | # the map function performs the integration test on each 3D array 61 | # in the lists provided 62 | 63 | modul.tests$Marsh.F 64 | modul.tests$Marsh.M 65 | modul.tests$Sinkhole.F 66 | modul.tests$Sinkhole.M 67 | 68 | group.Z <- compare.CR(modul.tests, CR.null = FALSE) 69 | summary(group.Z) 70 | 71 | # Example 2: Compare alternative modular hypotheses 72 | 73 | # 3 module hypothesis (tail now a module) 74 | land.gps3 <- rep('a',56); land.gps3[39:48]<-'b'; 75 | land.gps3[c(6:9,28:38)] <- 'c' 76 | 77 | # 4 module hypothesis (eye now a module) 78 | land.gps4 <- rep('a',56); land.gps4[39:48]<-'b'; 79 | land.gps4[c(6:9,28:38)] <- 'c'; 80 | land.gps4[c(10,49:56)] <- 'd' 81 | 82 | m3.test <- modularity.test(coords.gp$Marsh.F,land.gps3, 83 | print.progress = FALSE) 84 | m4.test <- modularity.test(coords.gp$Marsh.F,land.gps4, 85 | print.progress = FALSE) 86 | 87 | model.Z <- compare.CR(modul.tests$Marsh.F,m3.test,m4.test, 88 | CR.null = TRUE) 89 | summary(model.Z) 90 | } 91 | } 92 | \references{ 93 | Adams, D.C. and M.L. Collyer. 2019. Comparing the strength of modular signal, and evaluating alternative modular hypotheses, 94 | using covariance ratio effect sizes for morphometric data. Evolution. 73:2352-2367. 95 | } 96 | \author{ 97 | Dean Adams and Michael Collyer 98 | } 99 | \keyword{analysis} 100 | -------------------------------------------------------------------------------- /man/digitize2d.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/digitize2d.r 3 | \name{digitize2d} 4 | \alias{digitize2d} 5 | \title{Digitize 2D landmarks on .jpg files} 6 | \usage{ 7 | digitize2d( 8 | filelist, 9 | nlandmarks, 10 | scale = NULL, 11 | tpsfile, 12 | MultScale = FALSE, 13 | verbose = TRUE 14 | ) 15 | } 16 | \arguments{ 17 | \item{filelist}{A list of names of jpeg images to be digitized.} 18 | 19 | \item{nlandmarks}{Number of landmarks to be digitized.} 20 | 21 | \item{scale}{A vector containing the length of the scale to be placed on each image.} 22 | 23 | \item{tpsfile}{The name of a TPS file to be created or read} 24 | 25 | \item{MultScale}{A logical option indicating if the coordinates should be pre-multiplied by scale} 26 | 27 | \item{verbose}{logical. User decides whether to digitize in verbose or silent format (see details), default is verbose} 28 | } 29 | \value{ 30 | Function returns a tps file containing the digitized landmark coordinates. 31 | } 32 | \description{ 33 | An interactive function to digitize two-dimensional(2D) landmarks from .jpg files. 34 | } 35 | \details{ 36 | This function may be used for digitizing 2D landmarks from jpeg images (.jpg). The user provides 37 | a list of image names, the number of landmarks to be digitized, and the name of an output 38 | TPS file. An option is included to allow the user to digitize a scale on each image to convert 39 | the landmark coordinates from pixels into meaningful units. Landmarks to be digitized can include 40 | both fixed landmarks and semi-landmarks, the latter of which are to be designated as "sliders" 41 | for subsequent analysis (see the function \code{\link{define.sliders}}). 42 | 43 | \subsection{The Digitizing Session}{ 44 | Digitizing landmarks from 2D photos requires that a scale bar is placed in the image in order to scale the coordinate 45 | data. The 'scale' option requires: a single number (e.g. 10) which means that the scale to be measured in all images 46 | is a 10mm scale bar; OR a vector the same length as the filelist containing a number for the scale of each image. 47 | If scale=NULL, then the digitized coordinates will not be scaled. This option is NOT recommended. 48 | 49 | Users may digitize all specimens in one session, or may return at a later time to complete digitizing. In the latter 50 | case, the user provides the same filelist and TPS file and the function will determine where the user left off. 51 | 52 | If specimens have missing landmarks, these can be incorporated during the digitizing process using the 'a' option 53 | as described below (a=absent). 54 | } 55 | 56 | 57 | \subsection{Specimen Digitizing}{ 58 | Digitizing landmarks involves landmark selection using a mouse in the plot window, 59 | using the LEFT mouse button (or regular button for Mac users): 60 | \enumerate{ 61 | \item Digitize the scale bar (if requested) by selecting the two end points. Use a single click for start and end points. The 62 | user is asked whether the system should keep or discard the digitized scale bar. 63 | \item Digitize each landmark with single click and the landmark is shown in red. 64 | } 65 | If verbose = TRUE, digitizing is interactive between landmark selection using a mouse and the R console. 66 | Once a landmark is selected, the user is asked if the system should keep or discard the 67 | selection (y/n/a). If "y", the user is asked to continue to select the next landmark. If "n", the user is 68 | asked to select it again. 69 | 70 | To digitize a missing landmark, simply click on any location in the image. Then, when 71 | prompted to keep selection, choose 'a' (for absent). Missing landmarks can only be included during the digitizing process when verbose=TRUE. 72 | 73 | If verbose = FALSE the digitizing of landmarks is continuous and uninterrupted. Here the user will not be prompted to approve each landmark selection. 74 | 75 | At the end of digitizing, the landmark coordinates are written to a TPS file. By default, the 76 | x,y values are unscaled if a vector of scales is included, and the scale is returned on line 77 | SCALE= after each specimen x,y data. Optionally, one may have the coordinates pre-multiplied by 78 | scale by using the option MultScale=TRUE. 79 | } 80 | } 81 | \seealso{ 82 | \code{\link[jpeg]{readJPEG}} (for JPEG input) 83 | } 84 | \author{ 85 | Dean Adams, Erik Otarola-Castillo and Emma Sherratt 86 | } 87 | \keyword{digitizing} 88 | -------------------------------------------------------------------------------- /R/plotAllSpecimens.r: -------------------------------------------------------------------------------- 1 | #' Plot landmark coordinates for all specimens 2 | #' 3 | #' Function plots landmark coordinates for a set of specimens 4 | #' 5 | #' The function creates a plot of the landmark coordinates for all specimens. This is useful for examining 6 | #' patterns of variation in Procrustes shape variables, after a GPA has been performed. If "mean = TRUE", the mean shape will be calculated and added to the plot. 7 | #' Additionally, if a matrix of links is provided, the landmarks of the mean shape will be connected by lines. 8 | #' The link matrix is an m x 2 matrix, where m is the desired number of links. Each row of the link matrix 9 | #' designates the two landmarks to be connected by that link. The function will plot either two- or 10 | #' three-dimensional data (e.g. see \code{\link{define.links}}). 11 | #' 12 | #' @param A A 3D array (p x k x n) containing Procrustes shape variables for a set of specimens 13 | #' @param mean A logical value indicating whether the mean shape should be included in the plot 14 | #' @param links An optional matrix defining for links between landmarks (only if mean=TRUE) 15 | #' @param label A logical value indicating whether landmark numbers will be plotted (only if mean=TRUE) 16 | #' @param plot_param A list of plot parameters for the points (pt.bg, pt.cex), mean (mean.bg, mean.cex), links (link.col, link.lwd, link.lty) and landmark labels (txt.cex, txt.adj, txt.pos, txt.col) 17 | #' @export 18 | #' @keywords visualization 19 | #' @author Dean Adams 20 | #' @seealso \code{\link[rgl]{rgl-package}} (used in 3D plotting) 21 | #' @examples 22 | #' \dontrun{ 23 | #' data(plethodon) 24 | #' Y.gpa <- gpagen(plethodon$land) #GPA-alignment 25 | #' 26 | #' plotAllSpecimens(Y.gpa$coords, links = plethodon$links) 27 | #' } 28 | plotAllSpecimens<-function(A,mean=TRUE,links=NULL,label=FALSE,plot_param = list()){ 29 | if (length(dim(A))!=3){ 30 | stop("Data matrix not a 3D array (see 'arrayspecs').") } 31 | if(any(is.na(A))==T){ 32 | stop("Data matrix contains missing values. Estimate these first (see 'estimate.missing').") } 33 | k<-dim(A)[2] 34 | if(mean==TRUE){ mn<-mshape(A) } 35 | 36 | p.p <- plot_param 37 | if(is.null(p.p$pt.bg)) p.p$pt.bg="gray" ; if(is.null(p.p$pt.cex)) p.p$pt.cex=1 ; 38 | if(is.null(p.p$mean.bg)) p.p$mean.bg="black" ; if(is.null(p.p$mean.cex)) p.p$mean.cex=2 39 | if(is.null(p.p$link.col)) p.p$link.col="black" ; if(is.null(p.p$link.lwd)) p.p$link.lwd=2 40 | if(is.null(p.p$link.lty)) p.p$link.lty=1 ; if(is.null(p.p$txt.adj)) p.p$txt.adj=c(-.1,-.1) 41 | if(is.null(p.p$txt.col)) p.p$txt.col="black" ; if(is.null(p.p$txt.cex)) p.p$txt.cex=0.8 42 | if(is.null(p.p$txt.pos)) p.p$txt.pos=1 43 | 44 | if(k==2){ 45 | plot(A[,1,],A[,2,],asp=1, pch=21,bg=p.p$pt.bg,cex=p.p$pt.cex*1,xlab="x",ylab="y") 46 | if(mean==TRUE){ 47 | if(is.null(links)==FALSE){ 48 | linkcol <- rep(p.p$link.col,nrow(links))[1:nrow(links)] 49 | linklwd <- rep(p.p$link.lwd,nrow(links))[1:nrow(links)] 50 | linklty <- rep(p.p$link.lty,nrow(links))[1:nrow(links)] 51 | for (i in 1:nrow(links)){ 52 | segments(mn[links[i,1],1],mn[links[i,1],2],mn[links[i,2],1],mn[links[i,2],2], 53 | col=linkcol[i],lty=linklty[i],lwd=linklwd[i]) 54 | } 55 | } 56 | points(mn,pch=21,bg=p.p$mean.bg,cex=p.p$mean.cex) 57 | if(label == TRUE){text(mn, label=paste(1:dim(mn)[1]),adj=(p.p$txt.adj+p.p$mean.cex), 58 | pos=p.p$txt.pos,cex=p.p$txt.cex,col=p.p$txt.col)} 59 | } 60 | } 61 | if(k==3){ 62 | A3d<-NULL 63 | for (i in 1:dim(A)[[3]]){ 64 | A3d<-rbind(A3d,A[,,i]) 65 | } 66 | plot3d(A3d,type="s",col=p.p$pt.bg,xlab="x",ylab="y",zlab="z",size=p.p$pt.cex*1.5,aspect=FALSE) 67 | if(mean==TRUE){ 68 | if(is.null(links)==FALSE){ 69 | linkcol <- rep(p.p$link.col,nrow(links))[1:nrow(links)] 70 | linklwd <- rep(p.p$link.lwd,nrow(links))[1:nrow(links)] 71 | linklty <- rep(p.p$link.lty,nrow(links))[1:nrow(links)] 72 | for (i in 1:nrow(links)){ 73 | segments3d(rbind(mn[links[i,1],],mn[links[i,2],]), 74 | col=linkcol[i],lty=linklty[i],lwd=linklwd[i]) 75 | } 76 | } 77 | points3d(mn,color=p.p$mean.bg,size=p.p$mean.cex*2) 78 | if(label == TRUE){text3d(mn, texts = paste(1:dim(mn)[1]), adj=(p.p$txt.adj+p.p$mean.cex), 79 | pos=p.p$txt.pos,cex=p.p$txt.cex,col=p.p$txt.col)} 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /R/warpRefMesh.r: -------------------------------------------------------------------------------- 1 | #' Creates a mesh3d object warped to the mean shape 2 | #' 3 | #' A function that uses the thin-plate spline to warp a 3D mesh into a shape defined 4 | #' by a set of landmark coordinates. 5 | #' 6 | #' Function takes a 3D mesh (class mesh3d or shape3d, e.g. from \code{\link{read.ply}}) and its digitized landmark coordinates 7 | #' and uses the thin-plate spline method (Bookstein 1989) to warp the mesh into the shape 8 | #' defined by a second set of landmark coordinates, usually those of the 9 | #' mean shape for a set of aligned specimens. It is highly recommended that the mean shape is used as the 10 | #' reference for warping (see Rohlf 1998). The workflow is as follows: 11 | #' \enumerate{ 12 | #' \item {Calculate the mean shape using \code{\link{mshape}}} 13 | #' \item{Choose an actual specimen to use for the warping. The specimen used as the template for this warping 14 | #' is recommended as one most similar in shape to the average of the sample, but can be any reasonable 15 | #' specimen - do this by eye, or use \code{\link{findMeanSpec}} } 16 | #' \item{Warp this specimen into the mean shape using \code{\link{warpRefMesh}} } 17 | #' \item{Use this average mesh where it asks for a mesh= in the analysis functions and visualization functions } 18 | #' } 19 | #' Users should ensure that their mesh and mesh.coord matrix are in the same scale (a common issue is that the mesh is in micrometers and coordinates are in mm or cm). Use range(mesh$vb[1:3,]) and range(mesh.coord) to check and adjust mesh.coord as necessary. 20 | #' 21 | #' For landmark coordinates digitized with geomorph digitizing functions, centered = TRUE. This refers to the 22 | #' specimen being centered prior to landmark acquisition in the RGL window. For landmark data collected outside 23 | #' of geomorph, centered=FALSE will usually be the case. The returned mesh3d object is for use in geomorph 24 | #' functions where shape deformations are plotted (\code{\link{picknplot.shape}}, 25 | #' \code{\link{two.b.pls}}, \code{\link{bilat.symmetry}}, and \code{\link{plotRefToTarget}}). 26 | #' 27 | #' @param mesh A mesh3d object (e.g. made by \code{\link{read.ply}}) 28 | #' @param mesh.coord A p x k matrix of 3D coordinates digitized on the ply file. 29 | #' @param ref A p x k matrix of 3D coordinates made by \code{\link{mshape}} 30 | #' @param color Color to set the ply file $material. If the ply already has color, use NULL. 31 | #' For ply files without color, color=NULL will be plotted as gray. 32 | #' @param centered Logical If the data in mesh.coords were collected from a centered mesh (see details). 33 | #' @export 34 | #' @seealso \code{\link{findMeanSpec}} 35 | #' @keywords utilities 36 | #' @keywords visualization 37 | #' @author Emma Sherratt 38 | #' @seealso \code{\link[rgl]{rgl-package}} (used in 3D plotting) 39 | #' @return Function returns a mesh3d object, which is a list of class mesh3d (see rgl for details) 40 | #' @references Bookstein, F. L. 1989 Principal Warps: Thin-Plate Splines and the Decomposition 41 | #' of Deformations. IEEE Transactions on Pattern Analysis and Machine Intelligence 11(6):567-585. 42 | #' @references Rohlf, F. J. 1998. On Applications of Geometric Morphometrics to Studies of Ontogeny and Phylogeny. Systematic Biology. 47:147-158. 43 | warpRefMesh <- function(mesh, mesh.coord, ref, color=NULL, centered=FALSE){ 44 | if (inherits(mesh, "mesh3d") == FALSE){ 45 | stop ("File is not a mesh3d object or xyz matrix") } 46 | plotspec(mesh, mesh.coord, centered=centered) #changed from just 'centered' 6/25/2020 47 | title3d(main="Imported Mesh") 48 | mesh.vb <- as.matrix(t(mesh$vb)[,-4]) 49 | if (centered == TRUE){ mesh.vb <- scale(mesh.vb, scale = FALSE) } 50 | checkmat <- is.matrix(mesh.coord) 51 | if (checkmat==FALSE) { stop("Input must be a p-x-k matrix of landmark coordinates")} 52 | checkdim <- dim(mesh.coord)[2] 53 | if (checkdim==2) {stop("Input must be a p-x-k matrix of three-dimensional landmark coordinates") } 54 | coord <- scale(mesh.coord, scale=F) 55 | sc.mat <- matrix(rep(1,nrow(mesh.vb)), ncol=1) %*% apply(mesh.coord,2,mean) 56 | mesh.vb <- mesh.vb - sc.mat 57 | cat("\nWarping mesh\n") 58 | warp <- tps2d3d(mesh.vb, coord, ref) 59 | mesh$vb[1:3,] <- t(warp) 60 | if(is.null(mesh$material)) mesh$material <- list() 61 | if(!is.null(color)){ mesh$material$color <- color } 62 | if(is.null(color) && is.null(mesh$material$color)) { mesh$material$color <- "gray" } 63 | if(!is.null(mesh$normals)){ mesh <- addNormals(mesh)} 64 | open3d(); shade3d(mesh, meshColor="legacy"); title3d(main="Warped Ref Mesh") 65 | return(mesh) 66 | } 67 | -------------------------------------------------------------------------------- /R/warpRefOutline.r: -------------------------------------------------------------------------------- 1 | #' Creates a 2D outline warped to the mean shape 2 | #' 3 | #' A function to take an outline (defined by many points) and use thin-plate spline method to warp the outline 4 | #' into the estimated mean shape for a set of aligned specimens. 5 | #' 6 | #' Function takes an outline (defined by many points) with a set of fixed landmark coordinates and uses the thin-plate spline method (Bookstein 1989) 7 | #' to warp the outline into the shape defined by a second set of landmark coordinates, usually those of the 8 | #' mean shape for a set of aligned specimens. It is highly recommended that the mean shape is used as the 9 | #' reference for warping (see Rohlf 1998). The workflow is as follows: 10 | #' \enumerate{ 11 | #' \item {Calculate the mean shape using \code{\link{mshape}}} 12 | #' \item{Choose an actual specimen to use for the warping. The specimen used as the template for this warping 13 | #' is recommended as one most similar in shape to the average of the sample, but can be any reasonable 14 | #' specimen - do this by eye, or use \code{\link{findMeanSpec}} } 15 | #' \item{Warp this specimen into the mean shape using \code{\link{warpRefOutline}} } 16 | #' \item{Use this average outline where it asks for a outline= in the analysis functions and visualization functions } 17 | #' } 18 | #' The returned outline object is for use in geomorph 19 | #' functions where shape deformations are plotted (\code{\link{picknplot.shape}}, 20 | #' \code{\link{two.b.pls}}, \code{\link{bilat.symmetry}}, and \code{\link{plotRefToTarget}}). 21 | #' 22 | #' @param file A .txt or .csv file of the outline point coordinates, or a .TPS file with OUTLINES= or CURVES= elements 23 | #' @param coord A p x k matrix of 2D fixed landmark coordinates 24 | #' @param ref A p x k matrix of 2D coordinates made by \code{\link{mshape}} 25 | #' @export 26 | #' @seealso \code{\link{findMeanSpec}} 27 | #' @keywords utilities 28 | #' @keywords visualization 29 | #' @author Emma Sherratt 30 | #' @return Function returns an outline object 31 | #' @references Bookstein, F. L. 1989 Principal Warps: Thin-Plate Splines and the Decomposition 32 | #' of Deformations. IEEE Transactions on Pattern Analysis and Machine Intelligence 11(6):567-585. 33 | #' @references Rohlf, F. J. 1998. On Applications of Geometric Morphometrics to Studies of Ontogeny and Phylogeny. Systematic Biology. 47:147-158. 34 | warpRefOutline <- function(file, coord, ref){ 35 | checkmat <- is.matrix(coord) 36 | if (checkmat==FALSE) { stop("Input must be a p-x-k matrix of landmark coordinates")} 37 | checkdim <- dim(coord)[2] 38 | if (checkdim==3) {stop("Input must be a p-x-k matrix of two-dimensional landmark coordinates") } 39 | if(grepl(".txt", file, ignore.case=TRUE) == TRUE) {outline <- as.matrix(read.table(file, header = F))[,1:2] 40 | npoints <- as.vector(nrow(outline)) } 41 | if(grepl(".csv", file, ignore.case=TRUE) == TRUE) {outline <- as.matrix(read.csv(file, header = F))[,1:2] 42 | npoints <- as.vector(nrow(outline))} 43 | if(grepl(".tps", file, ignore.case=TRUE) == TRUE) { 44 | tpsfile <- scan(file = file, what = "char", sep = "\n", quiet = TRUE) 45 | curves <- grep("POINTS=", tpsfile) 46 | npoints <- as.numeric(sub("POINTS=", "", tpsfile[curves])) 47 | outline = NULL 48 | for (i in 1:length(curves)){ 49 | tmp <- tpsfile[(curves[i]+1): ((curves[i])+npoints[i])] 50 | outline <- rbind(outline, matrix(as.numeric(unlist(strsplit(tmp, split = " +"))), ncol = 2, byrow = T)) } 51 | imscale <- as.numeric(sub("SCALE=", "", tpsfile[grep("SCALE", tpsfile)])) 52 | if (identical(imscale, numeric(0)) == TRUE) {imscale = 1} 53 | outline <- outline * imscale 54 | } 55 | if(sum(range(outline[,1])) < sum(range(outline[,2]))){ layout(t(c(1,2))) } 56 | if(sum(range(outline[,1])) > sum(range(outline[,2]))){ layout(c(1,2)) } 57 | plot(outline, pch=19, cex=0.3, main = "Imported outline", asp=T, xlab="x", ylab="y") 58 | points(coord, pch=19, col="red") 59 | text(coord, labels = c(1:nrow(coord)), adj=2) 60 | coord.sc <- scale(coord, scale=F) 61 | sc.mat <- matrix(rep(1,nrow(outline)), ncol=1) %*% apply(coord,2,mean) 62 | outline <- outline - sc.mat 63 | warp <- tps2d(outline, coord.sc, ref) 64 | plot(warp, pch=19, cex=0.3, main = "Warped outline", asp=T, xlab="x", ylab="y") 65 | points(ref, pch=19, cex=0.8, col= "red") 66 | text(ref, labels = c(1:nrow(ref)), adj=2) 67 | layout(1) 68 | return(list(outline=warp, npoints = npoints)) 69 | } 70 | -------------------------------------------------------------------------------- /R/shapeHulls.r: -------------------------------------------------------------------------------- 1 | #' Update Plots with Convex Hulls for Groups 2 | #' 3 | #' This function is used to update \code{\link{plot.procD.lm}} and \code{\link{plot.gm.prcomp}} ordination plot 4 | #' objects with convex hulls for different groups. If no groups are defined (groups is NULL) just a single 5 | #' convex hull will be returned. Groups do not need to be a factor in the original \code{\link{procD.lm}} fit. 6 | #' 7 | #' This function is a wrapper for the \code{\link{points}} function. It is intentionally limited, so 8 | #' as to not interfere with other plot parameter adjustments. 9 | #' 10 | #' @param x A \code{\link{plot.procD.lm}} or \code{\link{plot.gm.prcomp}} plot object. 11 | #' @param groups An optional vector or factor to define groups for hull. If NULL, only one hull will be generated for all points. 12 | #' @param group.cols An optional vector to define hull colors, arranged in the same order as factor levels. If NULL and if multiple groups 13 | #' exist, the general R color sequence (black, red, green, blue, etc.) will be used. 14 | #' @param group.lwd An optional vector equal in length to the number of group levels, and arranged in the order of group levels, 15 | #' to modify hull line width. 16 | #' @param group.lty An optional vector equal in length to the number of group levels, and arranged in the order of group levels, 17 | #' to modify hull line type. 18 | #' @export 19 | #' @author Michael Collyer 20 | #' @seealso \code{\link{procD.lm}} 21 | #' @keywords utilities 22 | #' @examples 23 | #' \dontrun{ 24 | #' # Via procD.lm and plot.procD.lm 25 | #' 26 | #' data("pupfish") 27 | #' gdf <- geomorph.data.frame(coords = pupfish$coords, Sex = pupfish$Sex, 28 | #' Pop = pupfish$Pop) 29 | #' fit <- procD.lm(coords ~ Pop * Sex, data = gdf, print.progress = FALSE) 30 | #' pc.plot <- plot(fit, type = "PC", pch = 19) 31 | #' shapeHulls(pc.plot) 32 | #' 33 | #' pc.plot <- plot(fit, type = "PC", pch = 19) 34 | #' groups <- interaction(gdf$Pop, gdf$Sex) 35 | #' 36 | #' shapeHulls(pc.plot, groups = groups, 37 | #' group.cols = c("dark red", "dark red", "dark blue", "dark blue"), 38 | #' group.lwd = rep(2, 4), group.lty = c(2, 1, 2, 1)) 39 | #' 40 | #' legend("topright", levels(groups), 41 | #' col = c("dark red", "dark red", "dark blue", "dark blue"), 42 | #' lwd = rep(2,4), lty = c(2, 1, 2, 1)) 43 | #' 44 | #' pc.plot <- plot(fit, type = "PC", pch = 19) 45 | #' shapeHulls(pc.plot, groups = gdf$Sex, group.cols = c("black", "black"), 46 | #' group.lwd = rep(2, 2), group.lty = c(2, 1)) 47 | #' legend("topright", levels(gdf$Sex), lwd = 2, lty = c(2, 1)) 48 | #' 49 | #' # Via gm.prcomp and plot.gm.prcomp 50 | #' 51 | #' data(plethspecies) 52 | #' Y.gpa <- gpagen(plethspecies$land) #GPA-alignment 53 | #' pleth.phylo <- gm.prcomp(Y.gpa$coords, phy = plethspecies$phy) 54 | #' summary(pleth.phylo) 55 | #' 56 | #' pc.plot <- plot(pleth.phylo, phylo = TRUE) 57 | #' gp <- factor(c(rep(1, 5), rep(2, 4))) 58 | #' shapeHulls(pc.plot, groups = gp, group.cols = 1:2, 59 | #' group.lwd = rep(2, 2), group.lty = c(2, 1)) 60 | #' legend("topright", c("P. cinereus clade", "P. hubrichti clade"), 61 | #' col = 1:2, lwd = 2, lty = c(2, 1)) 62 | #' } 63 | 64 | shapeHulls <- function(x, groups = NULL, group.cols = NULL, 65 | group.lwd = NULL, group.lty = NULL){ 66 | y <- as.matrix(x$PC.points) 67 | if(NCOL(y) < 2) stop("Cannot generate hulls in fewer than 2 dimensions") 68 | if(NCOL(y) > 2) y <- y[,1:2] 69 | n <- NROW(y) 70 | if(!is.null(groups) && length(groups) != n ) stop("Different number of observations between groups factor and PC plot.\n", 71 | call. = FALSE) 72 | 73 | if(is.null(groups)) groups <- rep(1, n) 74 | groups <- as.factor(groups) 75 | if(length(unique(groups)) != length(levels(groups))) 76 | warning("The levels in the grouping factor do not match the number of unique factor levels.\n", 77 | call. = FALSE, immediate. = TRUE) 78 | ug <- unique(groups) 79 | g <- length(ug) 80 | if(is.null(group.cols)) group.cols <- 1:g 81 | if(is.null(group.lwd)) group.lwd <- rep(1, g) 82 | if(is.null(group.lty)) group.lty <- rep(1, g) 83 | if(length(group.cols) != g) stop("Number of requested group colors does not match the number of groups") 84 | if(length(group.lwd) != g) stop("Number of requested group widths does not match the number of groups") 85 | if(length(group.lty) != g) stop("Number of requested group line types does not match the number of groups") 86 | 87 | for(i in 1:g){ 88 | yy <- y[groups == ug[i],] 89 | chp <- chull(yy) 90 | chp <- c(chp, chp[1]) 91 | points(yy[chp,], type = "l", lty = group.lty[i], 92 | lwd = group.lwd[i], col = group.cols[i]) 93 | } 94 | } 95 | --------------------------------------------------------------------------------