Best way to calculate MNA (minimum number alive) estimates?

Thanks for the membership to the forum!

I’m starting to get a lot of capture-recapture data on red foxes with monthly sampling, which I want to use to calculate abundance with MNA (minimum number alive) estimates. Some time in the future I will also use more advanced stuff like recapture packages, Rmark, mark JollySeber, but for now I just want to get started and make it easy. I started doing this manually in Excel, but, I would like to do it more properly/reproducable, so here’s my question: Instead of doing this manually, could I make function for this job? Maybe using dplyr would be appropriate, not sure. Or is there a package that I haven’t found that could work?

(MNA is defined as = actual number of individuals caught at time (t) + those present, not caught at time (t), but caught subsequently (Krebs, 1966))

1 Like

Welcome @oxyria

Could you post a sample of your data? Seems like a pretty straight-forward dplyr job but it’s hard to say without seeing the data.

1 Like

Thanks for your reply!

I have more variables, but the ones that I would need here is only the individual animal’s id and the trapping session (I have several dates for each session, but I will find a way to group these into sessions). And as in the example, I don’t have NA/zero data, is that a problem? Hope this makes sense anyway! And, thank you!

ID, date
individual_id1, june
individual_id2, june
individual_id2, june
individual_id3, june
individual_id1, july
individual_id1, september
individual_id3, september


Alright so I’ve given this my best shot based on your comment. I couldn’t quite figure out how to do it with dplyr alone but the base-R solution isn’t super complicated.

The process is

  1. Build data (note that I converted your date column to year-month-day format to make subsetting possible)

  2. Use lapply to iterate through unique dates
    a. Grab current date
    b. Grab all individuals caught at current date
    c. Grab individuals caught before/after
    d. Subset ^^ to include only individuals caught both before AND after
    e. Subset ^^ to remove individuals caught on current date

  3. Construct a data frame to hold unique dates from our original data and their corresponding MNA value

# Build some data
fox_data <- data.frame(
  ID = c(
    "fox1", "fox2", "fox2",
    "fox3", "fox1", "fox1",
  Date = as.Date(c(
    "2018-06-01", "2018-06-01", "2018-06-01",
    "2018-06-01", "2018-07-01", "2018-09-01",
  stringsAsFactors = FALSE

mna_data <- lapply(unique(fox_data$Date), function(x){
  # Grab current date
  current_date <- x
  # Grab all indviduals caught at this date
  caught_at_date <- unique(fox_data$ID[fox_data$Date == current_date])
  # Grab all individuals caught after
  caught_aft <- unique(fox_data$ID[fox_data$Date > current_date])
  # Grab all individuals caught before
  caught_bf <- unique(fox_data$ID[fox_data$Date < current_date])
  # Subset for individuals caught before who were also caught after
  caught_bf_and_aft <- caught_bf[which(caught_bf %in% caught_aft)]
  # Remove individuals caught on current day
  caught_bf_and_aft <- setdiff(caught_bf_and_aft, caught_at_date)
  # Calculate MNA
  mna <- length(caught_at_date) + length(caught_bf_and_aft)


results <- data.frame(Dates = unique(fox_data$Date),
                      MNA = unlist(mna_data))


       Dates MNA
1 2018-06-01   3
2 2018-07-01   2
3 2018-09-01   2

Hopefully I’ve understood what you’re trying to do correctly. Maybe someone else will jump in and suggest a dplyr method for doing this.


Thank you so much for taking the time! And you’re very pedagogic too.

I struggled a bit to get my dates to act as dates (they were date+time+some weird stuff), but then afterwards I could follow your logic and script.

However, I simplified my question a bit, so I actually have several clumped dates that should count as one. I thought first I could call it by the month, but then some of the data is just between two months… luckily its always 3 dates next to eachother every time, I think that will make it easier. Maybe I can group them before launching your script. I’ll try that tomorrow!

Thanks again, it was really helpful!

No it stopped again… Didn’t find a way to combine these dates. Is there any way to make R combine "all dates closer to eachother than 5 for example? I’ve looked at aggregate, not sure that’s the way to go, seems I need to do it manually for every grouping which of course is possible, but I was hoping for a more automated way…

@oxyria Post an example of what you’re talking about and I may be able to help.

Just FYI: the R community loves reproducible examples so, wherever possible, you should try to post some example data and your best attempt at solving the problem. Makes it easier for folks trying to assist.