Following the approval of our proposal by the Swiss Vogelwarte to study the migration patterns of two Afro-tropical migrants: the Red-capped Robin-Chat (RCRC) and Mangrove Kingfisher (MK) with geolocators, we must now work out when to equip these birds and determine which sex and age to equip.

That’s where A Rocha Kenya’s fabulous database of 20+ years of ringing comes in handy! It should provide some clues to answer these questions.

The preliminary step for this study is shown for reproducibility purposes only, to convert the Microsoft Access database to a more convenient format in R.

# Create the connection
mdbConnect<-odbcConnectAccess2007('C:/Users/rnussba1/Desktop/Ringing/Ringing/Data/0_ARK Ringing DB_2019-09-01.accdb')

# Visualize the table content
sqlTables(mdbConnect)

# Import Tables
SPE <- sqlFetch(mdbConnect, "Species2")
SES <- sqlFetch(mdbConnect, "Sessions")
LOC <- sqlFetch(mdbConnect, "Localities")
CAP <- sqlFetch(mdbConnect, "Captures")

# Combine datasets
d <- CAP %>%
  left_join(SES, by = 'SessionID') %>%
  left_join(LOC, by = 'LocalityID') %>%
  left_join(SPE, by = c('SpeciesID' = 'Species#')) %>%
  mutate(Julian = as.numeric(format(Date,'%j')), Year = as.numeric(format(Date,'%Y')), Month = as.numeric(format(Date,'%m')))

write.csv(d, './ringing_data.csv')
d <- read.csv('./ringing_data.csv')
dm <- d %>% filter(Location=='Mwamba Plot 28, Watamu')

When did we ring at Mwamba?

Let’s explore the content of the ringing database.

The basic unit of the database is a capture - see an extract of the database below. As you can see, there is a lot of information associated with each record, such as ring number, measurements, date, location etc.

Excerpt of the ringing data table
X CaptureID SpeciesID SessionID CaptureType RingNo Age SuspAge Sex Wing Head Tarsus Tarsus.method Weight ppWear ssWear TertWear TailWear BpCp Time Initials NetNo Notes ColourRing Mark Condition WingChecked TarsusChecked HeadChecked LocalityID Date NettingSite Weather Nets6m Nets9m Nets12m Nets18m NetsOther NetsOpen NetsClosed SessionNotes RingingScheme Ringer.. Location Coords Latitude Longitude Habitat Altitude Country X2010. SAFRING. CommonName ScientificName Julian Year Month
1 30 729 6 1 A24878 0 NA 0 95 38.8 25.3 1 35.2 0 0 0 0 0 1899-12-30 07:55:00 OM NA NA NA 0 0 0 0 0 17 2018-08-03 NA NA 0 0 0 0 NA 1899-12-30 07:15:00 NA OM = Ogeto Mwebi 1 1489 Mwamba Plot 28, Watamu 0322S 3959E NA NA NA 0 Kenya 727 3036 Common Bulbul Pycnonotus barbatus 215 2018 8
2 31 729 6 1 A24879 0 NA 0 102 39.4 27.5 1 41.0 3 6 0 0 0 1899-12-30 07:55:00 OM NA NA NA 0 0 0 0 0 17 2018-08-03 NA NA 0 0 0 0 NA 1899-12-30 07:15:00 NA OM = Ogeto Mwebi 1 1489 Mwamba Plot 28, Watamu 0322S 3959E NA NA NA 0 Kenya 727 3036 Common Bulbul Pycnonotus barbatus 215 2018 8
3 33 728 6 1 A24881 0 NA 2 105 42.6 27.6 1 44.5 3 3 0 0 1 1899-12-30 08:30:00 OM NA NA NA 0 0 0 0 0 17 2018-08-03 NA NA 0 0 0 0 NA 1899-12-30 07:15:00 NA OM = Ogeto Mwebi 1 1489 Mwamba Plot 28, Watamu 0322S 3959E NA NA NA 0 Kenya 741 1194 Yellow-throated Leaflove Chlorocichla flavicollis 215 2018 8
4 34 893 6 1 J89235 3 NA 0 54 30.6 23.7 1 14.5 3 3 0 0 0 1899-12-30 08:30:00 OM NA NA NA 0 0 0 0 0 17 2018-08-03 NA NA 0 0 0 0 NA 1899-12-30 07:15:00 NA OM = Ogeto Mwebi 1 1489 Mwamba Plot 28, Watamu 0322S 3959E NA NA NA 0 Kenya 675 643 Singing Cisticola Cisticola cantans 215 2018 8
5 35 729 6 1 A24882 0 NA 0 99 39.0 25.4 1 39.0 4 4 0 0 0 1899-12-30 08:30:00 OM NA NA NA 0 0 0 0 0 17 2018-08-03 NA NA 0 0 0 0 NA 1899-12-30 07:15:00 NA OM = Ogeto Mwebi 1 1489 Mwamba Plot 28, Watamu 0322S 3959E NA NA NA 0 Kenya 727 3036 Common Bulbul Pycnonotus barbatus 215 2018 8
6 36 729 6 1 A24883 0 NA 0 91 37.7 25.4 1 34.5 3 0 0 0 0 1899-12-30 08:30:00 OM NA NA NA 0 0 0 0 0 17 2018-08-03 NA NA 0 0 0 0 NA 1899-12-30 07:15:00 NA OM = Ogeto Mwebi 1 1489 Mwamba Plot 28, Watamu 0322S 3959E NA NA NA 0 Kenya 727 3036 Common Bulbul Pycnonotus barbatus 215 2018 8

For this project, we are interested in finding out when the ringing sessions occurred at Mwamba. In particular, we want to see if there are any biases in the distribution of ringing sessions throughout the year or over the years.

dt <- dm %>%    
  group_by(SessionID) %>% 
  summarise(Month=first(Month), Year = first(Year)) %>% 
  group_by(Month, Year) %>%
  summarise(nb = n())
Distribution of the ringing sessions according to year and month. Colorscale indicates the number of ringing session

Distribution of the ringing sessions according to year and month. Colorscale indicates the number of ringing session

The ringing sessions are relatively well-spread throughout the year, although with a higher intensity in Spring (Month=3-4). Over the years, there is a more heterogenous distribution: very good coverage between 2003 and 2007, variable from 2008 to 2012.

Mangrove Kingfisher

Mangrove Kingfisher 14 May 2020. Mwamba. @Raphaƫl Nussbaumer

Let’s focus on the Mangrove Kingfisher data.

specie_name = 'Mangrove Kingfisher'

At the session level, we can explore how many MK are captured per session along the year. To do so, we fit a GAM (Generalized Additive Model) to visualize the evolution throughout the year.

dm %>% 
  group_by(SessionID) %>% 
  summarize( 
    Date = as.Date(first(Date)), 
    Julian = median(Julian), 
    Year = median(Year), 
    Count = sum(CommonName==specie_name, na.rm = TRUE), 
    )%>% 
ggplot() + 
  geom_point( aes( x=Julian , y=Count ) ) + 
  geom_smooth(aes( x=Julian , y=Count ), method = "gam", formula = y ~ s(x), method.args = list(family = "poisson"), ) +
  ylim(0,3) +
  xlab('Day of Year') +
  scale_x_continuous(breaks=as.numeric(format(ISOdate(2004,1:12,1),"%j")),
                     labels=format(ISOdate(2004,1:12,1),"%B"),
                     limits = c(50,350)) 
Number of Mangrove Kingfishers captured per ringing session along the year. The dots indicates the count of MK for each ringing session and the blue line shows the GAM fitted on these data.

Number of Mangrove Kingfishers captured per ringing session along the year. The dots indicates the count of MK for each ringing session and the blue line shows the GAM fitted on these data.

Mangrove Kingfishers arrive in late April, their number peaks soon after in May and slowly decreases until December. At its peak, an average of 0.5 MK are captured by session. The best session caught 3 of them!

For our study, we want to equip 10 MK with geolocators, a small device which records light intensity during the day, allowing us to estimate the geographical coordinates of the bird. An important consideration for our study is that we must retrap the bird to retrieve the information stored in the geolocator.

As most of the birds trapped at Mwamba are passing birds, we won’t equip the birds ringed at the centre. Instead, to maximize recapture probability, we are planning to catch MK on its non-breeding terrritory.

Thus, the number of capture per session is of less importance here. Yet, the phenology curve given by this Figure indicates that most birds in May are still migrating. Therefore, it is best to equip birds from end of May up to August. To make sure that the birds are holding territory, we will visit the same place several times to ensure the bird remains there.

We can further analyse the retrap rate of MK. For each ring number RingNo (individual bird), we compute the number of retrap retrap_i, the duration since capture or last retrap duration_capture, whether the bird will be retrapped later in its life isRetrap, and whether its retrap will be in a subsequent season (or year).

dr <- dm %>% 
  filter(CommonName==specie_name ) %>% 
  arrange(Date) %>% 
  group_by(RingNo) %>% 
  mutate(n = 1, 
         retrap_i = cumsum(n)-1, 
         duration_capture = as.numeric(difftime(lead(Date),Date,units='days')),
         isRetrap = if_else(is.na(lead(retrap_i)>retrap_i),0, 1),
         nextSeason = isRetrap & (duration_capture+Julian)>490,
         Yearsince = Year-first(Year),
         isAdult = Age==4) %>% 
  select(RingNo, Date, Year, Julian, retrap_i, isRetrap, nextSeason, duration_capture, isAdult, Yearsince) %>% 
  arrange(RingNo)
Excerpt of the Mangrove Kingfisher ringing data
RingNo Date Year Julian retrap_i isRetrap nextSeason duration_capture isAdult Yearsince
BB10243 2015-05-08 2015 128 0 0 FALSE NA TRUE 0
BB10244 2015-05-08 2015 128 0 0 FALSE NA TRUE 0
bb10248 2015-07-09 2015 190 0 1 TRUE 1188 FALSE 0
bb10248 2018-10-09 2018 282 1 0 FALSE NA TRUE 3
BB10271 2018-10-11 2018 284 0 0 FALSE NA FALSE 0
BB110244 2015-05-08 2015 128 0 0 FALSE NA TRUE 0

The retrap rate is the probability that a bird captured will be retrapped later in its life. Over the 24 unique MK individual captured, we retrapped 8 of them (33.3333333%).

If we only consider birds which have been retraped a following season, the number of retraps decreases to 6 (25%).

Looking at the seasonal variation of the retrap rate confirms the impression that captures in May include a larger proportion of migrant birds, which won’t be retrapped. However, the number of birds retrapped is very small, and any conclusion should be taken with some precaution…

dr %>% 
  filter(retrap_i<1) %>% 
  ggplot(aes(x=Julian, y=isRetrap)) +
  geom_point() +
  xlab('Day of Year') +
  geom_smooth(method = "gam", formula = y ~ s(x), method.args = list(family = "binomial")) +
  scale_x_continuous(breaks=as.numeric(format(ISOdate(2004,1:12,1),"%j")),
                   labels=format(ISOdate(2004,1:12,1),"%B"),
                   limits = c(100,300))
Retrap rate of MK along the year. The dots indicates the time of the first capture of a MK, whether it is retrapped later in its life (`isRetrap=1`) or not (`isRetrap=0`). The blue line is a GAM fitted on this data showing the general trend of retrap probability. Note that we are not filtering for *next season only* .

Retrap rate of MK along the year. The dots indicates the time of the first capture of a MK, whether it is retrapped later in its life (isRetrap=1) or not (isRetrap=0). The blue line is a GAM fitted on this data showing the general trend of retrap probability. Note that we are not filtering for next season only .

Digging deeper into the database, we can use ringing data to tell the story of individual birds. Here, you can see when and how many times each captured bird has been retrapped.

dr %>% 
  filter(any(isRetrap==1)) %>% 
  ggplot( aes(x=Julian,y=RingNo)) +
  geom_point(aes(shape = isAdult, colour = Yearsince, size = Yearsince )) +
  scale_colour_gradientn(colours = brewer.pal(9, 'YlGnBu')) +
  xlab('Day of Year') +
  scale_x_continuous(breaks=as.numeric(format(ISOdate(2004,1:12,1),"%j")),
                     labels=format(ISOdate(2004,1:12,1),"%B"),
                     limits = c(100,350))
The retrap story of each birds.

The retrap story of each birds.

Our champion is definitively BB2050 which has been captured 14 times between the years 2002, 2007! This bird has cleary established a a winter residency in Mwamba.

Red-Capped Robin-Chat

Mangrove Kingfisher 30 April 2020. Mwamba. @Raphaƫl Nussbaumer

specie_name = 'Red-capped Robin Chat'

For the Red-capped Robin-Chat, we can also start by looking at the count captured along the year, but this time looking seperatly at juvenile and adult.

dm %>% 
  group_by(SessionID) %>% 
  summarize( 
    Date = as.Date(first(Date)), 
    Julian = median(Julian), 
    Year = median(Year), 
    Count = sum(CommonName==specie_name, na.rm = TRUE), 
    CountAd = sum(CommonName==specie_name & Age != 0 & Age==4, na.rm = TRUE),
    CountJuv = sum(CommonName==specie_name & Age != 0 & Age!=4, na.rm = TRUE)
    )%>% 
ggplot() + 
  geom_point( aes( x=Julian , y=Count ) ) + 
  geom_smooth(aes( x=Julian , y=Count ), method = "gam", formula = y ~ s(x), method.args = list(family = "poisson"), colour="black") + 
  geom_smooth(aes( x=Julian , y=CountAd ), method = "gam", formula = y ~ s(x), method.args = list(family = "poisson"), colour="red") +
  geom_smooth(aes( x=Julian , y=CountJuv ), method = "gam", formula = y ~ s(x), method.args = list(family = "poisson"), colour="green") +
  ylim(0,3) +
  xlab('Day of Year') +
  scale_x_continuous(breaks=as.numeric(format(ISOdate(2004,1:12,1),"%j")),
                     labels=format(ISOdate(2004,1:12,1),"%B"),
                     limits = c(100,365)) +
  ggtitle("All (black), Adult (red) and Juvenile (green)") 

The ringing data indicates that two passage in June and mid-October for adult while juvenile number have only a shallow peak in August. Are the adult moving faster to choose the best location? Are they moving further north then juvenile? These are the sort of questions that we wish to answer with our study with geolocators.

# Caputure per year
dm %>% 
  group_by(SessionID) %>%
  summarize( 
    Date = as.Date(first(Date)), 
    Julian = median(Julian), 
    Year = median(Year), 
    Count = sum(CommonName==specie_name, na.rm = TRUE), 
    )%>% 
  group_by(Year) %>% 
  summarize( avgCount = mean(Count)) %>% 
  ggplot() + 
  geom_point(aes( x=Year , y=avgCount )) + 
  geom_smooth(aes( x=Year , y=avgCount ), method = "glm", formula = y ~ x, method.args = list(family = "poisson")) + ylab('Average count / year / session')

A surprinsing figure is this trend of descreasing number of RCRC capture per session along the years. More analysis needs to be performed to identify the origin of it (duration of survey, suitable habitat change in Mwamba, number of nets used etc… )

dr <- dm %>% 
  filter(CommonName==specie_name ) %>% 
  arrange(Date) %>% 
  group_by(RingNo) %>% 
  mutate(n = 1, 
         retrap_i = cumsum(n)-1, 
         duration_capture = as.numeric(difftime(lead(Date),Date,units='days')),
         isRetrap = if_else(is.na(lead(retrap_i)>retrap_i),0, 1),
         nextSeason = isRetrap & (duration_capture+Julian)>490,
         Yearsince = Year-first(Year),
         isAdult = Age==4) %>% 
  select(RingNo, Date, Year, Julian, retrap_i, isRetrap, nextSeason, duration_capture, isAdult, Yearsince) %>% 
  arrange(RingNo)

Similarly to the MK, we can study the retrap rate. Over the 163 unique RCRC individu captured, we retrapped 67 of them (41.1042945%). Considering birds which have been retraped a following season, the number of retraps decreases to 39 (23.9263804%).

dr %>% 
  filter(retrap_i<1) %>% 
  filter(!nextSeason) %>% 
  ggplot(aes(x=Julian, y=isRetrap)) +
  geom_point() +
  geom_smooth(method = "gam", formula = y ~ s(x), method.args = list(family = "binomial")) +
  geom_smooth(aes( x=Julian , y=isRetrap, col=isAdult ), method = "gam", formula = y ~ s(x), method.args = list(family = "binomial")) +
  xlab('Day of Year') +
  scale_x_continuous(breaks=as.numeric(format(ISOdate(2004,1:12,1),"%j")),
                   labels=format(ISOdate(2004,1:12,1),"%B"),
                   limits = c(100,350))

The temporal pattern of retrap shows a higher retrap rate for bird capture between July and August. This correspond probably to resident bird. Note that the uncertainty is larger during this period compared to May-July where more bird were captured (cf above figure) thus providing a better estimate of the retraping rate during these month. The artificial increase of the uncertainty from October is an artifact of the GAM which can be ignored.

For the purpose of our study, we want to equip 15 RCRC. While waiting for July August seems preferable to increase the retrap rate, the number of capture bird do decrease and might corespond to the same bird (resident). In addition, in order to learn more about the age difference pattern observed in the ringing data, we think that is best to start equipping some bird already in end of June and wait for mid-July to equip the others.

## Figure 3: Capture recapture
dr %>% 
  filter(any(isRetrap==1)) %>% 
  ggplot( aes(x=Julian,y=RingNo)) +
  scale_colour_gradientn(colours = brewer.pal(9, 'YlGnBu')) +
  geom_point(aes(shape = isAdult, colour = Yearsince, size = Yearsince )) +
  scale_x_continuous(breaks=as.numeric(format(ISOdate(2004,1:12,1),"%j")),
                     labels=format(ISOdate(2004,1:12,1),"%B"),
                     limits = c(100,350)) +
  xlab('Day of Year')

The life history of each RCRC is more complicated to interpretaed in this figure because there are many. Some birds are capture several over a single year (only small dots), while other have been capture over 5-10 years (large icon)!

Want to know more?

We set up a shiny interface to explore the ringing database for all locations and all species!

Update on the project will be posted on ResearchGate for the scientific part and on the Facebook page of A Rocha for the field work.