A picture of a NutNet site. I’ve no idea what site, or who took it, but it was part of the front page of the NutNet website where it was also unattributed, so I’m assuming no one minds me displaying it here too!
trait.space is based around a simple assumption: given a co-existence matrix of species (0–> species coexist always, 1–> species don’t co-exist at all) we should be able to plot all those species in 2-D space (i.e., on a piece of paper) and their distance be proportional to their coexistence. It’s perhaps not the most complicated model in the world, and it makes absolutely no attempt to link to mechanism in any way.
It does have the advantage that you can make predictions for whether species you haven’t observed together (perhaps they’re in different continents) could potentially co-exist if given the chance. Since all species are put somewhere in the 2-D space, and species are only parameterised on the basis of species that overlap (via the ‘mask’ argument), if the space in some way reflects reality then position in it should have predictive power.
I worked on all this at a recent NutNet meeting. I was quite shocked at how nice everyone in the room was: they let a horrible data parasite like me just tag along for the ride, and I’m very grateful for it. So, if you’re a member of NutNet, thank you, and here’s that code I was working on during the meeting. I’m putting this up here in the spirit of how nice and friendly those guys were; a few people have expressed surprise that I put all these things that I work on here online before publishing them. Like it has for the people at NutNet, I’m hoping that being nice pays off in the long-run.
Example meta-community phylogeny. Circles are proportional to the number of individuals at the end of the run. Look! The species that died out isn’t anywhere at the end! I used rainbow to make this look slightly more appealing; I admit it’s not the prettiest figure in history.
Following on from the last post, I wrote a quick function that (sort of) simulates individuals of species moving through a meta-community (sim.meta.comm), and then added something on top that simulates the evolution of those species (including generating a phylogeny; sim.meta.phy.comm). I also neatened up the creation of a phylogeny from what I’ve been calling an ‘edge matrix’ in my code (edge2phylo). The meta-community has different environmental conditions throughout it, and individuals can migrate at each time-step. There’s no competition in the model yet.
I expected this to be a nightmare, but as long as you use the steps that monitor the ecology of the species as a check for whether you need to do anything with the phylogeny, it actually turns out that simulating the phylogeny is easier when you’ve got ecological information than when you’re just doing the phylogeny alone. In this version, I don’t have any effect of species traits – that’s for next time.
The main conceptual point I took from this is the difficulty in deciding how to model stochasticity. It’s hard to get the environmental parameters on the same scale as the stochasticity and species abundance parameters, and as such I ended up doing everything with Poisson distributions which seemed rather strange to me. It’s quite worrying how easy it was to make environments where species all headed to extinction, apart from in very, very small patches of the environment before I got my head around it all.
Next time – competition and trait evolution within the same model! Then, and only then, will I move on to actually trying to estimate parameters of interest from all this…
A while ago I was lucky enough to spend a few months in the Exelixis lab in Heidelberg, with rather grand hopes of modelling turnover in species composition as if they were nucleotides in a DNA molecule. C++ (sorry, not R, I know…) code implementing this method is up online here (to build you will need the Boost library, and ‘make install’ should build it all for you).
You can read a more detailed description of the method here (I’m about to put it on arXiv), but the general principle is that, at each time-step, an individual can reproduce, be replaced by another individual of another species, or die and not be replaced. New individuals can join a community, allowing the overall abundance to grow. The first two of these events (reproduction and replacement) are analogous to models of DNA substitution in phylogenetics; in phylogenetics such models help us figure out what has happened in the past based on extant DNA.
In this method we need this model to estimate the historical event that took place in a community; there is a circularity because you need the model to estimate the events, and the events to estimate the model (we never see when an individual replaces another individual, right?). While the method doesn’t work so well on simulated data (albeit data I’ve simulated to show the method’s failings), there is some hope that the program detects signal in real, biological data. I’ve decided to put this up online because I don’t really have time to do anything more with this, but if you’re interested here are a few things I’d like to try:
- Re-write the whole thing and use MCMC; I did some experiments with Filzbach a while ago and it looks like integrating out the uncertainty in figuring out the events, as well as having a search procedure that’s less-likely to get caught in local optima, works wonders.
- Stop treating the individuals in this model as real individuals, and instead view them as positions in niche space that are being fought for among species. This niche space battle can then be a ‘hidden model’ that generates observed abundances.
- Apply this to some real data in simpler systems. I’m convinced that species like butterflies, where (generally) there’s an alternation of generations with little overlap, have a lot of fluctuations that are modelled quite nicely by something like this where abundances are essentially a random draw from a slightly biased bag.
Let me know what you think! If you’re interested in doing something with this… let me know!