This is a test version of Biostars. For the public version, visit https://www.biostars.org.
R-package coala: how to create a stepping stone migration model

I am using the coala R-package to do coalescent simulations, and I was wondering if someone knows how to easily implement a stepping-stone migration model?

A reproducible example: 4 linearly distributed populations exchange migrants according to stepping-stone pattern (only the adjacent populations).

model <- coal_model(sample_size = c(5, 5, 5, 5), # sample 5 ind from every pop
                                   loci_number = 1,
                                   loci_length = 10,
                                    ploidy = 1) +
feat_mutation(rate = mut_rate, # e.g. 0.1
                       model = "HKY",
                       base_frequencies = c(0.25,0.25,0.25,0.25),
                       tstv_ratio = 4) +
feat_migration(mig_rate, 1, 2) + # mig_rate can be e.g. 0.5
feat_migration(mig_rate, 2, 1) +
feat_migration(mig_rate, 2, 3) +
feat_migration(mig_rate, 3, 2) +
feat_migration(mig_rate, 3, 4) +
feat_migration(mig_rate, 4, 3) +
sumstat_dna(name = "dna", transformation = identity)

This example works, but the downside is that I have to write two new lines for every pair of populations that exchange individuals. It is fine for a small number of populations, but I want to do a large simulation with about 70 populations. Does someone has a good idea how to automate this? The documentation has not helped me so far.

I tried two things that didn't work:

feat_migration(mig_rate, c(1,2,2,3,3,4), c(2,1,3,2,4,3))

and something like this:

migration_model <- function(){
  for(i in 1:n_pops){
    feat_migration(mig_rate, i, i+1) +
    feat_migration(mig_rate, i+1, i))
}

In the latter case, I don't really know how I can correctly create and parse all functions correctly into my model.

Good ideas are very welcome! :)

r coala coalescent simulation

You can look into do.call as a means to build a function call. Lexical scoping works very well in R so you shouldn't have a problem generating a function call as plain text and then executing it as an actual function call.

Thank you for your suggestion! I've never used this function before, and I tried to implement it as follows:

model <- coal_model(<params>) +
               feat_mutation(<params>) +
               do.call(feat_migration, list(mig_rate, 
                           pop_from = c(1,2,2,3,3,4), 
                           pop_to = c(2,1,3,2,4,3))) +
               sumstat_dna(<params>)

However, I get an error from the package "Error: population not identical to "all" or length(population) not equal to expected_length" (no such error with the original code). Am I implementing the do.call function right? Should I do something about quoting the arguments or the environment maybe?

Play around with it. You might need to use apply to ensure only one of each of the pop_from and pop_to lists are passed per feat_mutation call.

1 answer

Instead of using do.call() I used Map() and Reduce() as proposed by user Parfait on Stackoverflow.

n_pops <- 4    
start_pts <- as.vector(sapply(seq(n_pops-1), function(x) c(x, x+1)))  
end_pts <- as.vector(sapply(seq(n_pops-1), function(x) c(x+1, x)))

# LIST OF feat_migration()
feats <- Map(function(x, y) feat_migration(mig_rate, x, y), start_pts, end_pts)

# LIST OF FUNCTIONS
funcs <- c(list(coal_model(sample_size = c(5, 5, 5, 5),
                           loci_number = 1,
                           loci_length = 10,
                           ploidy = 1),
                feat_mutation(rate = mut_rate, # e.g. 0.1
                              model = "HKY",
                              base_frequencies = c(0.25,0.25,0.25,0.25),
                              tstv_ratio = 4),
                sumstat_dna(name = "dna", transformation = identity)),

            feats)
           )

# MODEL CALL     
model <- Reduce(`+`, funcs)

You really should have mentioned the cross-post to SO. I was helping you out on a pure R question as I thought you might find SO challenging to work with, which does not seem to be the case. Cross-posting runs the risk of annoying people in the community for good reason.

I am very sorry, I didn't know this was an issue. I haven't been using Biostars for very long. I figured some people in this community might have experience with this specific package as it is very specific to genetics, and perhaps ran into the same issue. When someone want to use a more complex migration model with the coala package in the future, they can now also find a fix in this community. How would you advise I go about this in the future?

Log in to answer this question.