Ringed Seal Range of Movement
During the Spring 2022 semester, myself and two other students conducted a research project for our Mammalogy course. We chose to do a spatial ecology project, since we all had dabbled in R, but wanted to gain more experience with it.
This project was really hard and took so much time, but I definitely learned more about R’s capabilities and the potential it has! It was a lot of trial and error, and I really appreciate Nicki Barbour (graduate student at UMD) for her support on this project!
We chose to look into the movements of the Ringed Seal, which has three distinct life stages that are very depended on Arctic sea ice. With a warming global climate, their survival behaviors are being threatened. We were interested in confirming whether or not Ringed Seals range of movement is related to the amount of sea ice present in their habitat.
My group and I found that the “Basking” season of Seal behavior has a significantly smaller range of movement than other seasons. The Basking period occurs during when there is a moderate (we defined it as “medium” with respect to the other seasons in our project) amount of sea ice cover in the Hudson Bay.
We used a data set from movebank.org, which tagged the movements of 66 ringed seals in the Hudson Bay from the years of 2006 to 2011 using ARGOS PTT trackers (Luque et al., 2014). We chose three “seasons” of three months each where Ringed Seals are known to display certain life history behavior traits (Kelly et al., 2010) and calculated average distance traveled by Ringed Seals in those seasons. These seasons were also correlated with sea ice cover — low, medium, high — and data was obtained from the National Snow & Ice Center for the months of interest in 2006-2011.
“Our ANOVA test revealed that there is a significant difference in total distance traveled by the ringed seals between the basking period and the subnivean/foraging period. However, rather than there be a trend in the range of movement, there seems to be a ‘normal’ range of movement that occurs during the Subnivean (High sea ice cover) and Foraging (Low sea ice cover) periods, but a significantly smaller range of movement during the Basking (Medium sea ice cover) period. Thus, our hypothesis that seal activity decreases as ice cover increases is not supported by our results.”
Boxplot displaying distances traveled by individuals during the three time periods of interest. Subnivean = March, April & May; Basking = June, July & August; Foraging = September, October & November.
Results from ANOVA comparison of means test for the three seasons. We see a significant difference between the Basking period and both the Subnivean & Foraging, but not between Subnivean & Foraging.
R Code: by Nicki Barbour & Emma Yockman
# load in packages library(move);library(ggplot2);library(bcpa);library(dplyr);library(sf) # load in data loginStored <- movebankLogin(username="[INSERT HERE]", password="[INSERT HERE]) searchMovebankStudies(x="Ringed seals Sanikiluaq", login=loginStored) RSS <- getMovebankData(study="Ringed seals Sanikiluaq", login=loginStored, removeDuplicatedTimestamps=TRUE ) # convert to dataframe format ## it's good policy to rename your objects when you make changes to them, so that older versions aren't lost RSS_df<-as.data.frame(RSS) # remove columns you don't need (select the ones you want, by using their column number) ## eg columns 4, 5, 6, 18 (lat, long, timestamp, trackID) RSS_df<-RSS_df[,c(4,5,6,18)] # use ggplot to look at track durations ggplot(RSS_df, aes(x = timestamp, y = trackId)) + geom_path()+theme_classic() ## looks like you have multiple years of data # use a "homemade" function to check what the sampling rate of the data is ## eg median timestep (median time gap between locations for each id) and track duration # we will call the function "dtime" and then apply it to our data dtime <- function(t, ...) {difftime(t[-1], t[-length(t)], ...) %>% as.numeric} data_summary <- RSS_df %>% group_by(trackId) %>% summarize(start = min(timestamp),end = max(timestamp), Median_timestep_hrs = median(dtime(timestamp, units = "days"))) %>% mutate(DataSpan=end-start) # look at the output View(data_summary) # minimum track duration seems to be around 30 days # let's use the bcpa package to determine the step length (straight line distance) between locations for each id # first we need to split up our new data by id New_ID<-split(RSS_df,RSS_df$trackId) # then we use a for-loop to find our new data for (i in c(1:length(New_ID))){ # make sf object (spatial), convert to utm coordinate ref system (units are meters not degrees now), then add coordinates to df myd.sf <- st_as_sf(New_ID[[i]], coords = c("location_long","location_lat"), crs = 4326) %>% st_transform(26918) New_ID[[i]]$X <- st_coordinates(myd.sf)[,1] New_ID[[i]]$Y <- st_coordinates(myd.sf)[,2] New_ID[[i]]$Time <- New_ID[[i]]$timestamp # get VT table from each track (bcpa package) # contains speeds, step lengths, and turning angle vt <- GetVT(New_ID[[i]], units = "hour") # extract step length (in meters) ## divide by 1000 to make km New_ID[[i]]$Step_Length_km <- c(NA, NA, vt$S)/1000 # bind NA's to beginning to deal with subset from VT function # subset data to remove first couple obs (have Na's for step length, etc) New_ID[[i]] <- New_ID[[i]][3:nrow(New_ID[[i]]),] } # we can bind all our ids together again RSS_df2<-do.call("rbind",New_ID) # summarize total distance traveled (all step lengths) by id and month ## create month variable RSS_df2$Month<-as.factor(as.numeric(format(RSS_df2$timestamp,"%m"))) # label by season: ## lets pretend you want to labels as summer, fall, winter, spring, summer: ## you can change these to match the months/seasons you want! RSS_df2$Season<-NA ## Subnivean: mar apr may ( 3 4 5 ) RSS_df2[which(RSS_df2$Month=="3"|RSS_df2$Month=="4"|RSS_df2$Month=="5"),]$Season<-"Subnivean" ## Basking: june july aug RSS_df2[which(RSS_df2$Month=="6"|RSS_df2$Month=="7"|RSS_df2$Month=="8"),]$Season<-"Basking" ## Foraging: sept oct nov RSS_df2[which(RSS_df2$Month=="9"|RSS_df2$Month=="10"|RSS_df2$Month=="11"),]$Season<-"Foraging" # group by track and season, find total distance traveled (sum step length over time period) RSS_month_id<- RSS_df2 %>% group_by(trackId,Season) %>% summarize(Total_Distance_km=sum(Step_Length_km,na.rm=TRUE))%>% ungroup() %>% data.frame() # look at first 7 rows of new dataframe, grouped by total distance traveled by id and season RSS_month_id # plug into a model: does total difference traveled have a significant relationship with season? model<-lm(Total_Distance_km ~ Season, data= RSS_month_id) # print out model summary summary(model) # reference level is Basking #get rid of NA seasons RSS_month_id2 <- RSS_month_id %>% filter(is.na(Season)==FALSE) # can plot in boxplot using following code: ggplot(RSS_month_id2,aes(x=Season,y=Total_Distance_km,fill=Season))+geom_boxplot()+ylab("Total Distance Traveled (km)")+theme_classic() ## boxplot shows RSS_month_id$Season<-as.factor(RSS_month_id$Season) # change reference level of model to summer: RSS_month_id$Season <- relevel(RSS_month_id$Season,"Subnivean") # refit model model<-lm(Total_Distance_km ~ Season, data= RSS_month_id) # print out model summary summary(model) ## shows that fall and spring have significantly higher distances traveled than summer # ANOVA for difference in persistence between categorical groups (such as Season) # one-way ANOVA: tests for difference in means between groups anova1<-aov(formula = Total_Distance_km ~ Season, data = RSS_month_id2) summary(anova1) # my results: from ANOVA, there is a significant difference in the means for at least one of the groups # we can use a post hoc test, TukeyHSD, to see which groups differ from each other TukeyHSD(anova1) # note: we are using a p-value threshold of 0.05 to determine significance # the Tukeypost-hoc test shows that there are significant differences in peristence between: ## Spr - Fall ## Summer - Spr ## Winter - Summer # we can use a boxplot to visualize these differences! ggplot(New_Daily_Data_sf,aes(Season,Abs_Persistence,fill=Season))+geom_boxplot() # low move persistence in spring vs fall # higher persistence in summer vs spring # low move persistence in winter vs summer ## no difference between winter and fall
Cover photo via CBS News.