[R-sig-phylo] Boostrap and likelihood values on branches
Dear all, I used a very raw 18S phylogeny of Craniates to introduce phylogeny to students, and I would like to estimate bootstrap or likelihood values for branches. Sorry for this long message, but I hope you can answer at least some of my questions. 1) For bootstrapping, I obtain zero values for some of them and wonder : i) if it is possible (and how to interpret it) ; ii) what to change to correct it ? Here is the script (the alnx.fasta file can be found at the end of this message) : library(ape) alnx2 - read.dna(file = alnx.fasta, format = fasta) alnxdist - dist.dna(alnx2, model = raw, pairwise.deletion = FALSE) trx - nj(alnxdist) rtrx - root(trx, Branchiostoma) plot(rtrx) bp - boot.phylo(rtrx, alnx2, function(x) nj(dist.dna(x, model = raw, pairwise.deletion = FALSE))) # I also obtain zero values if pairwise.deletion = TRUE nodelabels(bp) 2) Secondly, I also would like to obtain likelihood values for branches (I think it is the second common kind of values found on branches, with bootstrap ones), but could not find a function to do so. Would you know one ? If I try maximum likelihood estimation, are those likelihood values calculated for the branches ? I see them for trees and sites, but not for branches… library(phangorn) alnx2pml - pml(rtrx, as.phyDat(alnx2)) alnx2pmloptim - optim.pml(alnx2pml) # This is just a test ; I don't really need a model plot(alnx2pmloptim) #The following commands do not seem to be a great idea (for boostrap) ; my computer doesn't like them… # bp2 - boot.phylo(rtrx, alnx2, function(x) optim.pml( pml( nj(dist.dna(x)) , as.phyDat(x)) ) ) # nodelabels(bp2) 3) Then, where to find likelihood values after a mrbayes run ? library(phyloch) mrbayes(alnx2, path = getwd(),ngen = 100, file = test.con, run = FALSE) # I obtain the file I can use then in mrbayes 4) Eventually, for parsimony, what do the parsimony score represent ? Is it a way to weight it ? I suppose the answer is no, and parsimony scores are only there to compare them, not to deduce what is a good or bad score… alnx2pars - parsimony(rtrx, as.phyDat(alnx2)) alnx2parsoptim - optim.parsimony(rtrx, as.phyDat(alnx2)) plot(alnx2parsoptim) Thanks a lot in advance for your answer. All the best, Gwennaël Bataille ___ Salmo aagccatgcaagtctaagtacacacggcc-ggtacagtgaaactgcgaatggctcattaaatcagttatggttcctttgatcgctccaac-gt--tacttggataactgtggcaattctagagctaatacatgcagacga-gcgctgacc-tccatgcgtgcatttatcag-acccaaa---acc---catgcgggccaa-tctcggttgccccggccgctttggtgactctagataacctcg--agccgatcgcgcgccctttgtggcggtgacgtctcattcgaatgtctgccctatcaactttcgatggtactttctgtgcctaccatggtgaccacgggtaacaatcagggttcgattccggagagggagcctgagaaacggctaccacatccaaggaaggcagcaggcgcgcaaattacccactcccgactcaggtagtgacgataacaatacaggactctttcgaggccctgtaattggaatgagtacactttaaatccttta-acgaggatccattggagggcaagtctggtgccagcagccgcggtaattccagctccaatagcgtatcttaaagttgctgcagttagctcgtagttggatctcgggatcgagctggcgg--tccgccgcgaggcgagctaccgcctgtc-ccagtgcctctcggcgctcga-tgctcttaactg-agtgtcccgc--tccgaagcgtttactttgaattagagtgttcaaagcaggcccggtcg--cctgaataccgcagctaggaataatggaataggactccggt-tctagtgggtcttctgaac-tccatgattaagagggacggccgcattcgtattgtgccgctagaggtgaaattcttggaccggcgcaagacggacgaaagcgaaagcatttgccaagaatgcattaatcaagaacgaaagtcggaggttcgaagacgatcaga-taccgtcgtagttccgaccataaacgatgccaactagcgatccggcggcgtt-attcccatgacccgccgggcagc-gtccgggaaaccaa-agtctttgggttccggagtatggttgcaaagctgaaacttaaaggaattgacggaagggcaccaccaggagtggagcctgcggcttaatttgactcaacacgggaaacctcacccggcccggacacggaaaggattgacagattgatagctctttctcgattctgtgggtggtggtgcatggccgttcttagttggtggagcgatttgtctggttaattccgataacgaacgagactccggcatgctaactagttatgcggg--agcggtcggcgt-ccaacttcttagagggacaagtggcgttcagccacacgagattgagcaataacaggtctgtgatgcccttagatgtccctgcacgcgcgccacactgagcggatcagcgtgtgtct-acccttcgccgagaggcgtgggtaacccgctgaaactcgtgatagggattattgcaattatttcccatgaacgaggaattcccagtaagcgcgggtcataagctcgcgttgattaagtccctgccctttgtacacaccgcccgtcgctactaccgattggatggtttagtgaggtcctcggatcggccctgccgagg-tcggtcacggccc-tggtggagcgccgagaagacgatcaaacttgactatctagaggaagtgt--- Bufo
[R-sig-phylo] 3. partial correlation with gls residuals? (Tom Schoenemann)
Dear Tom, There is no reason to assume that the residuals from your two PGLS analyses will be independent of phylogeny, so if you are going to do this you should correlate the residuals phylogenetically (i.e. run them through PGLS). General problems with using residuals as data have been commented on in the literature by people like Freckleton, but I think that in the situation where each variable of interest is regressed on the same confounding variable it is valid to use residuals - because the correlation between the residuals is the same as the partial correlation between them. However, the simplest solution for this analysis would be to regress A on B and C in a single PGLS. Rob Barton On 12/03/2012 11:00, r-sig-phylo-requ...@r-project.org r-sig-phylo-requ...@r-project.org wrote: 3. partial correlation with gls residuals? (Tom Schoenemann) Hello, I was hoping to get some feedback on whether I'm doing something legitimate. Basically, I have 3 variables (say: A, B, and C) measured on 100 species, and I want to see whether A and B correlate with each other after controlling for C, and for phylogeny at the same time. Here is what I thought seems reasonable: 1) do a gls with variable A predicted by variable C, using a corPagel correlations structure derived from a phylogeny of these species to control for phylogenetic effects. The residuals from this are then extracted 2) do a gls with variable B predicted by variable C, using the same method, also extracting the residuals for this comparison 3) do a simple lm of the residuals from step 1 vs. the residuals from step 2 I guess my question is, are the residuals from the gls independent of my phylogeny? If they are, then wouldn't this give me the partial correlation between A and B, controlling for C, and for phylogeny? Or is there a better (or alternative) way to do this? Thanks for any suggestions, -Tom - Professor Robert Barton Professor of Evolutionary Anthropology President, European Human Behaviour Evolution Association email: r.a.bar...@durham.ac.uk Address: Department of Anthropology, Durham University, Dawson Building, South Road, Durham, DH1 3LE U.K. Tel.+44 (0)191 334 1603 Mobile +44 (0)7507564773 RAI's First Annual Postgraduate Conference at Durham 2011: http://www.dur.ac.uk/rai.postgrad/ http://www.dur.ac.uk/rai.postgrad/ Department: http://www.dur.ac.uk/anthropology/ Evolutionary Anthropology Research Group: http://www.dur.ac.uk/anthropology/research/earg/ Phylogeny of Sleep project: http://www.bu.edu/phylogeny/ Evolutionary Architecture of Reproduction project: http://www.dur.ac.uk/reproductionproject/ European Human Behaviour Evolution Association: http://www.ehbea.com/ ___ R-sig-phylo mailing list R-sig-phylo@r-project.org https://stat.ethz.ch/mailman/listinfo/r-sig-phylo
Re: [R-sig-phylo] Boostrap and likelihood values on branches
Dear Gwennaël, first it seems there was a bug in the function prop.clades from ape introduced recently, results in many zeros of bootstrap values. This function needs to be replaced in the ape package: prop.clades - function (phy, ..., part = NULL, rooted = FALSE) { if (is.null(part)) { obj - list(...) if (length(obj) == 1 class(obj[[1]]) != phylo) obj - unlist(obj, recursive = FALSE) part - prop.part(obj, check.labels = TRUE) } bp - prop.part(phy) if (!rooted){ bp - postprocess.prop.part(bp) part - postprocess.prop.part(part) # This line I added!! } n - numeric(phy$Nnode) for (i in seq_along(bp)) { for (j in seq_along(part)) { if (identical(bp[[i]], part[[j]])) { n[i] - attr(part, number)[j] done - TRUE break } } } n } On 3/12/12, Gwennaël Bataille gwennael.batai...@uclouvain.be wrote: Dear all, I used a very raw 18S phylogeny of Craniates to introduce phylogeny to students, and I would like to estimate bootstrap or likelihood values for branches. Sorry for this long message, but I hope you can answer at least some of my questions. 1) For bootstrapping, I obtain zero values for some of them and wonder : i) if it is possible (and how to interpret it) ; ii) what to change to correct it ? Here is the script (the alnx.fasta file can be found at the end of this message) : library(ape) alnx2 - read.dna(file = alnx.fasta, format = fasta) alnxdist - dist.dna(alnx2, model = raw, pairwise.deletion = FALSE) trx - nj(alnxdist) rtrx - root(trx, Branchiostoma) plot(rtrx) bp - boot.phylo(rtrx, alnx2, function(x) nj(dist.dna(x, model = raw, pairwise.deletion = FALSE))) # I also obtain zero values if pairwise.deletion = TRUE nodelabels(bp) 2) Secondly, I also would like to obtain likelihood values for branches (I think it is the second common kind of values found on branches, with bootstrap ones), but could not find a function to do so. Would you know one ? If I try maximum likelihood estimation, are those likelihood values calculated for the branches ? I see them for trees and sites, but not for branches… The branch length in a ML tree are (proportional to) time (molecular clock) or the expected number of substitutions per site. library(phangorn) alnx2pml - pml(rtrx, as.phyDat(alnx2)) alnx2pmloptim - optim.pml(alnx2pml) # This is just a test ; I don't really need a model plot(alnx2pmloptim) #The following commands do not seem to be a great idea (for boostrap) ; my computer doesn't like them… # bp2 - boot.phylo(rtrx, alnx2, function(x) optim.pml( pml( nj(dist.dna(x)) , as.phyDat(x)) ) ) # nodelabels(bp2) There is function for bootstrapping in phangorn: library(phangorn) alnx2pml - pml(rtrx, as.phyDat(alnx2)) alnx2pmloptim - optim.pml(alnx2pml, TRUE) # some tree rearrangements, otherwise you may get some zeros alnx2bs - bootstrap.pml(alnx2pmloptim, optNni=TRUE) plotBS(alnx2pmloptim$tree, alnx2bs) 3) Then, where to find likelihood values after a mrbayes run ? library(phyloch) mrbayes(alnx2, path = getwd(),ngen = 100, file = test.con, run = FALSE) # I obtain the file I can use then in mrbayes 4) Eventually, for parsimony, what do the parsimony score represent ? Is it a way to weight it ? I suppose the answer is no, and parsimony scores are only there to compare them, not to deduce what is a good or bad score… The parsimony score is the minimal number of substitutions needed to account for the data on a phylogeny. If you weigh a tree with the parsimony score the edge length represent the minimal number of substitutions needed. alnx2pars - parsimony(rtrx, as.phyDat(alnx2)) alnx2parsoptim - optim.parsimony(rtrx, as.phyDat(alnx2)) plot(alnx2parsoptim) pratchet is likely to find better tree (not for this small tree here) alnx2pars - parsimony(rtrx, as.phyDat(alnx2)) alnx2parsoptim - pratchet(as.phyDat(alnx2), start=rtrx) alnx2parsoptim - acctran(alnx2parsoptim, as.phyDat(alnx2)) # assign edge length via ACCTRAN criterion, # the assignment for the edge length is in general not unique!!! tree - midpoint(alnx2parsoptim) # midpoint rooting for a nicer look plot(tree) edgelabels(round(tree$edge.length, 3), adj = c(.5, 1), frame=none) add.scale.bar() Thanks a lot in advance for your answer. All the best, Gwennaël Bataille ___ Salmo
[R-sig-phylo] Hypothesis testing with phylosor
I have a doubt with using the picante::phylosor.rnd for testing hypothesis about the phylogenetic dissimilarities between sites. This function gives the randomized matrices obtained with the null model chosen. But how can I do to explicitly test for a significant difference between the observed phylosor value and the randomized value? Thank you in advance and I'm sorry if this question is too simple. Diogo -- Atenciosamente, *Diogo Borges Provete* == Biólogo Mestre em Biologia Animal (UNESP) Doutorando PPG Ecologia e Evolução Laboratório de Ecologia de Insetos (sl. 222) Departamento de Ecologia Instituto de Ciências Biológicas - ICB 1 Universidade Federal de Goiás, campus II - UFG Goiânia-GO CP: 131 74001-970 Brazil Tel. Lab. +55 62 3521-1732 *Cel. +55 *62 8231-5775 * *: diogoprovete **: diogop...@yahoo.com.br *Personal web page https://sites.google.com/site/diogoprovetepage/* Traduza conosco: http://www.journalexperts.com/br/ Perfil no ProZ http://www.proz.com/profile/1335025http://www.proz.com/profile/1335025 == [[alternative HTML version deleted]] ___ R-sig-phylo mailing list R-sig-phylo@r-project.org https://stat.ethz.ch/mailman/listinfo/r-sig-phylo
Re: [R-sig-phylo] convergence issues with hansen model
Thanks for the response, Liam. I just tried out OUwie and it works. However, it appears to only fit 1 variable at a time (I only get one sigma squared value). When running some tests with OUCH, I found that sigma squared is different when one variable is fit to an OU model, versus when multiple variables are fit together. Is that expected? -Pascal On Mon, Mar 12, 2012 at 11:39 AM, Liam J. Revell liam.rev...@umb.eduwrote: You might want to try the OUWie package by Beaulieu O'Meara ( http://cran.r-project.org/**web/packages/OUwie/index.htmlhttp://cran.r-project.org/web/packages/OUwie/index.html )**. I have not tried it yet, but it promises to do multi-optimum OU model fitting as well. All the best, Liam -- Liam J. Revell University of Massachusetts Boston web: http://faculty.umb.edu/liam.**revell/http://faculty.umb.edu/liam.revell/ email: liam.rev...@umb.edu blog: http://phytools.blogspot.com On 3/12/2012 2:31 PM, Pascal Title wrote: Hi all I have a dataset of 5 PC axes for a phylogeny with 52 tips and I would like to get the variance-covariance matrix under a global OU model of evolution. I find that OU is strongly favored over BM, based on fitContinuous in GEIGER. However, I am having issues with convergence when trying to fit a hansen model to my data. What can I do to get around this problem? Alternatively, is there another way to get at the multivariate VCV matrix other than with the OUCH package? The error is: *unsuccessful convergence, code 1, see documentation for `optim'* *Warning message:* *In hansen(tree = ot, data = otd[varnames], regimes = otd[regimes], :* * unsuccessful convergence* I have posted a small file that contains the following R script along with the data herehttp://dl.dropbox.com/u/**34644229/OUhansen.ziphttp://dl.dropbox.com/u/34644229/OUhansen.zip . Any advice would be greatly appreciated! Thanks! require(ouch) require(ape) tree-read.nexus('tree.nex') data-read.csv('data.csv') rownames(data)-data$X data$X-NULL tree head(data) colnames(data)-varnames #for hansen() ot-ape2ouch(tree) otd-as(ot,data.frame) data$labels-rownames(data) otd-merge(otd,data,by=**labels,all=TRUE) rownames(otd)-otd$nodes ot-with(otd,ouchtree(nodes=**nodes,ancestors=ancestors,** times=times,labels=labels)) otd$regimes-as.factor(**global) h1-hansen(tree=ot,data=otd[**varnames],regimes=otd[** regimes],sqrt.alpha=c(1,0,0,**0,0,1,0,0,0,1,0,0,1,0,1),** sigma=c(1,0,0,0,0,1,0,0,0,1,0,**0,1,0,1)) -- Pascal Title Graduate Student Burns Lab http://kevinburnslab.com/ Department of Evolutionary Biology San Diego State University 5500 Campanile Drive San Diego, CA 92182-4614 [[alternative HTML version deleted]] ___ R-sig-phylo mailing list R-sig-phylo@r-project.org https://stat.ethz.ch/mailman/listinfo/r-sig-phylo
Re: [R-sig-phylo] convergence issues with hansen model
Just wanted to note that there's a fundamental difference between the way OUCH is handling the multivariate traits and the way geiger and similar packages are handling it. If you're giving geiger a data frame with multiple traits, it is fitting each independently, just saving you the trouble from passing them in one at a time. OUCH is actually fitting the multivariate trait model, which is the reason that you get different results fitting a single trait or fitting multiple traits simultaneously. In the OUCH model, dX = alpha ( theta - X) dt + sigma dB_t, X is a vector, alpha is a matrix, theta is a vector, sigma is a matrix, and dB_t is a vector of Brownian walks. Only if the off-diagonal terms of alpha and sigma matrices are zero will the results be the same. hope that helps, -Carl On Mon, Mar 12, 2012 at 4:56 PM, Pascal Title pascalti...@gmail.com wrote: Thanks for the response, Liam. I just tried out OUwie and it works. However, it appears to only fit 1 variable at a time (I only get one sigma squared value). When running some tests with OUCH, I found that sigma squared is different when one variable is fit to an OU model, versus when multiple variables are fit together. Is that expected? -Pascal On Mon, Mar 12, 2012 at 11:39 AM, Liam J. Revell liam.rev...@umb.eduwrote: You might want to try the OUWie package by Beaulieu O'Meara ( http://cran.r-project.org/**web/packages/OUwie/index.htmlhttp://cran.r-project.org/web/packages/OUwie/index.html )**. I have not tried it yet, but it promises to do multi-optimum OU model fitting as well. All the best, Liam -- Liam J. Revell University of Massachusetts Boston web: http://faculty.umb.edu/liam.**revell/http://faculty.umb.edu/liam.revell/ email: liam.rev...@umb.edu blog: http://phytools.blogspot.com On 3/12/2012 2:31 PM, Pascal Title wrote: Hi all I have a dataset of 5 PC axes for a phylogeny with 52 tips and I would like to get the variance-covariance matrix under a global OU model of evolution. I find that OU is strongly favored over BM, based on fitContinuous in GEIGER. However, I am having issues with convergence when trying to fit a hansen model to my data. What can I do to get around this problem? Alternatively, is there another way to get at the multivariate VCV matrix other than with the OUCH package? The error is: *unsuccessful convergence, code 1, see documentation for `optim'* *Warning message:* *In hansen(tree = ot, data = otd[varnames], regimes = otd[regimes], :* * unsuccessful convergence* I have posted a small file that contains the following R script along with the data herehttp://dl.dropbox.com/u/**34644229/OUhansen.ziphttp://dl.dropbox.com/u/34644229/OUhansen.zip . Any advice would be greatly appreciated! Thanks! require(ouch) require(ape) tree-read.nexus('tree.nex') data-read.csv('data.csv') rownames(data)-data$X data$X-NULL tree head(data) colnames(data)-varnames #for hansen() ot-ape2ouch(tree) otd-as(ot,data.frame) data$labels-rownames(data) otd-merge(otd,data,by=**labels,all=TRUE) rownames(otd)-otd$nodes ot-with(otd,ouchtree(nodes=**nodes,ancestors=ancestors,** times=times,labels=labels)) otd$regimes-as.factor(**global) h1-hansen(tree=ot,data=otd[**varnames],regimes=otd[** regimes],sqrt.alpha=c(1,0,0,**0,0,1,0,0,0,1,0,0,1,0,1),** sigma=c(1,0,0,0,0,1,0,0,0,1,0,**0,1,0,1)) -- Pascal Title Graduate Student Burns Lab http://kevinburnslab.com/ Department of Evolutionary Biology San Diego State University 5500 Campanile Drive San Diego, CA 92182-4614 [[alternative HTML version deleted]] ___ R-sig-phylo mailing list R-sig-phylo@r-project.org https://stat.ethz.ch/mailman/listinfo/r-sig-phylo -- Carl Boettiger UC Davis http://www.carlboettiger.info/ ___ R-sig-phylo mailing list R-sig-phylo@r-project.org https://stat.ethz.ch/mailman/listinfo/r-sig-phylo
Re: [R-sig-phylo] convergence issues with hansen model
That helps alot, Carl, thank you. So to bring this back to my original question, it sounds like the only way to get sigma squared values from a multivariate OU model is with OUCH. I'm currently not able to get results because of convergence issues. Does that mean that I simply won't be able to get such data? Is this the end of the line? Or are there parameters that I can tweak to get convergence? I know you can increase the number of iterations, and you can choose different optimization methods, but I don't know enough about these methods to know whether or not it is appropriate to change these, or if this could somehow affect the output. I really appreciate the help! -Pascal On Mon, Mar 12, 2012 at 3:01 PM, Carl Boettiger cboet...@gmail.com wrote: Just wanted to note that there's a fundamental difference between the way OUCH is handling the multivariate traits and the way geiger and similar packages are handling it. If you're giving geiger a data frame with multiple traits, it is fitting each independently, just saving you the trouble from passing them in one at a time. OUCH is actually fitting the multivariate trait model, which is the reason that you get different results fitting a single trait or fitting multiple traits simultaneously. In the OUCH model, dX = alpha ( theta - X) dt + sigma dB_t, X is a vector, alpha is a matrix, theta is a vector, sigma is a matrix, and dB_t is a vector of Brownian walks. Only if the off-diagonal terms of alpha and sigma matrices are zero will the results be the same. hope that helps, -Carl On Mon, Mar 12, 2012 at 4:56 PM, Pascal Title pascalti...@gmail.com wrote: Thanks for the response, Liam. I just tried out OUwie and it works. However, it appears to only fit 1 variable at a time (I only get one sigma squared value). When running some tests with OUCH, I found that sigma squared is different when one variable is fit to an OU model, versus when multiple variables are fit together. Is that expected? -Pascal On Mon, Mar 12, 2012 at 11:39 AM, Liam J. Revell liam.rev...@umb.edu wrote: You might want to try the OUWie package by Beaulieu O'Meara ( http://cran.r-project.org/**web/packages/OUwie/index.html http://cran.r-project.org/web/packages/OUwie/index.html )**. I have not tried it yet, but it promises to do multi-optimum OU model fitting as well. All the best, Liam -- Liam J. Revell University of Massachusetts Boston web: http://faculty.umb.edu/liam.**revell/ http://faculty.umb.edu/liam.revell/ email: liam.rev...@umb.edu blog: http://phytools.blogspot.com On 3/12/2012 2:31 PM, Pascal Title wrote: Hi all I have a dataset of 5 PC axes for a phylogeny with 52 tips and I would like to get the variance-covariance matrix under a global OU model of evolution. I find that OU is strongly favored over BM, based on fitContinuous in GEIGER. However, I am having issues with convergence when trying to fit a hansen model to my data. What can I do to get around this problem? Alternatively, is there another way to get at the multivariate VCV matrix other than with the OUCH package? The error is: *unsuccessful convergence, code 1, see documentation for `optim'* *Warning message:* *In hansen(tree = ot, data = otd[varnames], regimes = otd[regimes], :* * unsuccessful convergence* I have posted a small file that contains the following R script along with the data herehttp://dl.dropbox.com/u/**34644229/OUhansen.zip http://dl.dropbox.com/u/34644229/OUhansen.zip . Any advice would be greatly appreciated! Thanks! require(ouch) require(ape) tree-read.nexus('tree.nex') data-read.csv('data.csv') rownames(data)-data$X data$X-NULL tree head(data) colnames(data)-varnames #for hansen() ot-ape2ouch(tree) otd-as(ot,data.frame) data$labels-rownames(data) otd-merge(otd,data,by=**labels,all=TRUE) rownames(otd)-otd$nodes ot-with(otd,ouchtree(nodes=**nodes,ancestors=ancestors,** times=times,labels=labels)) otd$regimes-as.factor(**global) h1-hansen(tree=ot,data=otd[**varnames],regimes=otd[** regimes],sqrt.alpha=c(1,0,0,**0,0,1,0,0,0,1,0,0,1,0,1),** sigma=c(1,0,0,0,0,1,0,0,0,1,0,**0,1,0,1)) -- Pascal Title Graduate Student Burns Lab http://kevinburnslab.com/ Department of Evolutionary Biology San Diego State University 5500 Campanile Drive San Diego, CA 92182-4614 [[alternative HTML version deleted]] ___ R-sig-phylo mailing list R-sig-phylo@r-project.org https://stat.ethz.ch/mailman/listinfo/r-sig-phylo -- Carl Boettiger UC Davis http://www.carlboettiger.info/ -- Pascal Title Graduate Student Burns Lab http://kevinburnslab.com/ Department of Evolutionary Biology San Diego State University 5500 Campanile Drive San Diego, CA 92182-4614 [[alternative HTML version deleted]]