├── .gitattributes ├── .gitignore ├── Day1 ├── HMM_Tutorial_Day1.pptx ├── Tutorial_HMM_2022_Day1.Rmd ├── Tutorial_HMM_2022_Day1.html └── data │ ├── bathy.grd │ ├── bathy.gri │ └── seals.csv ├── Day2 ├── HMM_Tutorial_Day2.pptx ├── Tutorial_HMM_2022_Day2.Rmd ├── Tutorial_HMM_2022_Day2.html └── data │ ├── Eclipse_Sound_Map.jpg │ ├── dives.csv │ ├── land.dbf │ ├── land.prj │ ├── land.shp │ ├── land.shx │ └── tracks.csv ├── Day3 ├── HMMs_DFO_TutorialDay3.pdf ├── Tutorial_HMM_2022_Day3.Rmd ├── Tutorial_HMM_2022_Day3.html └── data │ ├── BlacktipB.txt │ └── tigershark_depthchange10min.csv ├── LectureSlides ├── HMMs_DFO_Day1 - Copy.pptx ├── HMMs_DFO_Day1.pptx ├── HMMs_DFO_Day2.pdf └── HMMs_DFO_Day3.pdf ├── README.md └── preWorkshopInfo ├── 0_Installing_packages.Rmd ├── 0_Installing_packages.html └── email.docx /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .Rproj.user 3 | .Rhistory 4 | .RData 5 | .Ruserdata 6 | *.Rproj 7 | 8 | .DS_Store 9 | 10 | **/figure-html/* 11 | **/html/* 12 | 13 | **/latex/* 14 | **/figure-latex/* 15 | 16 | -------------------------------------------------------------------------------- /Day1/HMM_Tutorial_Day1.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/Day1/HMM_Tutorial_Day1.pptx -------------------------------------------------------------------------------- /Day1/Tutorial_HMM_2022_Day1.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Hidden Markov Models: Basics for animal movement data' 3 | author: "Marie Auger-Méthé & Ron Togunov" 4 | output: 5 | bookdown::html_document2: 6 | number_sections: true 7 | highlight: tango 8 | editor_options: 9 | chunk_output_type: console 10 | --- 11 | 12 | 13 | ```{=html} 14 | 20 | ``` 21 | 22 | 23 | ```{r setup, include=FALSE} 24 | knitr::opts_chunk$set(echo = TRUE) 25 | ``` 26 | # Tutorial goals and set up 27 | 28 | The goal of this tutorial is to explore how to fit hidden Markov models 29 | (HMMs) to movement data. To do so, we will investigate a new R package, 30 | `momentuHMM`. This package builds on a slightly older package, 31 | `moveHMM`, that was developed by Théo Michelot , Roland Langrock, and 32 | Toby Patterson, see associated paper: 33 | . 34 | `momentuHMM`, was developed by Brett McClintock and Théo Michelot. 35 | momentuHMM has new features such as allowing for more data streams, 36 | inclusion of covariates as raster layers, and much more, see associated 37 | paper: 38 | . 39 | 40 | The primary learning objectives in this first tutorial are to: 41 | 42 | 1. Fit simple HMMs using `momentuHMM` 43 | 2. Checking model fit 44 | 3. Determining number of states to use 45 | 4. Incorporating and interpreting covariates on behaviour transition probabilities 46 | 5. Exploring effect of using different temporal resolutions 47 | 48 | ## Setup and data preparation 49 | 50 | First, let's load the packages that we will need to complete the 51 | analyses. Off course you need to have them installed first. 52 | 53 | ```{r Load packages, echo=TRUE, message=FALSE, attr.source = ".numberLines"} 54 | library(momentuHMM) # Package for fitting HMMs, builds on moveHMM 55 | library(raster) # For importing and extracting raster spatial covariates 56 | ``` 57 | 58 | While the `raster` package is being phased out in favour of the new `terra` package, `momentuHMM` still relies on the `raster` package to extract covariates. Therefore, for this tutorial we will still use `raster`, but do start working with `terra` in your work where possible for future compatability. 59 | 60 | Make sure to set working directory to "Day1" of the HMM workshop folder: 61 | 62 | ```{r, eval=FALSE, message=FALSE, attr.source = ".numberLines"} 63 | setwd("Day1") 64 | ``` 65 | 66 | One of the main features of the data used with HMMs is that locations 67 | are taken at regular time steps and that there are negligible position 68 | error. For example, HMMs are adequate to use on GPS tags that take 69 | locations at a set temporal frequency (e.g., every 2 hrs). Without 70 | reprocessing, HMMs are not particularly good for irregular times series 71 | of locations or locations with large measurement error (e.g., you would 72 | need to preprocess Argos data before applying HMMs). 73 | 74 | Unfortunately, movement of aquatic 75 | species is rarely taken at regular time intervals and without 76 | measurement error. For example, the data set we will work on, is the 77 | movement track of a grey seal tagged with a Fastlock GPS tag. This is a 78 | subset of the data set used in the paper from Whoriskey et al. 2017 79 | (), which 80 | applies a set of different HMMs to the movement data of various aquatic 81 | species. The original dataset is available in the online supplementary 82 | information. 83 | 84 | Let's read the data file and peak at it. 85 | 86 | ```{r Load data, warning=FALSE, attr.source = ".numberLines"} 87 | # Make sure you are in the good directory! 88 | seal <- read.csv("data/seals.csv", stringsAsFactors = FALSE) 89 | # Look at the data 90 | head(seal) 91 | ``` 92 | 93 | The files has three columns: date with the date and time, lon with the 94 | longitude, and lat with latitude. It's clear from the date column that 95 | the locations are taken at irregular time intervals. So just like in 96 | Whoriskey et al. 2017, we will regularize it. Note, that `momentuHMM` 97 | has functions to preprocess irregular movement time series and/or time 98 | series with large measurement errors (e.g., `crawlWrap`). 99 | However, these 100 | functions are much more complex. 101 | We will cover some of these functions in tomorrow's tutorial. 102 | For now, as in 103 | Whoriskey et al. 2017, we will assume that the animal moves in a 104 | straight line and at constant speed between two locations and 105 | interpolate the location at regular time intervals based this 106 | assumption. Note that this kind of interpolation may not be adequate in 107 | many circumstances and see activities to investigate the effects of the 108 | choice of the time interval on the analysis. 109 | 110 | ```{r, attr.source = ".numberLines"} 111 | # First, let's transform the date/time info into a 112 | # proper time format 113 | seal$date <- as.POSIXct(seal$date, format = "%Y-%m-%d %H:%M:%S", 114 | tz = "GMT") 115 | # Let's find the most appropriate time interval 116 | # Calculate the time intervals 117 | tint <- as.numeric(diff(seal$date), units = "hours") 118 | # Let's look at the time intervals 119 | summary(tint) 120 | # Min. 1st Qu. Median Mean 3rd Qu. Max. 121 | plot(tint, ylab = "Time interval (hr)", pch = 19, cex = 0.5, 122 | las = 1) 123 | # Let's go for 2 hrs, look at the activities to see 124 | # the effect of this choice 125 | # Regularising Create a 2hr sequence (2*60*60) from 126 | # the first time to the last time 127 | ti <- seq(seal$date[1], seal$date[length(seal$date)], 128 | by = 2 * 60 * 60) 129 | head(ti) 130 | # Interpolate the location at the times from the sequence 131 | iLoc <- as.data.frame(cbind(lon = approx(seal$date, seal$lon, 132 | xout = ti)$y, lat = approx(seal$date, seal$lat, xout = ti)$y)) 133 | # Create a new object that has the regular time and 134 | # interpolated locations 135 | sealreg <- cbind(date = ti, iLoc) 136 | head(sealreg) 137 | # Quickly plot the regularized locations 138 | plot(sealreg$lon, sealreg$lat, pch = 19, cex = 0.5, xlab = "Lon", 139 | ylab = "Lat", las = 1) 140 | # Add the original data 141 | points(seal$lon, seal$lat, pch = 19, cex = 0.5, col = rgb(1, 142 | 0, 0, 0.5)) 143 | # add legend 144 | legend(x = -62.4, y = 42.1, pch = c(19, 19), 145 | legend = c("Original data", "Regularised locations"), 146 | col = c("red", "black")) 147 | ``` 148 | 149 | Here, we interpolated the location data to 2 hours. The resolution we 150 | choose can have a significant effect on the results, so the this 151 | decision must be made wisely. At the end of this tutorial, in section 152 | [Effects of interpolation]{#effect_of_int}. In tomorrow's tutorial, we 153 | will review a more comprehensive strategy to select an appropriate 154 | temporal resolution when we have irregular data. 155 | 156 | Ok, we have now a regular time series of locations. For the most basic 157 | movement HMMs, you need to transform the time series of locations into 158 | two time-series: one which represents the step lengths (distance between 159 | two locations) and one that represents the turning angle (angle between 160 | two steps). The package `momentuHMM` has a function that does that: 161 | `prepData`. The data is in latitude and longitude and I'm assuming using 162 | WGS84. You can use `prepData` on latitude and longitude data or on 163 | projected data (e.g., UTM). `prepData` can do much more, and we will see 164 | some other features later, but for now the arguments that we need to 165 | think about are: 166 | 167 | - type: whether it's easting/northing coordinate system (`type="UTM"`) 168 | or whether it's longitude/latitude (`type = "LL"`). We are using 169 | `"LL"`. 170 | 171 | - `"coordNames"`: the names of the columns with the coordinates. So in 172 | our case `lon` and `lat`. 173 | 174 | ```{r, attr.source = ".numberLines"} 175 | # Preparing the data: here mainly calculating step 176 | # lengths and turning angles 177 | sealPrep <- prepData(sealreg, type = "LL", coordNames = c("lon", 178 | "lat")) 179 | # Let's peak at the data 180 | head(sealPrep) 181 | # What kind of object is this? 182 | class(sealPrep) 183 | ``` 184 | 185 | If we take a quick look at the data, we can see that the step lengths 186 | (column step) and angles (column angle) have been calculated and that 187 | the names of the columns with the coordinates are now x and y, rather 188 | than `lon` and `lat`. We also have a new column: `ID`. In cases where 189 | you have multiple individuals, you would want your original data to have 190 | an `ID` column before being imputed in the `prepData` function. 191 | Note that the object it returns is from a specific S3 class defined in 192 | the `momentuHMM` package. This means that we can apply generic functions 193 | like `plot` to it and it will return specified outputs. 194 | 195 | ```{r, attr.source = ".numberLines"} 196 | plot(sealPrep) 197 | ``` 198 | 199 | We can see the track of the animal and the times series of the step 200 | lengths and turning angles, as well as the histograms of the step 201 | lengths and turning angles. Can you already identify patterns? 202 | 203 | ## Fitting the HMM 204 | 205 | Now that our data is ready to use, we can fit the HMM. For this we use 206 | the function `fitHMM`. This is where we need to make many of our 207 | modelling decisions and most of these decisions will be associated with 208 | one of the arguments of the function. The minimum arguments `fitHMM` 209 | requires are: `fitHMM(data, nbState, dist, Par0)`. 210 | 211 | First, when we fit a HMM, we need to decide the number of behavioural 212 | states we are going to model. To start simple, we will only use two 213 | behavioural states. These could be, for example, representing one 214 | behaviour with fast and directed movement (e.g., travelling) and one 215 | behaviour with a more slow and tortuous movement (e.g., foraging). This 216 | mean that the argument `nbState` will be set to 2. Second, we need to 217 | decide whether we make the transition probabilities between the 218 | behavioural states dependent on covariates. Here again, we will start 219 | simple and we will not use covariates. That means that our formula 220 | argument will be `~1`. Third, we need to select the distribution we will 221 | use to model the step lengths and the one we will use to model the 222 | turning angles. For now, we will use the gamma distribution for the step 223 | length and the von Mises for the turning angles. This means that the 224 | argument dist will be set to: `list(step="gamma", angle="vm")`. Note 225 | that `dist` should be a list with an item for each data stream columns 226 | in the data that we are modelling (so here the column `step` and 227 | `angle`). The gamma distribution is strictly positive (i.e., it does not 228 | allow for 0s). If you have step lengths that are exactly zero in your 229 | data set, you need to use zero-inflated distributions. But in this case, 230 | we have no zeros. Let's check 231 | 232 | ```{r, attr.source = ".numberLines"} 233 | sum(sealPrep$step == 0, na.rm = TRUE) 234 | ``` 235 | 236 | Since the sum is 0, we don't have any values of zero and don't need to 237 | worry about modelling zero-inflation. 238 | 239 | By default, `fitHMM` will set the argument `estAngleMean` to `NULL`, 240 | which means that we assume that the mean angle is 0 for both behaviours 241 | (i.e., the animal has a tendency to continue in the same direction) and 242 | that only the angle concentration parameters differ. The concentration 243 | parameters control the extent to which the animal continues forward 244 | versus turn. Doing so reduces the number of parameters to estimate. 245 | These are all very important decisions that you must make when you 246 | construct your model. In addition, we need to specify initial values for 247 | the parameters to estimate. The HMMs are fit using maximum likelihood 248 | estimate (MLE) with a numerical optimizer. An unfortunate aspect of 249 | fitting models using numerical optimizers, is that, to be able to 250 | explore the parameter space and find the best parameter values for the 251 | model, the optimizer needs to start somewhere. You need to decide where 252 | it starts. Unfortunately, choosing bad starting values can result in 253 | parameter estimates that are not the MLE, but just a local maximum. To 254 | choose your initial parameter you can take a quick peak at the data 255 | (e.g., using the plots below) and use some general biological 256 | information. For example, it's common for animals to have one behaviour 257 | with long step lengths and small turning angles and one behaviour with 258 | short step lengths and larger turning angles. From the plots above, it 259 | looks like the animal has step lengths that are close to 0, 3, 7. As I 260 | see it, there are probably three behaviours with different mean step 261 | lengths around these values. 262 | 263 | ```{r, attr.source = ".numberLines"} 264 | plot(sealPrep$step ~ 265 | sealPrep$date, ty = "l", ylab = "Step length", 266 | xlab = "Date", las = 1) 267 | abline(h = 0, col = rgb(1, 0, 0, 0.5)) 268 | abline(h = 3, col = rgb(1, 0, 0, 0.5)) 269 | abline(h = 7, col = rgb(1, 0, 0, 0.5)) 270 | ``` 271 | 272 | So let's choose 3 and 7 for the means step lengths and use the same 273 | values for the standard deviations. The turning angles are either very 274 | close to 0 or pretty spread from $-\pi$ to $\pi$. High concentration 275 | parameter values ($\kappa$, said kappa) mean that the animal has a 276 | tendency to move in the same direction. Values close to 0 mean that the 277 | turning angle distribution is almost uniform (the animal turns in all 278 | directions). Note that $\kappa$ cannot be exactly 0, so let's choose 0.1 279 | and 1. 280 | 281 | ```{r, attr.source = ".numberLines"} 282 | # Setting up the starting values 283 | mu0 <- c(3, 7) # Mean step length 284 | sigma0 <- c(3, 7) # Sd of the step length 285 | kappa0 <- c(0.1, 1) # Turning angle concentration parameter (kappa > 0) 286 | ``` 287 | 288 | Ok, were are ready. Let's fit the HMM 289 | 290 | ```{r message=FALSE, cache=TRUE, attr.source = ".numberLines"} 291 | # Fit a 2 state HMM 292 | sealHMM2s <- fitHMM(sealPrep, nbState = 2, dist = list(step = "gamma", 293 | angle = "vm"), Par0 = list(step = c(mu0, sigma0), angle = kappa0), formula = ~ 1) 294 | ``` 295 | 296 | Let's explore the results. 297 | 298 | ```{r, attr.source = ".numberLines"} 299 | # Let's look at parameter estimates 300 | sealHMM2s 301 | # Let's plot it 302 | plot(sealHMM2s) 303 | ``` 304 | 305 | Based on the mean step parameters, it looks like the first behavioural 306 | state (state 1) has really small step lengths compare to state 2. This 307 | is particularly easy to see in the step histogram (first figure), where 308 | the estimated distribution for each state is overlaid on top of the 309 | observed step length frequencies. Surprisingly, the turning angle 310 | distributions of the two states both indicate directed movement (second 311 | figure). In fact, the concentration parameter of state 1 is bigger than 312 | that of state 2. In the last figure with the track, it looks like if we 313 | only have state 2. This is strange, since the transition probabilities 314 | estimated indicate that the animal remain in each behaviour for multiple 315 | steps (diagonal values of the transition probability matrix are \> 0.5). 316 | 317 | Part of what's happening may be that the locations of state 1 are hidden 318 | under state 2. We can see if this is the case by plotting state 2 with a 319 | higher transparency. 320 | 321 | ```{r, attr.source = ".numberLines"} 322 | # plot it with transparency 323 | plot(sealHMM2s, col = c(rgb(230, 160, 20, max = 255), 324 | rgb(80, 180, 230, alpha = 80, max = 255))) 325 | ``` 326 | 327 | Indeed, we are getting two states, but there is likely more going on. 328 | 329 | # Identifying behavioural states 330 | 331 | Maybe looking at the state sequence in more detail will help us 332 | understand. Actually, we are interested in identifying when an animal is 333 | in each of the behavioural states (here when the animal is in state 1 vs 334 | state 2), something we call state decoding. To do so, we can use the 335 | function `viterbi`, which uses the Viterbi algorithm to produce the most 336 | likely sequence of states according to your fit model and data. 337 | 338 | ```{r, cache=TRUE, attr.source = ".numberLines"} 339 | # Apply the Viterbi algorithm using your fited model object 340 | sealStates <- viterbi(sealHMM2s) 341 | # Let's look at predicted states of the first 20 time steps 342 | head(sealStates, 20) 343 | # How many locations in each state do we have? 344 | table(sealStates) 345 | ``` 346 | 347 | So they are some state 1, we are just not seeing them! 348 | 349 | In many cases, it is more interesting to get the probability of being in 350 | each state rather than the most likely state. To do so, you can use the 351 | function `stateProbs`, which returns a matrix of the probability of 352 | being in each state for each time step. 353 | 354 | ```{r, attr.source = ".numberLines"} 355 | # Calculate the probability of being in each state 356 | sealProbs <- stateProbs(sealHMM2s) 357 | # Let's look at the state probability matrix 358 | head(sealProbs) 359 | ``` 360 | 361 | We can see here the probability of being in both states for the first 6 362 | time steps. Here, the probability of being in state 1 is really high for 363 | these steps, but that may not always be the case. Sometimes you might 364 | have values closer to 0.5, which would indicate that for that time step, 365 | it's hard to identify which state you are in (i.e., which step length 366 | and turning angle distributions fit best). 367 | 368 | You can plot the results from both of these functions using the function 369 | `plotState` 370 | 371 | ```{r, attr.source = ".numberLines"} 372 | plotStates(sealHMM2s) 373 | ``` 374 | 375 | We clearly have two behavioural states. The steps from `state` 1 are 376 | just too small for us to see them in the track. 377 | 378 | # But do we have a good model? 379 | 380 | This is all great, but is this a good model for our data? 381 | 382 | ## Starting values: should we care? 383 | 384 | The first thing we need to look into is whether the parameter estimates 385 | are reliable. As I mentioned above, the initial parameter values can 386 | affect the estimating procedures. So it's always good to check if you 387 | get similar results with different starting values. Here, we will make 388 | the starting values of the two behavioural states closer to one another. 389 | 390 | ```{r message=FALSE, cache=TRUE, attr.source = ".numberLines"} 391 | # Setting up the starting values (more similar values) 392 | mu02 <- c(5, 7) # Mean step length 393 | sigma02 <- c(5, 7) # Sd of the step length 394 | kappa02 <- c(1, 1) # Turning angle concentration parameter (kappa > 0) 395 | 396 | # Fit the same 2 state HMM 397 | sealHMM2s2 <- fitHMM(sealPrep, 398 | nbState = 2, 399 | dist=list(step="gamma", angle="vm"), 400 | Par0 = list(step=c(mu02, sigma02), angle=kappa02)) 401 | ``` 402 | 403 | Let's compare the two results. First let's look at which of the two has 404 | the lowest negative log likelihood (equivalent of highest log 405 | likelihood, so closer to the real MLE). Let's look also at the parameter 406 | estimates they each returned. 407 | 408 | ```{r, attr.source = ".numberLines"} 409 | # Negative log likelihood 410 | c(original = sealHMM2s$mod$minimum, new = sealHMM2s2$mod$minimum) 411 | 412 | # Parameter estimates 413 | cbind(sealHMM2s$mle$step, sealHMM2s2$mle$step) 414 | cbind(sealHMM2s$mle$angle, sealHMM2s2$mle$angle) 415 | cbind(sealHMM2s$mle$gamma, sealHMM2s2$mle$gamma) 416 | ``` 417 | 418 | Looks like they both returned very close values for everything. So 419 | that's good! The function `fitHMM` also has the argument `retryFits` 420 | which perturbs the parameter estimates and retry fitting the model. The 421 | argument is used to indicate the number of times you want perturb the 422 | parameters and retry fitting the model (you can choose the size of the 423 | perturbation by setting the argument `retrySD`). 424 | 425 | Let's try (this will take a few minutes). 426 | 427 | ```{r message=FALSE, cache=TRUE, attr.source = ".numberLines"} 428 | # Fit the same 2-state HMM with retryFits 429 | # This is a random pertubation, so setting the seed to get the same results 430 | set.seed(1234) 431 | sealHMM2sRF <- fitHMM(sealPrep, 432 | nbState = 2, 433 | dist=list(step="gamma", angle="vm"), 434 | Par0 = list(step=c(mu02, sigma02), angle=kappa02), 435 | retryFits=10) 436 | ``` 437 | 438 | Let's compare the results again. 439 | 440 | ```{r, attr.source = ".numberLines"} 441 | # Negative log likelihood 442 | c(original = sealHMM2s$mod$minimum, new = sealHMM2s2$mod$minimum, 443 | retryFits = sealHMM2sRF$mod$minimum) 444 | 445 | # Parameter estimates 446 | cbind(sealHMM2s$mle$step, sealHMM2s2$mle$step, sealHMM2sRF$mle$step) 447 | cbind(sealHMM2s$mle$angle, sealHMM2s2$mle$angle, sealHMM2sRF$mle$angle) 448 | cbind(sealHMM2s$mle$gamma, sealHMM2s2$mle$gamma, sealHMM2sRF$mle$gamma) 449 | ``` 450 | 451 | Still looking very similar! 452 | 453 | But let's choose some wild starting values to see the type of problems 454 | we might run into. 455 | 456 | ```{r message=FALSE, cache=TRUE, attr.source = ".numberLines"} 457 | # Setting wild starting values 458 | mu0W <- c(5, 100) # Mean step length 459 | sigma0W <- c(5, 0.1) # Sd of the step length 460 | kappa0W <- c(10, 0.01) # Turning angle concentration parameter (kappa > 0) 461 | sealHMM2sW <- fitHMM(sealPrep, nbState = 2, 462 | dist=list(step="gamma", angle="vm"), 463 | Par0 = list(step=c(mu0W,sigma0W), angle=kappa0W)) 464 | 465 | ``` 466 | 467 | Let's compare the negative log likelihood (note that we want the minimum 468 | value here to get the MLE) and parameter estimates. 469 | 470 | ```{r, attr.source = ".numberLines"} 471 | # Negative log likelihood 472 | c(original = sealHMM2s$mod$minimum, wild=sealHMM2sW$mod$minimum) 473 | 474 | # Parameter estimates 475 | cbind(sealHMM2s$mle$step, sealHMM2sW$mle$step) 476 | cbind(sealHMM2s$mle$angle, sealHMM2sW$mle$angle) 477 | cbind(sealHMM2s$mle$gamma, sealHMM2sW$mle$gamma) 478 | ``` 479 | 480 | The negative log likelihood here is much larger than the negative log 481 | likelihood of the model fit with the sensible starting values. Note 482 | also that some of the parameter estimates are exactly the same values as 483 | the initial values, which is always a sign of optimization problems. 484 | These are all signs that the model fit with this new set of starting 485 | values is not good. Sometimes, you will get error messages saying that 486 | `nlm` or `optim`, the functions that minimize the negative log 487 | likelihood, did not converged or that non-finite values were supplied to 488 | them. Sometimes, you might not be able to plot the data or get the 489 | states. These are also signs that the starting values are poor or that 490 | the model is not good for your data. 491 | 492 | We will see later, that the package `momentuHMM` has functions to help 493 | selecting initial parameters for complex models. However, these 494 | functions rely on the user choosing initial parameter values for a 495 | simple model like the one we just explored. 496 | 497 | ## Pseudo-residuals 498 | 499 | Ok, we fit a model to data, looks like the parameter estimates are 500 | reliable, and we can get state probabilities, but is this a good model 501 | for our data? Can we use the model results? The best way to investigate 502 | model fit is through pseudo-residuals. Pseudo-residuals are a type of 503 | model residuals that account for the interdependence of observations. 504 | They are calculated for each of the time series (e.g., you will have 505 | pseudo-residuals for the step length time series and for the turning 506 | angle time series). If the fit model is appropriate, the 507 | pseudo-residuals produced by the functions `pseudoRes` should follow a 508 | standard normal distribution. You can look at pseudo-residuals directly 509 | via the function `plotPR`, which plots the pseudo-residual times-series, 510 | the qq-plots, and the autocorrelation functions (ACF). 511 | 512 | ```{r, attr.source = ".numberLines"} 513 | plotPR(sealHMM2s) 514 | ``` 515 | 516 | Both the qq-plot and the ACF plot indicate that the model does not fit 517 | the step length time series particularly well. The ACF indicates that 518 | there is severe autocorrelation remaining in the time series, even after 519 | accounting for the persistence in the underlying behavioural states. 520 | 521 | This could indicate that there are more hidden behavioural states. Let's 522 | try a 3-state HMMs. 523 | 524 | ```{r message=FALSE, cache=TRUE, attr.source = ".numberLines"} 525 | # Setting up the starting values (we need 3 now, because 3 states) 526 | mu03s <- c(0.1, 3, 7) # Mean step length 527 | sigma03s <- c(0.1, 3, 7) # Sd of the step length 528 | kappa03s <- c(0.1, 1, 1) # Turning angle concentration parameter 529 | 530 | # Fit a 3 state HMM 531 | sealHMM3s <- fitHMM(sealPrep, 532 | nbState = 3, 533 | dist=list(step="gamma", angle="vm"), 534 | Par0 = list(step=c(mu03s, sigma03s), angle=kappa03s)) 535 | ``` 536 | 537 | Let's look at it and at the pseudo-residuals. 538 | 539 | ```{r, attr.source = ".numberLines"} 540 | plot(sealHMM3s) 541 | plotStates(sealHMM3s) 542 | plotPR(sealHMM3s) 543 | ``` 544 | 545 | Ah, that's better. Not perfect, but less unexplained autocorrelation, 546 | especially in the step lengths. Some of the unexplained autocorrelation 547 | in the turning angles is related to the method we used to get location 548 | estimates at regular time intervals, see activities to explore this a 549 | bit more in depth. If we look at the step length distribution, we can 550 | see that we have still our state with really small steps (maybe 551 | resting?), a state with steps of medium size (maybe foraging?), and a 552 | state with large steps (maybe travelling?). Looking at the track, it 553 | does look like the movement in state 2 is more tortuous and in focal 554 | areas, while the movement in state 3 is very directed and span larger 555 | areas. 556 | 557 | ## Simulating data 558 | 559 | We can also use the function `simData` to look at whether the movement 560 | produced by the models is similar to the observed movement. Let's 561 | simulate the 3-state HMMs, and then fit it to be able to identify the 562 | behavioural states. Note that we could just plot directly the simulated 563 | data and colour code the state, rather than estimating the fitting the model and predicting the 564 | states and plotting the predicted states. 565 | However, plotting the simulated data might require a bit of fiddling (A good thing to know is 566 | that the colour palette used by the packages is: 567 | `c("#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7")`). 568 | One way fitting the model to the simulated data may be useful is in 569 | identifying whether you have enough data to estimate your parameters 570 | accurately. 571 | 572 | ```{r message=FALSE, cache=TRUE, attr.source = ".numberLines"} 573 | # Simulate the model 574 | sealSim <- simData(model=sealHMM3s, nbAnimals =1, states = TRUE) 575 | # Fit the model to the simulated data 576 | sealSimFit <- fitHMM(sealSim, 577 | nbState = 3, 578 | dist=list(step="gamma", angle="vm"), 579 | Par0 = list(step=c(mu03s, sigma03s), angle=kappa03s)) 580 | 581 | ``` 582 | 583 | ```{r, attr.source = ".numberLines"} 584 | # Plot the results 585 | plot(sealSimFit) 586 | # Compared the parameter estimates 587 | sealSimFit 588 | sealHMM3s 589 | ``` 590 | 591 | Looks similar, except maybe that the real seal goes back and forth to 592 | some of the same locations, something not captured in the simulation. 593 | The parameter estimates are close to those used to simulate the data, 594 | which is good. 595 | 596 | ## Confidence intervals 597 | 598 | We can look at the confidence intervals for the parameter estimates. 599 | This does not necessarily give us an idea of whether the model is good 600 | or not, but it helps us understand whether the behavioural states have 601 | different movement characteristics. To compute the confidence intervals, 602 | we can use the function `CIreal`. 603 | 604 | For example, let's look the step length mean parameters. 605 | 606 | ```{r, attr.source = ".numberLines"} 607 | # Caculate the CIs 608 | sealCI <- CIreal(sealHMM3s) 609 | # Let's look at the step lenth CIs 610 | rbind(lower=sealCI$step$lower["mean",], 611 | upper = sealCI$step$upper["mean",]) 612 | ``` 613 | 614 | We can see that the 95% confidence intervals of mean step length does 615 | not overlap for the three states, indicating that, in term of step 616 | lengths, they vary quite a bit. 617 | 618 | # Understanding the factors that affect movement: including covariates 619 | 620 | `momentuHMM` allows you to incorporate various covariates in the model 621 | in many different ways, which allows you to understand how covariates 622 | affect the behaviour and movement of the animal. There are so many 623 | different options (including activity centers, spatial covariates, etc), 624 | that it's impossible to look at them all here. Here are a few examples. 625 | 626 | ## Spatial covariates 627 | 628 | One of the most exciting aspect of `momentuHMM` is that you can 629 | incorporate spatial covariates that are kept in a raster file. Here we 630 | will use a raster that contains the bathymetry in the area of the seal. 631 | I created this file using the package `marmap`. To read the file you 632 | need the function `raster` from the package with the same name. 633 | 634 | Let's read the file and plot it. 635 | 636 | ```{r, attr.source = ".numberLines"} 637 | # Read the raster 638 | bathy <- raster("data/bathy.grd") 639 | # Let's plot the bathymethy raster 640 | plot(bathy) 641 | ``` 642 | 643 | This represents the bathymetry in meters. Any value above 0 is on land. 644 | 645 | Here we will use the function `prepData` again, but this time including 646 | the raster as a spatial covariate. The function will extract the raster 647 | values at the seal locations. Off course for this to work the spatial 648 | covariate raster needs to be in the same projection as the movement 649 | data. It's the case here. 650 | 651 | ```{r, attr.source = ".numberLines"} 652 | sealPrep <- prepData(sealreg, type="LL", coordNames = c("lon", "lat"), 653 | spatialCovs = list(bathy=bathy)) 654 | head(sealPrep) 655 | ``` 656 | 657 | Now our `sealPrep` object has a new column with the bathymetry value at 658 | that location. 659 | 660 | There are two ways in which the bathymetry can influence the movement of 661 | the animal. It can influence the behavioural state the animal is in or 662 | it can influence the movement characteristics in some of the state (e.g. 663 | change the mean step length value in one of the behavioural states). 664 | 665 | Let's explore the first option. So here we are assuming that the 666 | probability to switch between behavioural states is affected by the 667 | bathymetry. Because of the way the HMMs are constructed, we have to 668 | estimate one more parameter per switching probability ($\gamma_{ij}$ 669 | said gamma i j), excluding the probability of remaining in the same 670 | state, which can be deducted based on the switching probabilities. 671 | Please see the mathy section below to understand the details. So if $N$ 672 | represents the number of states, it means you need to estimate $N(N-1)$ 673 | new parameters. For an HMM with 3 states, we would estimate 6 new 674 | parameters. 675 | 676 | The main argument of the `fitHMM` function that we need to change are 677 | the `formula` and the starting values (because we have 6 new parameters 678 | to estimate). The default value for the `formula` is $\sim 1$, which 679 | means that the transition probability are not affected by covariates. 680 | Here, we want to indicate that the transition probabilities are affected 681 | by the bathymetry. We can use the function `getPar0` to help us find 682 | starting values based on our simpler 3-state HMMs. This might be a bit 683 | of an overkill for this model, as `getPar0` will set the starting values 684 | for the covariate effects on the transition probabilities to 0. But it 685 | can make a small difference to use good starting values for the other 686 | parameters (might be worth looking if it makes indeed a difference). 687 | Note that to be able to use `getPar0` in this case, we have to refit the 688 | simpler model with the new data that has the bathymetry data. 689 | 690 | ```{r message=FALSE, attr.source = ".numberLines"} 691 | # New formula 692 | bathyForm <- ~bathy 693 | 694 | # Refit the simple 3-states HMM - so it's associated with the data with bathymetry 695 | sealHMM3s <- fitHMM(sealPrep, 696 | nbState = 3, 697 | dist=list(step="gamma", angle="vm"), 698 | Par0 = list(step=c(mu03s, sigma03s), angle=kappa03s)) 699 | 700 | # Get new starting values based on simpler model, here the 3-states HMM 701 | par0b <- getPar0(model=sealHMM3s, formula=bathyForm) 702 | ``` 703 | 704 | ```{r, attr.source = ".numberLines"} 705 | # Look at the starting values 706 | par0b 707 | ``` 708 | 709 | ```{r message=FALSE, attr.source = ".numberLines"} 710 | # Now we fit the new model with bathymetry 711 | sealHMMb <- fitHMM(sealPrep, nbState = 3, 712 | dist=list(step="gamma", angle="vm"), 713 | Par0 = par0b$Par, beta0=par0b$beta, 714 | formula=bathyForm) 715 | ``` 716 | 717 | ```{r, attr.source = ".numberLines"} 718 | sealHMMb 719 | ``` 720 | 721 | The first thing to note is that the model now has a new row of 722 | parameters in the section 723 | `Regression coeffs for the transition probabilities`. This row 724 | represents the effects of bathymetry on the transition probabilities. A 725 | positive value means that increasing values of the covariate increase 726 | the switching probability, while a negative value means the reverse 727 | relationship. So for example, as bathymetry increases, the probability 728 | of switching from state 1 to state 2 only slightly increases, but the 729 | probability of switching from state 3 to state 1 increases much more. 730 | Note that the relationship between these coefficients and the final 731 | transition probabilities are dependent on each other and on the 732 | intercept, see math section for details. Keep in mind here that 733 | bathymetry is represented in negative values, so as bathymetry value 734 | increases the seal is in shallower water. 735 | 736 | The row with the intercept represents the base probabilities before we 737 | incorporate the bathymetry effects. In model without covariates, you 738 | would only get the intercept values and would use them alone to 739 | calculate the transition probabilities, see the math section below for 740 | more details. 741 | 742 | Let's look at it visually. First by using the generic `plot` function 743 | and, then, by using the function `plotStationary`, which plots the 744 | stationary state probabilities. 745 | 746 | ```{r, attr.source = ".numberLines"} 747 | plot(sealHMMb) 748 | ``` 749 | 750 | 751 | 752 | We can see that the bathymetry mainly affects the transition probability 753 | in high bathymetry values (so, close/on land). One of the most obvious 754 | patterns is that it increases the probability of switching to state 1 755 | from both states 2 and 3 and decreases the probability of staying in 756 | state 2 and staying in state 3. Remember, state 1 is associated with the 757 | very small step lengths. This is likely seal hauling out on land or 758 | resting in shallow waters! In fact, one of the places where we have a 759 | lot of state 1 is on small islands, where I'm pretty sure they are known 760 | to haul out. 761 | 762 | Here a quick plot to convince you. 763 | 764 | ```{r, attr.source = ".numberLines"} 765 | # Create a new file, so we can see land better 766 | water <- bathy 767 | water[water >= 0] <- NA 768 | # Create color ramp to show bathymetry in blue gradients 769 | bluePal <- colorRampPalette(c(rgb(0.1,0.1,1), rgb(0.9,0.9,1))) 770 | 771 | # plot depth with land (NA) as grey 772 | plot(water, col = bluePal(50), colNA = "grey30") 773 | # Let's plot only the state 1 774 | points(sealPrep[viterbi(sealHMMb) == 1, c("x","y")], 775 | col = rgb(230, 160, 20, 12, max = 255), 776 | pch = 19) 777 | # add legend 778 | legend(x = -60.8, y = 40.3, pch=c(19, NA), 779 | legend = c("State 1", "Land"), col = c("#E69F00", NA), 780 | fill = c(NA, "grey20"), border = NA) 781 | ``` 782 | 783 | Ok, but it is a better model? 784 | 785 | ```{r, attr.source = ".numberLines"} 786 | AIC(sealHMM3s, sealHMMb) 787 | ``` 788 | 789 | Yes. 790 | 791 | What about the pseudo-residuals? 792 | 793 | ```{r, attr.source = ".numberLines"} 794 | plotPR(sealHMM3s) 795 | ``` 796 | 797 | Still some issues, but not too too bad. 798 | 799 | ## Non spatial covariates 800 | 801 | Could there be diurnal patterns explaining the autocorrelation in 802 | turning angles? We are not limited to incorporate spatial covariates. We 803 | can incorporate any covariates as long as we can relate each of the 804 | locations to a covariate value (that's in essence what the `prepData` 805 | function does for the spatial covariates). 806 | 807 | So here we are going to create a new column that keeps track of the hour 808 | of the day for each observation. We are going to set it in the time zone 809 | where the seals are. 810 | 811 | ```{r, attr.source = ".numberLines"} 812 | sealPrep$hour <- as.integer(strftime(sealPrep$date, format = "%H", tz="Etc/GMT+4")) 813 | ``` 814 | 815 | Here again we can make the covariate affect the transition 816 | probabilities. The difference is that we have to use a more complex 817 | function that represents the cyclical nature of time of day. This is the 818 | `cosinor` function. For more information on the `cosinor` function, see 819 | mathy section below. 820 | 821 | ```{r message = FALSE, attr.source = ".numberLines", cache=TRUE} 822 | # New formula that says that the transition probabilties are affected by the time of day 823 | diurnForm <- ~ cosinor(hour, period = 24) 824 | 825 | # Refit model with new data 826 | sealHMM3s <- fitHMM(sealPrep, 827 | nbState = 3, 828 | dist = list(step = "gamma", angle = "vm"), 829 | Par0 = list(step = c(mu03s, sigma03s), angle = kappa03s)) 830 | 831 | # Get initial parameters 832 | par0diurn <- getPar0(model = sealHMM3s, formula = diurnForm) 833 | 834 | # Now we fit the diurnal model with the starting values returned by getPar0 835 | sealHMMdiurn <- fitHMM(sealPrep,nbState = 3, 836 | dist = list(step = "gamma", angle = "vm"), 837 | Par0 = par0diurn$Par, beta0 = par0diurn$beta, 838 | formula = diurnForm) 839 | ``` 840 | 841 | ```{r, attr.source = ".numberLines"} 842 | # Let's look at the results 843 | sealHMMdiurn 844 | plot(sealHMMdiurn) 845 | AIC(sealHMMb, sealHMMdiurn) 846 | ``` 847 | 848 | I'm not a 100% sure how to interpret the results biologically. But again 849 | it appears to be affecting state 1, which is likely resting. According 850 | to AIC it's less good than the bathymetry model. 851 | 852 | To help understand the relationship further we can also use the function 853 | `plotStationary`, which display the relationship between the covariate 854 | and the stationary probability of being in each state rather than the 855 | relationship between the covariates and the switching probability. 856 | 857 | ```{r, attr.source = ".numberLines"} 858 | plotStationary(sealHMMdiurn) 859 | ``` 860 | 861 | So it looks like there is a higher probability of being in state 2 (the 862 | foraging type of behaviour) at night and a peak in each of the other 863 | behaviours during different period of the day. Some datasets are very 864 | high resolution, and it's important to note that daily effects can only 865 | be used when the data spans at least several days. 866 | 867 | Covariates can affect the state-dependent movement, by which I mean the 868 | characteristics of the movement in a given state. So for example, the 869 | animal might make all the behaviours at night and during the day, but at 870 | night it might do them with smaller steps. Here, we are going to look at 871 | whether the seal is more or less directed at night. To do this, we are 872 | going to change the argument `DM`. For this kind of model, it's 873 | particular useful to use `getPar0`, because it helps set starting values 874 | for the parameters associated with the effects of covariates on the 875 | movement parameters. 876 | 877 | ```{r, attr.source = ".numberLines"} 878 | # Use the formula to describe the changes in the design matrix 879 | diurnDM <- list(angle = list(concentration = ~ cosinor(hour, period = 24))) 880 | 881 | # Get parameter starting values 882 | par0diurnDM <- getPar0(model=sealHMM3s, DM=diurnDM) 883 | # Look at starting values 884 | par0diurnDM 885 | ``` 886 | 887 | ```{r message=FALSE, attr.source = ".numberLines", cache=TRUE} 888 | # Now we fit the new diurnal model with the starting values returned by getPar0 889 | sealHMMdiurnDM <- fitHMM(sealPrep, nbState = 3, 890 | dist=list(step="gamma", angle="vm"), 891 | Par0 = par0diurnDM$Par, beta0=par0diurnDM$beta, 892 | DM=diurnDM) 893 | ``` 894 | 895 | ```{r, attr.source = ".numberLines"} 896 | # Let's look at the results 897 | sealHMMdiurnDM 898 | plot(sealHMMdiurnDM, plotCI=TRUE) 899 | AIC(sealHMMb, sealHMMdiurn, sealHMMdiurnDM) 900 | ``` 901 | 902 | So here it looks like the seal makes more directed movement in state 1 903 | at night, makes more directed movement in state 2 early in the morning, 904 | and makes more directed movement in state 3 early in the morning. 905 | But the CIs are wide and according to AIC, the bathymetry model outperform this model. 906 | 907 | Note that we can combine various covariates. For example, here we are 908 | going to combine bathymetry and time of day. 909 | 910 | ```{r message=FALSE, attr.source = ".numberLines", cache=TRUE} 911 | # Get parameter starting values 912 | par0bd <- getPar0(model=sealHMM3s, formula=bathyForm, DM=diurnDM) 913 | 914 | # Now we fit the new model with the starting values returned by getPar0 915 | sealHMMbd <- fitHMM(sealPrep, nbState = 3, 916 | dist=list(step="gamma", angle="vm"), 917 | Par0 = par0bd$Par, beta0=par0bd$beta, 918 | formula=bathyForm, 919 | DM=diurnDM) 920 | ``` 921 | 922 | ```{r, attr.source = ".numberLines"} 923 | # Let's look at the results 924 | sealHMMbd 925 | plot(sealHMMbd) 926 | AIC(sealHMMb, sealHMMdiurn, sealHMMdiurnDM, sealHMMbd) 927 | plotPR(sealHMMbd) 928 | ``` 929 | 930 | While this combined model is better, given the complexity, I think I 931 | would stick to the bathymetry model for the moment and look into better 932 | ways to try to explain the data, especially since incorporating the time 933 | of day doesn't fix the angle pseudo-residual problem. 934 | 935 | This is where we stop the main tutorial. There are two other sections 936 | below. One that describes some of the mathematical details and one with 937 | activities that you can do on your own to further explore HMMs. 938 | 939 | # For the statistically/mathematically inclined 940 | 941 | One of the most exciting aspect of the `momentuHMM` package is that you 942 | can incorporate the potential effects of environmental covariates on the 943 | probability of switching behavioural states. To understand how the 944 | covariates can affect the behaviour, it's useful to spend time 945 | understanding the transition probabilities. This section is a bit more 946 | technical, but I think is needed to fully understand what the estimated 947 | covariate relationships mean. 948 | 949 | If you have a model that has two behavioural states (state 1 and 2) and 950 | no covariates, you would have a transition probability matrix like this: 951 | 952 | \begin{equation} 953 | \mathbf{\Gamma} = 954 | \begin{pmatrix} 955 | \gamma_{11} & \gamma_{12}\\ 956 | \gamma_{21} & \gamma_{22} (\#eq:gamma) 957 | \end{pmatrix}, 958 | \end{equation} 959 | 960 | where $\gamma_{ij}$ represent the probability of switching from i to j. 961 | For example, $\gamma_{11}$ represents the probability of staying in 962 | state 1 if you are already in state 1. Similarly, $\gamma_{12}$ 963 | represents the probability of switching to state 2 if you are in state 964 | 1. By definition the row entries need to sum to 1. Which simply means 965 | that if you are in state 1 at time $t-1$ you will end up in a state at 966 | time $t$ (i.e., you don't go in behavioural limbo). 967 | 968 | Let's look again at the transition probability matrix that was estimated 969 | in our seal example. 970 | 971 | ```{r, attr.source = ".numberLines"} 972 | sealHMM2s 973 | ``` 974 | 975 | We can see that the probability of switching in state 2 if you are in 976 | state 1 is $\approx `r round(sealHMM2s$mle$gamma[1,2],2)`$ and so the probability 977 | of staying in state 1 is 978 | $\approx `r round(sealHMM2s$mle$gamma[1,1],2)`$. 979 | The same logic applies to the probability of staying or switching from 980 | state 2. This means that for a model with $N$ behavioural states, we 981 | only need to estimate $N (N-1)$ transition probabilities (so 2 for the 982 | example here), because for each state at time $t-1$ we will be able to 983 | calculate one of the transition probabilities based on the difference 984 | with the sum of the transition probabilities estimated (so here we can 985 | deduce $\gamma_{11}$ based on $\gamma_{12}$). 986 | 987 | To incorporate the covariates we are saying that the transition 988 | probabilities are changing through time as a function of the covariate 989 | values at that time step. Specifically, 990 | 991 | 992 | \begin{equation} 993 | \gamma^{(t)}_{ij} = \frac{\exp(\eta_{ijt})}{\sum^N_{k=1}\exp(\eta_{ikt})}, (\#eq:linkFx) 994 | \end{equation} 995 | 996 | where 997 | 998 | 999 | \begin{equation} 1000 | \eta_{ijt} =\begin{cases}\beta_{0ij} + \sum^p_{l=1} \beta_{lij} w_{lt} & \text{if} \ i \neq j,\\0, & \text{otherwise},\end{cases}(\#eq:covRel) 1001 | \end{equation} 1002 | 1003 | 1004 | where $w_{lt}$ is the $l$-th covariate at time $t$ and $p$ is the number 1005 | of covariates considered. Equation \@ref(eq:linkFx) is only a link 1006 | function to ensure that the transitions probabilities are between 0 and 1007 | 1 and that the row sum to 1. The important relationship between the 1008 | covariates and the transition probabilities are in equation 1009 | \@ref(eq:covRel), where the $\beta_{0ij}$ is the base transition probability 1010 | for the switch from state $i$ to state $j$ that is not affected by the 1011 | covariates. The $\beta_{lij}$ are the coefficient relating the 1012 | transition probability to the $l$-th covariate. Note that $\eta_{ii}$ 1013 | (the probability of staying in state $i$, the diagonal values in the 1014 | transition probability matrix) are fixed to 0 because we only want to 1015 | $N (N-1)$ transition probabilities to be estimated and the row sums to 1016 | one. 1017 | 1018 | So in a model with no covariates, only the $\beta_{0ij}$ for $i \neq j$ 1019 | (switching probabilities from state $i$ to another state $j$) are 1020 | estimated. If you look in the code box above you'll see that we only 1021 | have \emph{regression coeffs for the transition probabilities} for 1 1022 | $->$ 2 and 2 $->$ 1, and that the transition probabilities for 1023 | corresponding states are 1024 | $\gamma_{ij} = \frac{\exp(\eta_{ij})}{\sum^N_{k=1}\exp(\eta_{ik})}$. 1025 | 1026 | For example, for the transition probability from state 1 to state 2. 1027 | 1028 | ```{r, attr.source = ".numberLines"} 1029 | # gamma_{12} 1030 | sealHMM2s$mle$gamma[1,2] 1031 | # gamma_{12} calculated based on the equations above 1032 | exp(sealHMM2s$mle$beta[1])/(exp(0)+exp(sealHMM2s$mle$beta[1])) 1033 | ``` 1034 | 1035 | So the way we interpret the $\beta$ values, is that if they are 1036 | positive, it means that they increase the transition probability. Since 1037 | the total value of $\eta$ is what affects the transition probability, 1038 | the magnitude and sign of the intercept ($\beta_0$) will affect when the 1039 | transition probability goes from above or below 0.5. 1040 | 1041 | This is a great way to incorporate covariates, but it means that it add 1042 | $N(N-1)$ parameters to your model, where $N$ is the number of states. So 1043 | if you have many behavioural states, it will results in a very complex 1044 | model. 1045 | 1046 | ## cosinor 1047 | 1048 | The function `cosinor` internally creates the covariates 1049 | cos$(2 \pi \; \text{value}/\text{period})$ and 1050 | sin$(2 \pi \; \text{value}/\text{period})$. So for example 1051 | cos$(2 \pi \; \text{hour}/24)$. 1052 | 1053 | ```{r, attr.source = ".numberLines"} 1054 | plot(cos(2*pi*(1:24)/24), pch=19, ylab="cosinorCos", xlab="Time of day") 1055 | ``` 1056 | 1057 | ```{r, attr.source = ".numberLines"} 1058 | plot(sin(2*pi*(1:24)/24), pch=19, ylab="cosinorSin", xlab="Time of day") 1059 | ``` 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | # Activities 1070 | 1071 | ## Try it on your own data 1072 | 1073 | Give it a try on your own data! If you don't have data try the other 1074 | activities. 1075 | 1076 | ## Activity centers 1077 | 1078 | This is fun but could be hard. Skip to the next activity if you find the 1079 | material challenging. 1080 | 1081 | Let's look whether adding bathymetry improved the simulations. Here, 1082 | it's easy to have some problem, where the animal moves outside of the 1083 | raster. So to help, we are setting the initial position as the initial 1084 | position observed. We are also limiting the simulation to a time series 1085 | of 200 steps. We are also setting the seed, because the animal will 1086 | often wonder off map by chance. 1087 | 1088 | ```{r message=FALSE, attr.source = ".numberLines", cache=TRUE} 1089 | set.seed(1) 1090 | sealSimB <- simData(model=sealHMMb, nbAnimals =1, spatialCovs = list(bathy=bathy), 1091 | initialPosition = as.matrix(sealreg[1,c("lon","lat")]), 1092 | obsPerAnimal = 100, retrySims = 10) 1093 | sealSimFitB <- fitHMM(sealSimB, 1094 | nbState = 3, 1095 | dist=list(step="gamma", angle="vm"), 1096 | Par0 = par0b$Par, beta0=par0b$beta, 1097 | formula=bathyForm) 1098 | ``` 1099 | 1100 | ```{r, attr.source = ".numberLines"} 1101 | # Plot simulation 1102 | plot(water, col=bluePal(50)) 1103 | points(sealSimB[,c("x","y")], 1104 | col=c("#E69F00", "#56B4E9", "#009E73")[viterbi(sealHMMb)], 1105 | pch=19, cex=0.5) 1106 | ``` 1107 | 1108 | I'm not sure. The animal definitely wonders off in regions we wouldn't 1109 | expect it to go. But the state 1 is only in shallow waters. 1110 | 1111 | Look at the `momentuHMM` vignette and see whether you can include 1112 | activity centers. 1113 | 1114 | ## Modelling step length and turning angles 1115 | 1116 | You can model the observations with a set of different distributions. To 1117 | change the distribution simply requires changing the argument `dist` in 1118 | the function `fitHMM`. In the example above, we used the gamma 1119 | distribution (using the name `"gamma"`) for the step length. However, 1120 | you can use a variety of alternative distribution, including: Weibull 1121 | (`"weibull"`) and exponential (`"exp"`). Similarly, we used the von 1122 | Mises (named `"vm"`) for the turning angle distribution, but one could 1123 | use the wrapped Cauchy (`"wrpcauchy"`). 1124 | 1125 | Explore whether changing the distribution affects the fit of the model. 1126 | Use AIC to compare the different models. Use the `plot` and `viterbi` 1127 | functions to see whether it has a meaningful biological effect. 1128 | 1129 | For a description of the parameters needed for each of the 1130 | distributions, please see `momentuHMM` vignette. 1131 | 1132 | ```{r message=FALSE, attr.source = ".numberLines"} 1133 | 1134 | #### Wrapped Cauchy for turning angle 1135 | kappa0wp <- c(0.9, 0.9) # Turning angle concentration parameter, kappa close 1136 | sealHMMwp <- fitHMM(sealPrep, nbState = 2, 1137 | dist=list(step="gamma", angle="wrpcauchy"), 1138 | Par0 = list(step=c(mu0,sigma0), angle=kappa0wp)) 1139 | ``` 1140 | 1141 | ```{r, attr.source = ".numberLines"} 1142 | AIC(sealHMM2s, sealHMMwp)# Wrapped Cauchy better 1143 | 1144 | #### Weibull for step length 1145 | mu0 <- c(0.6, 1) # Shape 1146 | sigma0 <- c(1, 5) # Rate 1147 | kappa0 <- c(0.9, 0.9) # Turning angle concentration parameter, kappa close 1148 | sealHMMwb <- fitHMM(sealPrep, nbState = 2, dist=list(step="weibull", angle="vm"), 1149 | Par0 = list(step=c(mu0,sigma0), angle=kappa0)) 1150 | 1151 | AIC(sealHMM2s,sealHMMwb) # Weibull is better 1152 | plot(sealHMMwb) # Doesn't have a big effect 1153 | sum(abs(viterbi(sealHMM2s) - viterbi(sealHMMwb)))/nrow(sealPrep) # Only 2 different states (< 1% difference) 1154 | 1155 | #### Exponential for step length 1156 | mu0 <- c(2, 1) # Rate - has one less parameters 1157 | kappa0 <- c(0.9, 0.9) # Turning angle concentration parameter, kappa close 1158 | ``` 1159 | 1160 | ```{r message=FALSE, attr.source = ".numberLines", cache=TRUE} 1161 | sealHMMexp <- fitHMM(sealPrep, nbState = 2, 1162 | dist=list(step="exp", angle="vm"), 1163 | Par0 = list(step=c(mu0), angle=kappa0)) 1164 | ``` 1165 | 1166 | ```{r, attr.source = ".numberLines"} 1167 | AIC(sealHMM2s, sealHMMwb,sealHMMexp) # Exponential is worst 1168 | plot(sealHMMexp) # It has a bit more of an effect 1169 | sum(abs(viterbi(sealHMM2s) - viterbi(sealHMMexp)))/nrow(sealPrep) # 4 different states (< 1%) 1170 | ``` 1171 | 1172 | Many of the distributions, including the gamma distribution, are 1173 | strictly positive. This means for example that you cannot have a step 1174 | length of exactly 0 if you simply use the gamma distribution. You can 1175 | however, use a zero-inflated distribution. Such a distribution assumes 1176 | that there is a probability $z$ to observe a 0 and a probability $1-z$ 1177 | to observe a positive value distributed according the the strictly 1178 | positive distribution of your choice (e.g., the gamma). This can be 1179 | achieved by adding a zero-mass starting value for each state in the step 1180 | parameters (see the help page of `fitHMM` under the argument `Par0`). 1181 | 1182 | ## Effects of interpolation {#effect_of_int} 1183 | 1184 | The seal data we are using is not regular, by which we mean that the 1185 | locations are not taken at regular time intervals. As a quick trick we 1186 | regularised the data to 2 hours intervals using linear interpolation, 1187 | but this is likely to affect the analysis. Here, explore the effects of 1188 | using different time intervals. For example, look at the results when 1189 | using 1, 4, 8 hours intervals. Look at both the fit of the model and the 1190 | pseudo residuals. We commented out the plots for space, but do run them 1191 | to visualise the effect of resolution on the data and results. 1192 | 1193 | ```{r, attr.source = ".numberLines", cache=TRUE} 1194 | # Let's try different time intervals 1195 | # 1 hr 1196 | ti1 <- seq(seal$date[1], seal$date[length(seal$date)], by=60*60) 1197 | # 4 hr 1198 | ti4 <- seq(seal$date[1], seal$date[length(seal$date)], by=4*60*60) 1199 | ti8 <- seq(seal$date[1], seal$date[length(seal$date)], by=8*60*60) 1200 | 1201 | # Interpolate the location at the times from the sequence 1202 | iLoc1 <- as.data.frame(cbind(lon=approx(seal$date, seal$lon, 1203 | xout = ti1)$y, 1204 | lat=approx(seal$date, seal$lat, 1205 | xout = ti1)$y)) 1206 | iLoc4 <- as.data.frame(cbind(lon=approx(seal$date, seal$lon, 1207 | xout = ti4)$y, 1208 | lat=approx(seal$date, seal$lat, 1209 | xout = ti4)$y)) 1210 | iLoc8 <- as.data.frame(cbind(lon=approx(seal$date, seal$lon, 1211 | xout = ti8)$y, 1212 | lat=approx(seal$date, seal$lat, 1213 | xout = ti8)$y)) 1214 | 1215 | # Create a new object that has the regular time and interpolated locations 1216 | sealreg1 <- cbind(date=ti1, iLoc1) 1217 | sealreg4 <- cbind(date=ti4, iLoc4) 1218 | sealreg8 <- cbind(date=ti8, iLoc8) 1219 | 1220 | # # Quickly plot the regularized locations 1221 | # plot(seal$lon, seal$lat, 1222 | # pch=19, cex=0.5, xlab="Lon", ylab="Lat", las=1) 1223 | # points(sealreg1$lon, sealreg1$lat, pch=19, cex=0.5, col=rgb(1,0,0,0.5)) 1224 | # points(sealreg$lon, sealreg$lat, pch=19, cex=0.5, 1225 | # col=rgb(0.8,0.8,0.8,0.5)) 1226 | # points(sealreg4$lon, sealreg4$lat, pch=19, cex=0.5, col=rgb(0,0,1,0.5)) 1227 | # points(sealreg8$lon, sealreg8$lat, pch=19, cex=0.5, col=rgb(0,1,1,0.5)) 1228 | 1229 | # Create the prep data 1230 | sealPrep1 <- prepData(sealreg1, type="LL", coordNames = c("lon", "lat")) 1231 | sealPrep4 <- prepData(sealreg4, type="LL", coordNames = c("lon", "lat")) 1232 | sealPrep8 <- prepData(sealreg8, type="LL", coordNames = c("lon", "lat")) 1233 | 1234 | hist(sealPrep1$angle, breaks=40, 1235 | col=rgb(1,0,0,1), freq=FALSE, 1236 | ylim=c(0,2), las=1, border = NA) 1237 | hist(sealPrep$angle, breaks=40, add=TRUE, 1238 | col=rgb(0.8,0.8,0.8,0.8), freq=FALSE, border = NA) 1239 | hist(sealPrep4$angle, breaks=40, add=TRUE, 1240 | col=rgb(0,0,1,0.3), freq=FALSE, border = NA) 1241 | hist(sealPrep8$angle, breaks=40, add=TRUE, 1242 | col=rgb(0,1,1,0.3), freq=FALSE, border = NA) 1243 | 1244 | # None is exactly 0 == surprising... 1245 | sum(sealPrep1$angle == 0, na.rm = TRUE) 1246 | sum(sealPrep$angle == 0, na.rm = TRUE) 1247 | sum(sealPrep4$angle == 0, na.rm = TRUE) 1248 | sum(sealPrep8$angle == 0, na.rm = TRUE) 1249 | 1250 | # Ok let's fit the 3 state HMM again 1251 | # Fit a 3 state HMM 1252 | sealHMM3s1 <- fitHMM(sealPrep1, 1253 | nbState = 3, 1254 | dist=list(step="gamma", angle="vm"), 1255 | Par0 = list(step=c(mu03s, sigma03s), angle=kappa03s)) 1256 | sealHMM3s4 <- fitHMM(sealPrep4, 1257 | nbState = 3, 1258 | dist=list(step="gamma", angle="vm"), 1259 | Par0 = list(step=c(mu03s, sigma03s), angle=kappa03s)) 1260 | sealHMM3s8 <- fitHMM(sealPrep8, 1261 | nbState = 3, 1262 | dist=list(step="gamma", angle="vm"), 1263 | Par0 = list(step=c(mu03s, sigma03s), angle=kappa03s)) 1264 | 1265 | # plot(sealHMM3s1) 1266 | # plot(sealHMM3s) 1267 | # plot(sealHMM3s4) 1268 | # plot(sealHMM3s8) 1269 | # 1270 | # plotPR(sealHMM3s1) 1271 | # plotPR(sealHMM3s) 1272 | # plotPR(sealHMM3s4) 1273 | # plotPR(sealHMM3s8) 1274 | ``` 1275 | 1276 | # Thanks 1277 | 1278 | Thanks to Théo Michelot for input and help! 1279 | -------------------------------------------------------------------------------- /Day1/data/bathy.grd: -------------------------------------------------------------------------------- 1 | [general] 2 | creator=R package 'raster' 3 | created=2018-06-14 15:35:10 4 | [georeference] 5 | nrows=499 6 | ncols=762 7 | xmin=-69.8521784464519 8 | ymin=38.6749821980794 9 | xmax=-57.1758748372396 10 | ymax=46.9674547831218 11 | projection=+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0 12 | [data] 13 | datatype=FLT4S 14 | byteorder=little 15 | nbands=1 16 | bandorder=BIL 17 | categorical=FALSE 18 | minvalue=-5516 19 | maxvalue=1331 20 | nodatavalue=-3.4e+38 21 | [legend] 22 | legendtype= 23 | values= 24 | color= 25 | [description] 26 | layername=layer -------------------------------------------------------------------------------- /Day1/data/bathy.gri: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/Day1/data/bathy.gri -------------------------------------------------------------------------------- /Day1/data/seals.csv: -------------------------------------------------------------------------------- 1 | "date","lon","lat" 2 | 2014-02-18 03:32:08,-60.1675415039063,43.9757690429688 3 | 2014-02-18 15:32:08,-60.1678504943848,43.9757881164551 4 | 2014-02-19 03:32:08,-60.1680107116699,43.9756813049316 5 | 2014-02-19 11:00:07,-60.1703491210938,43.9753189086914 6 | 2014-02-19 12:02:40,-60.203498840332,43.9492797851563 7 | 2014-02-19 13:04:07,-60.2250289916992,43.9156303405762 8 | 2014-02-19 14:05:30,-60.2445182800293,43.8779106140137 9 | 2014-02-19 15:07:54,-60.2536506652832,43.8371200561523 10 | 2014-02-19 16:14:20,-60.2676200866699,43.7959289550781 11 | 2014-02-19 21:27:42,-60.3977584838867,43.6207618713379 12 | 2014-02-19 23:38:06,-60.4555282592773,43.5659294128418 13 | 2014-02-20 00:39:44,-60.4885215759277,43.5500106811523 14 | 2014-02-20 01:44:39,-60.5342483520508,43.5390014648438 15 | 2014-02-20 02:50:54,-60.5792503356934,43.5233116149902 16 | 2014-02-20 03:51:44,-60.6134796142578,43.5051498413086 17 | 2014-02-20 10:06:30,-60.8426208496094,43.3899192810059 18 | 2014-02-20 11:08:04,-60.8900489807129,43.3847007751465 19 | 2014-02-20 12:08:58,-60.9338111877441,43.3768501281738 20 | 2014-02-20 14:11:38,-60.9845695495605,43.3267402648926 21 | 2014-02-20 15:16:28,-60.9902610778809,43.2895393371582 22 | 2014-02-20 19:22:04,-61.0668907165527,43.146800994873 23 | 2014-02-20 23:30:09,-61.3275909423828,43.0878295898438 24 | 2014-02-21 00:32:58,-61.3864898681641,43.1021194458008 25 | 2014-02-21 01:34:46,-61.4532203674316,43.1096687316895 26 | 2014-02-21 02:39:35,-61.5178985595703,43.1182708740234 27 | 2014-02-21 03:44:29,-61.5717582702637,43.122730255127 28 | 2014-02-21 04:49:34,-61.6223182678223,43.1225814819336 29 | 2014-02-21 06:54:55,-61.7154197692871,43.1200408935547 30 | 2014-02-21 07:56:05,-61.7629585266113,43.1241798400879 31 | 2014-02-21 08:58:11,-61.8151702880859,43.122989654541 32 | 2014-02-21 10:00:39,-61.8684310913086,43.1249809265137 33 | 2014-02-21 11:01:19,-61.9205207824707,43.1187705993652 34 | 2014-02-21 14:09:53,-62.0805206298828,43.1309013366699 35 | 2014-02-21 15:10:30,-62.1263313293457,43.1386299133301 36 | 2014-02-21 16:11:43,-62.169750213623,43.141960144043 37 | 2014-02-21 17:11:48,-62.2031288146973,43.1465911865234 38 | 2014-02-21 18:15:55,-62.240550994873,43.1537818908691 39 | 2014-02-21 19:16:00,-62.2737617492676,43.155891418457 40 | 2014-02-21 20:17:00,-62.3254013061523,43.1487197875977 41 | 2014-02-21 22:27:53,-62.4323387145996,43.1405601501465 42 | 2014-02-21 23:27:53,-62.4731292724609,43.1387786865234 43 | 2014-02-22 01:28:55,-62.5349311828613,43.1403503417969 44 | 2014-02-22 02:29:40,-62.5893211364746,43.1455917358398 45 | 2014-02-22 03:30:14,-62.6415481567383,43.1568489074707 46 | 2014-02-22 04:32:09,-62.6869506835938,43.1582298278809 47 | 2014-02-22 05:36:09,-62.7334403991699,43.1604194641113 48 | 2014-02-22 06:41:56,-62.7803802490234,43.1624984741211 49 | 2014-02-22 08:46:26,-62.8734283447266,43.1698188781738 50 | 2014-02-22 09:53:12,-62.9146614074707,43.1864013671875 51 | 2014-02-22 10:53:14,-62.9542808532715,43.1911201477051 52 | 2014-02-22 11:53:14,-62.9943504333496,43.2003517150879 53 | 2014-02-22 13:56:59,-63.0873908996582,43.2175903320313 54 | 2014-02-22 14:57:12,-63.1303405761719,43.2078285217285 55 | 2014-02-22 15:59:56,-63.1773300170898,43.1917610168457 56 | 2014-02-22 18:05:36,-63.2581596374512,43.1554489135742 57 | 2014-02-22 20:14:12,-63.3186912536621,43.1245803833008 58 | 2014-02-22 21:14:11,-63.3424110412598,43.1111297607422 59 | 2014-02-22 23:19:55,-63.4328193664551,43.0820693969727 60 | 2014-02-23 00:20:42,-63.4605407714844,43.0676116943359 61 | 2014-02-23 01:24:22,-63.4928398132324,43.0461807250977 62 | 2014-02-23 03:28:46,-63.5808792114258,43.0067481994629 63 | 2014-02-23 10:46:00,-63.7941017150879,42.8606796264648 64 | 2014-02-23 11:48:46,-63.8207397460938,42.8807907104492 65 | 2014-02-23 12:52:58,-63.8650817871094,42.892219543457 66 | 2014-02-23 13:57:56,-63.9139709472656,42.8980407714844 67 | 2014-02-23 14:59:23,-63.9630088806152,42.8983612060547 68 | 2014-02-23 15:59:28,-64.0103607177734,42.8996086120605 69 | 2014-02-23 17:01:31,-64.0596008300781,42.8933982849121 70 | 2014-02-23 18:06:51,-64.1106109619141,42.8920288085938 71 | 2014-02-23 19:10:19,-64.1539916992188,42.9065208435059 72 | 2014-02-23 21:10:50,-64.2356567382813,42.9092292785645 73 | 2014-02-23 23:12:37,-64.3077774047852,42.8811302185059 74 | 2014-02-24 00:12:40,-64.3437881469727,42.8586883544922 75 | 2014-02-24 01:13:11,-64.3881301879883,42.8400497436523 76 | 2014-02-24 03:16:44,-64.4742965698242,42.8003196716309 77 | 2014-02-24 04:21:39,-64.529670715332,42.785530090332 78 | 2014-02-24 06:21:44,-64.6195373535156,42.7778015136719 79 | 2014-02-24 08:34:12,-64.7227935791016,42.7486114501953 80 | 2014-02-24 09:39:23,-64.7696304321289,42.7323684692383 81 | 2014-02-24 10:46:09,-64.8078384399414,42.7145614624023 82 | 2014-02-24 11:52:39,-64.8435668945313,42.7000885009766 83 | 2014-02-24 12:55:23,-64.8828811645508,42.6822204589844 84 | 2014-02-24 15:01:31,-64.9509429931641,42.6324195861816 85 | 2014-02-24 16:06:32,-64.9746780395508,42.6184005737305 86 | 2014-02-24 17:12:28,-65.0182723999023,42.600170135498 87 | 2014-02-24 18:16:39,-65.0532073974609,42.5890617370605 88 | 2014-02-24 21:22:57,-65.1768569946289,42.5610694885254 89 | 2014-02-24 22:23:00,-65.2126617431641,42.5469207763672 90 | 2014-02-24 23:24:18,-65.2384262084961,42.5234794616699 91 | 2014-02-25 00:24:37,-65.2329483032227,42.492790222168 92 | 2014-02-25 01:26:26,-65.2282562255859,42.4570999145508 93 | 2014-02-25 03:38:20,-65.2742919921875,42.3848304748535 94 | 2014-02-25 04:44:00,-65.3113708496094,42.3486404418945 95 | 2014-02-25 05:47:42,-65.3710021972656,42.3282012939453 96 | 2014-02-25 07:52:45,-65.4395980834961,42.2860298156738 97 | 2014-02-25 09:59:45,-65.5204391479492,42.2618713378906 98 | 2014-02-25 11:01:10,-65.5478515625,42.2421798706055 99 | 2014-02-25 12:04:16,-65.5850219726563,42.2288398742676 100 | 2014-02-25 13:04:21,-65.6298522949219,42.213939666748 101 | 2014-02-25 14:05:35,-65.6668472290039,42.1916694641113 102 | 2014-02-25 15:06:00,-65.6902313232422,42.1718902587891 103 | 2014-02-25 16:13:07,-65.7068786621094,42.1543197631836 104 | 2014-02-25 17:13:13,-65.7373962402344,42.1409683227539 105 | 2014-02-25 20:19:51,-65.8664321899414,42.1434783935547 106 | 2014-02-25 23:21:52,-66.0414962768555,42.2123489379883 107 | 2014-02-26 00:24:43,-66.0617370605469,42.2292785644531 108 | 2014-02-26 01:24:48,-66.0691833496094,42.2390594482422 109 | 2014-02-26 04:26:24,-66.0279998779297,42.2403793334961 110 | 2014-02-26 06:26:51,-66.0214233398438,42.2238883972168 111 | 2014-02-26 08:27:14,-66.0623397827148,42.2094993591309 112 | 2014-02-26 09:28:15,-66.0995788574219,42.199821472168 113 | 2014-02-26 10:28:33,-66.1304016113281,42.1834983825684 114 | 2014-02-26 11:29:00,-66.1504364013672,42.1638717651367 115 | 2014-02-26 12:33:46,-66.1571807861328,42.1404685974121 116 | 2014-02-26 13:39:05,-66.1564331054688,42.11376953125 117 | 2014-02-26 14:39:28,-66.1530990600586,42.0839385986328 118 | 2014-02-26 15:44:54,-66.1493377685547,42.0518112182617 119 | 2014-02-26 16:44:57,-66.1593399047852,42.0392303466797 120 | 2014-02-26 17:45:00,-66.1732635498047,42.0174789428711 121 | 2014-02-26 18:48:48,-66.2029266357422,41.9938812255859 122 | 2014-02-26 19:54:29,-66.2205581665039,41.9822807312012 123 | 2014-02-26 22:02:04,-66.3026504516602,41.9777488708496 124 | 2014-02-26 23:02:04,-66.305419921875,41.9834785461426 125 | 2014-02-27 00:02:59,-66.32470703125,41.9753303527832 126 | 2014-02-27 01:03:31,-66.3317337036133,41.972469329834 127 | 2014-02-27 03:05:47,-66.3102188110352,41.9481391906738 128 | 2014-02-27 04:06:18,-66.3082122802734,41.9112205505371 129 | 2014-02-27 05:06:40,-66.316650390625,41.8748588562012 130 | 2014-02-27 07:14:44,-66.3306274414063,41.8185691833496 131 | 2014-02-27 09:23:51,-66.3972015380859,41.8138885498047 132 | 2014-02-27 10:31:04,-66.4090576171875,41.8277397155762 133 | 2014-02-27 11:32:25,-66.4393997192383,41.8371315002441 134 | 2014-02-27 12:38:13,-66.4575805664063,41.8502006530762 135 | 2014-02-27 13:38:16,-66.4666595458984,41.8600387573242 136 | 2014-02-27 14:38:41,-66.4653625488281,41.8574981689453 137 | 2014-02-27 15:41:23,-66.4673461914063,41.8431205749512 138 | 2014-02-27 17:46:24,-66.4685516357422,41.7901802062988 139 | 2014-02-27 18:49:08,-66.4940414428711,41.7602500915527 140 | 2014-02-27 19:49:12,-66.5478515625,41.7450790405273 141 | 2014-02-27 21:53:40,-66.6481781005859,41.7388305664063 142 | 2014-02-27 22:53:58,-66.6898193359375,41.7473602294922 143 | 2014-02-28 06:00:20,-66.6767807006836,41.7723388671875 144 | 2014-02-28 08:10:52,-66.6077117919922,41.7303695678711 145 | 2014-02-28 09:10:57,-66.5989685058594,41.7378616333008 146 | 2014-02-28 10:11:00,-66.597770690918,41.7598495483398 147 | 2014-02-28 11:11:58,-66.59326171875,41.7825584411621 148 | 2014-02-28 12:11:59,-66.5964431762695,41.810661315918 149 | 2014-02-28 13:12:46,-66.5851669311523,41.8244705200195 150 | 2014-02-28 14:14:45,-66.554557800293,41.8316497802734 151 | 2014-02-28 16:17:21,-66.5056304931641,41.8433799743652 152 | 2014-02-28 17:23:04,-66.4874114990234,41.8391799926758 153 | 2014-02-28 20:35:33,-66.5003280639648,41.8216094970703 154 | 2014-02-28 21:35:36,-66.5141525268555,41.8184814453125 155 | 2014-02-28 23:38:13,-66.5329818725586,41.8546485900879 156 | 2014-03-01 00:38:46,-66.5355911254883,41.8852882385254 157 | 2014-03-01 01:38:52,-66.5253601074219,41.9153709411621 158 | 2014-03-01 02:39:42,-66.4925003051758,41.9297485351563 159 | 2014-03-01 03:39:48,-66.4591064453125,41.9395713806152 160 | 2014-03-01 06:45:33,-66.3456802368164,41.8853797912598 161 | 2014-03-01 07:46:15,-66.3430786132813,41.8518905639648 162 | 2014-03-01 09:51:10,-66.3695602416992,41.8299903869629 163 | 2014-03-01 10:51:35,-66.411003112793,41.8380699157715 164 | 2014-03-01 11:54:40,-66.445442199707,41.84619140625 165 | 2014-03-01 12:55:39,-66.4759979248047,41.8568687438965 166 | 2014-03-01 13:56:10,-66.4906768798828,41.8686599731445 167 | 2014-03-01 15:04:44,-66.4782562255859,41.8808403015137 168 | 2014-03-01 16:51:51,-66.4335479736328,41.8914413452148 169 | 2014-03-01 17:52:33,-66.4114227294922,41.8836517333984 170 | 2014-03-01 18:55:53,-66.3778991699219,41.8701095581055 171 | 2014-03-01 20:02:51,-66.3735961914063,41.8402214050293 172 | 2014-03-01 21:07:06,-66.3896179199219,41.8209686279297 173 | 2014-03-01 22:07:59,-66.4153594970703,41.8219718933105 174 | 2014-03-01 23:08:04,-66.4380874633789,41.8236618041992 175 | 2014-03-02 00:08:09,-66.4404983520508,41.8380889892578 176 | 2014-03-02 01:08:12,-66.4274291992188,41.8640785217285 177 | 2014-03-02 03:10:28,-66.4134521484375,41.9267616271973 178 | 2014-03-02 04:10:32,-66.3817367553711,41.9404182434082 179 | 2014-03-02 05:10:32,-66.3332824707031,41.9359092712402 180 | 2014-03-02 07:11:24,-66.2337188720703,41.9011306762695 181 | 2014-03-02 08:11:28,-66.2222290039063,41.8540000915527 182 | 2014-03-02 09:11:46,-66.2366790771484,41.8219299316406 183 | 2014-03-02 10:12:12,-66.2712936401367,41.8036994934082 184 | 2014-03-02 11:16:16,-66.3206329345703,41.7991905212402 185 | 2014-03-02 13:17:09,-66.4051132202148,41.8042793273926 186 | 2014-03-02 15:17:12,-66.4406890869141,41.846321105957 187 | 2014-03-02 16:21:25,-66.4400024414063,41.8715209960938 188 | 2014-03-02 17:23:04,-66.4401473999023,41.8721618652344 189 | 2014-03-02 19:30:42,-66.4157028198242,41.859130859375 190 | 2014-03-02 20:32:04,-66.4124374389648,41.8485794067383 191 | 2014-03-03 02:34:50,-66.5234527587891,41.8746185302734 192 | 2014-03-03 03:34:56,-66.4965362548828,41.8910789489746 193 | 2014-03-03 04:36:36,-66.456787109375,41.9117202758789 194 | 2014-03-03 05:36:37,-66.406867980957,41.9325714111328 195 | 2014-03-03 06:39:21,-66.3520126342773,41.9295082092285 196 | 2014-03-03 08:43:46,-66.2671432495117,41.8687591552734 197 | 2014-03-03 09:48:18,-66.249397277832,41.8368110656738 198 | 2014-03-03 10:53:12,-66.2573318481445,41.8340492248535 199 | 2014-03-03 11:53:16,-66.2940521240234,41.8311195373535 200 | 2014-03-03 13:55:13,-66.3498229980469,41.8574485778809 201 | 2014-03-03 14:55:49,-66.3833389282227,41.8797988891602 202 | 2014-03-03 15:58:32,-66.4177780151367,41.9118194580078 203 | 2014-03-03 18:03:41,-66.4224014282227,41.9297294616699 204 | 2014-03-03 19:05:10,-66.3909530639648,41.9220085144043 205 | 2014-03-03 23:15:33,-66.3383331298828,41.8703002929688 206 | 2014-03-04 02:19:12,-66.3858795166016,41.8796691894531 207 | 2014-03-04 03:19:17,-66.3824081420898,41.9100112915039 208 | 2014-03-04 04:21:31,-66.3732299804688,41.9276885986328 209 | 2014-03-04 05:23:16,-66.3432769775391,41.9241714477539 210 | 2014-03-04 06:24:12,-66.2980804443359,41.9266204833984 211 | 2014-03-04 09:24:34,-66.1940612792969,41.884090423584 212 | 2014-03-04 10:25:58,-66.1782073974609,41.864860534668 213 | 2014-03-04 11:30:33,-66.1765899658203,41.8491287231445 214 | 2014-03-04 12:32:45,-66.2001113891602,41.8257102966309 215 | 2014-03-04 13:32:45,-66.2338409423828,41.8257904052734 216 | 2014-03-04 14:33:57,-66.2672424316406,41.8297805786133 217 | 2014-03-04 15:40:57,-66.3031616210938,41.8313903808594 218 | 2014-03-04 17:43:59,-66.3415298461914,41.8512916564941 219 | 2014-03-04 18:45:39,-66.3243026733398,41.8630599975586 220 | 2014-03-04 20:49:55,-66.2717437744141,41.8678398132324 221 | 2014-03-04 21:50:00,-66.2438507080078,41.8664398193359 222 | 2014-03-04 22:50:00,-66.2345962524414,41.8460998535156 223 | 2014-03-04 23:53:23,-66.2253036499023,41.8344306945801 224 | 2014-03-05 03:57:05,-66.3391723632813,41.8545303344727 225 | 2014-03-05 05:01:26,-66.3557510375977,41.8551902770996 226 | 2014-03-05 06:01:53,-66.3497772216797,41.8518905639648 227 | 2014-03-05 09:07:25,-66.2400665283203,41.8230094909668 228 | 2014-03-05 11:12:42,-66.203498840332,41.7617301940918 229 | 2014-03-05 12:13:47,-66.2369689941406,41.7272605895996 230 | 2014-03-05 13:17:30,-66.286979675293,41.705940246582 231 | 2014-03-05 14:17:43,-66.3441619873047,41.7067184448242 232 | 2014-03-05 15:21:41,-66.3677368164063,41.7303695678711 233 | 2014-03-05 16:22:12,-66.3848114013672,41.7467918395996 234 | 2014-03-05 17:22:13,-66.3727416992188,41.7688217163086 235 | 2014-03-05 18:24:16,-66.390869140625,41.7830009460449 236 | 2014-03-05 19:26:34,-66.3895797729492,41.7871513366699 237 | 2014-03-05 20:29:04,-66.3851699829102,41.7853088378906 238 | 2014-03-05 21:32:44,-66.3615493774414,41.7672080993652 239 | 2014-03-05 22:34:39,-66.3691711425781,41.741870880127 240 | 2014-03-05 23:37:49,-66.3809509277344,41.7058982849121 241 | 2014-03-06 03:40:38,-66.4213485717773,41.6666488647461 242 | 2014-03-06 04:41:09,-66.456298828125,41.6782417297363 243 | 2014-03-06 05:46:30,-66.4421234130859,41.6965789794922 244 | 2014-03-06 06:52:05,-66.4316101074219,41.7263488769531 245 | 2014-03-06 07:52:08,-66.3975372314453,41.7435188293457 246 | 2014-03-06 10:00:22,-66.3308563232422,41.7361793518066 247 | 2014-03-06 11:03:29,-66.3452529907227,41.7313690185547 248 | 2014-03-06 15:06:37,-66.4409637451172,41.7308883666992 249 | 2014-03-06 16:08:42,-66.443962097168,41.751148223877 250 | 2014-03-06 17:08:55,-66.4352416992188,41.7739906311035 251 | 2014-03-06 18:14:36,-66.4386901855469,41.7923316955566 252 | 2014-03-06 21:16:11,-66.4762191772461,41.8047103881836 253 | 2014-03-06 23:18:53,-66.4688415527344,41.8095588684082 254 | 2014-03-07 01:22:42,-66.4500885009766,41.8075485229492 255 | 2014-03-07 02:22:48,-66.4624786376953,41.8054084777832 256 | 2014-03-07 03:27:36,-66.4726028442383,41.826099395752 257 | 2014-03-07 04:30:53,-66.4598770141602,41.8437309265137 258 | 2014-03-07 05:30:56,-66.4454879760742,41.8690795898438 259 | 2014-03-07 06:30:59,-66.4253692626953,41.8892784118652 260 | 2014-03-07 08:32:52,-66.4065399169922,41.9289817810059 261 | 2014-03-07 11:36:15,-66.3897094726563,41.9789009094238 262 | 2014-03-07 12:40:14,-66.3886566162109,41.9798583984375 263 | 2014-03-07 13:40:20,-66.3914413452148,41.9822387695313 264 | 2014-03-07 14:43:04,-66.3992462158203,41.9920387268066 265 | 2014-03-07 15:46:08,-66.4062576293945,42.0165214538574 266 | 2014-03-07 16:46:12,-66.4104690551758,42.0399208068848 267 | 2014-03-07 18:48:32,-66.4045867919922,42.1007614135742 268 | 2014-03-07 20:52:29,-66.3635101318359,42.1841201782227 269 | 2014-03-07 21:52:32,-66.3147506713867,42.2247085571289 270 | 2014-03-07 22:54:57,-66.2777786254883,42.246410369873 271 | 2014-03-07 23:55:25,-66.2669982910156,42.2690391540527 272 | 2014-03-08 00:58:11,-66.265251159668,42.2932090759277 273 | 2014-03-08 02:02:11,-66.2688217163086,42.3193702697754 274 | 2014-03-08 03:08:56,-66.2751998901367,42.3540687561035 275 | 2014-03-08 04:13:09,-66.2833404541016,42.3811988830566 276 | 2014-03-08 05:16:29,-66.2900924682617,42.411018371582 277 | 2014-03-08 07:18:30,-66.306022644043,42.4709587097168 278 | 2014-03-08 08:19:10,-66.312141418457,42.4953002929688 279 | 2014-03-08 10:27:29,-66.2874221801758,42.5416793823242 280 | 2014-03-08 12:28:52,-66.2559204101563,42.5474395751953 281 | 2014-03-08 13:32:35,-66.2616806030273,42.5566291809082 282 | 2014-03-08 14:32:49,-66.2801208496094,42.5773696899414 283 | 2014-03-08 15:32:52,-66.2878875732422,42.6055297851563 284 | 2014-03-08 16:34:06,-66.2861785888672,42.6358795166016 285 | 2014-03-08 17:36:54,-66.2751007080078,42.6774482727051 286 | 2014-03-08 18:39:00,-66.2616424560547,42.7099494934082 287 | 2014-03-08 21:46:58,-66.2158889770508,42.8342514038086 288 | 2014-03-09 00:50:51,-66.1405334472656,42.910888671875 289 | 2014-03-09 01:55:07,-66.1178970336914,42.9314498901367 290 | 2014-03-09 02:55:50,-66.1024169921875,42.9502105712891 291 | 2014-03-09 03:57:23,-66.0984725952148,42.9736404418945 292 | 2014-03-09 05:03:00,-66.0969467163086,42.9938888549805 293 | 2014-03-09 09:12:06,-66.1147384643555,43.1446113586426 294 | 2014-03-09 10:12:12,-66.0935592651367,43.1786308288574 295 | 2014-03-09 11:13:04,-66.0550918579102,43.2109718322754 296 | 2014-03-09 12:13:13,-66.0091934204102,43.2401885986328 297 | 2014-03-09 13:13:21,-65.9849319458008,43.2747611999512 298 | 2014-03-09 14:15:27,-65.976188659668,43.3183212280273 299 | 2014-03-09 15:15:42,-65.9868927001953,43.3578987121582 300 | 2014-03-09 17:17:05,-66.0408935546875,43.4135818481445 301 | 2014-03-09 18:17:06,-66.0435104370117,43.4582786560059 302 | 2014-03-09 19:17:42,-66.0268478393555,43.5063896179199 303 | 2014-03-09 20:17:48,-66.0077590942383,43.5050392150879 304 | 2014-03-10 08:17:48,-66.007926940918,43.5048217773438 305 | 2014-03-10 20:17:48,-66.0077514648438,43.5048904418945 306 | 2014-03-11 08:03:04,-66.0113677978516,43.504768371582 307 | 2014-03-11 09:06:42,-66.0707321166992,43.5102310180664 308 | 2014-03-11 10:10:09,-66.1294326782227,43.5191802978516 309 | 2014-03-11 11:11:48,-66.1911087036133,43.5127410888672 310 | 2014-03-11 12:12:38,-66.2472381591797,43.499568939209 311 | 2014-03-11 13:15:35,-66.3031921386719,43.4843902587891 312 | 2014-03-11 14:15:36,-66.3430480957031,43.4470901489258 313 | 2014-03-11 17:22:18,-66.4512023925781,43.3196105957031 314 | 2014-03-11 18:27:15,-66.4982528686523,43.2820091247559 315 | 2014-03-11 19:29:12,-66.543701171875,43.2527885437012 316 | 2014-03-11 21:34:42,-66.629280090332,43.214111328125 317 | 2014-03-11 22:40:13,-66.6536483764648,43.1937217712402 318 | 2014-03-11 23:46:30,-66.6819534301758,43.1777305603027 319 | 2014-03-12 01:56:27,-66.7158889770508,43.1239891052246 320 | 2014-03-12 03:59:47,-66.7416076660156,43.0896186828613 321 | 2014-03-12 05:05:32,-66.7640533447266,43.068359375 322 | 2014-03-12 06:10:38,-66.7557067871094,43.0421905517578 323 | 2014-03-12 07:12:04,-66.7528762817383,43.0177192687988 324 | 2014-03-12 08:19:00,-66.7592697143555,42.9945106506348 325 | 2014-03-12 09:19:46,-66.7751007080078,42.9773292541504 326 | 2014-03-12 10:20:30,-66.7827606201172,42.9606094360352 327 | 2014-03-12 11:23:31,-66.7931594848633,42.9391403198242 328 | 2014-03-12 12:29:24,-66.7992935180664,42.917179107666 329 | 2014-03-12 14:34:41,-66.7983093261719,42.8636894226074 330 | 2014-03-12 15:34:44,-66.7945175170898,42.8352088928223 331 | 2014-03-12 16:39:37,-66.7822723388672,42.8070983886719 332 | 2014-03-12 17:47:21,-66.7671890258789,42.7778816223145 333 | 2014-03-12 18:50:44,-66.7615814208984,42.7642593383789 334 | 2014-03-12 19:52:50,-66.7453765869141,42.7675285339355 335 | 2014-03-12 20:53:59,-66.7329483032227,42.759220123291 336 | 2014-03-12 21:55:29,-66.7200469970703,42.7634201049805 337 | 2014-03-12 22:58:38,-66.7193984985352,42.7581596374512 338 | 2014-03-13 01:03:05,-66.737419128418,42.753101348877 339 | 2014-03-13 02:04:00,-66.717041015625,42.7337188720703 340 | 2014-03-13 03:05:51,-66.6930236816406,42.716609954834 341 | 2014-03-13 07:17:49,-66.6443710327148,42.6006889343262 342 | 2014-03-13 10:19:56,-66.6457595825195,42.5416297912598 343 | 2014-03-13 11:25:04,-66.6572189331055,42.555980682373 344 | 2014-03-13 12:25:04,-66.6765594482422,42.5537796020508 345 | 2014-03-13 13:25:04,-66.6747970581055,42.5386390686035 346 | 2014-03-13 14:27:04,-66.6876373291016,42.5324592590332 347 | 2014-03-13 17:28:39,-66.6751327514648,42.500171661377 348 | 2014-03-13 19:32:55,-66.657958984375,42.5233612060547 349 | 2014-03-13 20:33:32,-66.6535797119141,42.5380096435547 350 | 2014-03-13 22:36:59,-66.6369934082031,42.5733604431152 351 | 2014-03-14 00:43:11,-66.6603393554688,42.5884399414063 352 | 2014-03-14 04:50:04,-66.6587600708008,42.5420608520508 353 | 2014-03-14 05:53:04,-66.6635513305664,42.5202789306641 354 | 2014-03-14 06:53:04,-66.6797027587891,42.5161895751953 355 | 2014-03-14 07:57:26,-66.7047882080078,42.5173416137695 356 | 2014-03-14 12:10:39,-66.828727722168,42.5484199523926 357 | 2014-03-14 14:12:13,-66.8605117797852,42.5487518310547 358 | 2014-03-14 15:13:21,-66.844970703125,42.5365600585938 359 | 2014-03-14 16:14:23,-66.830322265625,42.5307083129883 360 | 2014-03-14 17:14:28,-66.8265686035156,42.535831451416 361 | 2014-03-14 18:15:04,-66.8135833740234,42.53955078125 362 | 2014-03-14 19:21:11,-66.8029403686523,42.546989440918 363 | 2014-03-14 22:30:29,-66.779411315918,42.5843200683594 364 | 2014-03-14 23:30:30,-66.7766571044922,42.6048583984375 365 | 2014-03-15 00:32:04,-66.7750396728516,42.619270324707 366 | 2014-03-15 01:33:04,-66.7701034545898,42.6281204223633 367 | 2014-03-15 02:38:26,-66.7453994750977,42.6220207214355 368 | 2014-03-15 03:39:43,-66.7279281616211,42.6049194335938 369 | 2014-03-15 06:46:15,-66.6325607299805,42.5211181640625 370 | 2014-03-15 07:48:38,-66.6045532226563,42.5112991333008 371 | 2014-03-15 08:51:41,-66.6008605957031,42.5105590820313 372 | 2014-03-15 09:54:30,-66.5931396484375,42.5223808288574 373 | 2014-03-15 11:55:54,-66.6462707519531,42.5457801818848 374 | 2014-03-15 14:59:17,-66.6907501220703,42.5522804260254 375 | 2014-03-15 18:04:45,-66.6393280029297,42.5403518676758 376 | 2014-03-15 19:04:46,-66.6079483032227,42.5339202880859 377 | 2014-03-15 20:05:46,-66.5715408325195,42.5329284667969 378 | 2014-03-15 21:08:00,-66.5424423217773,42.5366897583008 379 | 2014-03-16 00:12:38,-66.5511474609375,42.5824089050293 380 | 2014-03-16 01:16:10,-66.5737991333008,42.5995597839355 381 | 2014-03-16 03:21:54,-66.5942535400391,42.6138305664063 382 | 2014-03-16 04:22:08,-66.5849990844727,42.5986785888672 383 | 2014-03-16 05:22:09,-66.5817337036133,42.5864601135254 384 | 2014-03-16 08:25:31,-66.5327224731445,42.5267181396484 385 | 2014-03-16 09:27:10,-66.5232620239258,42.5161590576172 386 | 2014-03-16 10:29:31,-66.5164337158203,42.5150108337402 387 | 2014-03-16 13:29:46,-66.5446395874023,42.5196189880371 388 | 2014-03-16 14:30:22,-66.5523223876953,42.5138893127441 389 | 2014-03-16 16:30:23,-66.5350723266602,42.5029106140137 390 | 2014-03-16 17:30:28,-66.5175628662109,42.493091583252 391 | 2014-03-16 18:32:47,-66.4850463867188,42.5033798217773 392 | 2014-03-16 19:32:52,-66.4506301879883,42.5064697265625 393 | 2014-03-16 21:33:09,-66.4038467407227,42.5088691711426 394 | 2014-03-16 23:36:49,-66.4191665649414,42.5464401245117 395 | 2014-03-17 01:36:50,-66.4727096557617,42.5875587463379 396 | 2014-03-17 03:40:50,-66.5107421875,42.6231307983398 397 | 2014-03-17 04:40:52,-66.5237426757813,42.6198310852051 398 | 2014-03-17 05:41:30,-66.5369186401367,42.600959777832 399 | 2014-03-17 06:43:51,-66.5420227050781,42.5710105895996 400 | 2014-03-17 08:52:42,-66.5433502197266,42.520320892334 401 | 2014-03-17 10:54:16,-66.5733337402344,42.513729095459 402 | 2014-03-17 12:00:39,-66.6072311401367,42.5289192199707 403 | 2014-03-17 13:05:45,-66.642822265625,42.527889251709 404 | 2014-03-17 14:07:40,-66.6515808105469,42.5108299255371 405 | 2014-03-17 15:16:12,-66.6509628295898,42.5089302062988 406 | 2014-03-17 18:17:16,-66.5912628173828,42.5042610168457 407 | 2014-03-17 20:19:12,-66.5239562988281,42.4908790588379 408 | 2014-03-17 23:19:22,-66.4628601074219,42.4978790283203 409 | 2014-03-18 00:19:26,-66.4787216186523,42.5079917907715 410 | 2014-03-18 03:20:07,-66.5380783081055,42.5511512756348 411 | 2014-03-18 05:24:53,-66.5422668457031,42.5354499816895 412 | 2014-03-18 06:32:49,-66.5327301025391,42.512378692627 413 | 2014-03-18 08:40:27,-66.4854431152344,42.4927597045898 414 | 2014-03-18 11:46:17,-66.4532699584961,42.4815483093262 415 | 2014-03-18 14:54:07,-66.5419235229492,42.4866790771484 416 | 2014-03-18 16:59:07,-66.5598983764648,42.4892196655273 417 | 2014-03-18 18:03:18,-66.5649490356445,42.4699287414551 418 | 2014-03-18 19:13:20,-66.5472564697266,42.4581108093262 419 | 2014-03-18 20:21:20,-66.523567199707,42.439640045166 420 | 2014-03-18 21:21:24,-66.4935913085938,42.4346618652344 421 | 2014-03-18 22:21:46,-66.4660873413086,42.4362602233887 422 | 2014-03-18 23:25:25,-66.4600830078125,42.4383087158203 423 | 2014-03-19 00:26:36,-66.4628982543945,42.4420013427734 424 | 2014-03-19 01:29:04,-66.4740524291992,42.4381484985352 425 | 2014-03-19 04:40:59,-66.5576095581055,42.4057388305664 426 | 2014-03-19 06:42:30,-66.5512619018555,42.3696594238281 427 | 2014-03-19 09:51:20,-66.4588165283203,42.3096199035645 428 | 2014-03-19 13:13:15,-66.4714431762695,42.306339263916 429 | 2014-03-19 16:24:37,-66.5824432373047,42.339168548584 430 | 2014-03-19 18:26:04,-66.6110763549805,42.3819999694824 431 | 2014-03-19 20:44:40,-66.563591003418,42.4159889221191 432 | 2014-03-19 22:44:44,-66.5090484619141,42.4460983276367 433 | 2014-03-19 23:44:50,-66.4902496337891,42.460090637207 434 | 2014-03-20 00:53:26,-66.4797821044922,42.4773902893066 435 | 2014-03-20 01:54:38,-66.4766387939453,42.4914207458496 436 | 2014-03-20 02:56:12,-66.4833374023438,42.5061416625977 437 | 2014-03-20 03:56:16,-66.4890365600586,42.5251007080078 438 | 2014-03-20 06:04:44,-66.5259780883789,42.5495300292969 439 | 2014-03-20 07:04:46,-66.5055694580078,42.5410194396973 440 | 2014-03-20 08:07:59,-66.4812622070313,42.5414810180664 441 | 2014-03-20 10:22:05,-66.4055404663086,42.5199584960938 442 | 2014-03-20 11:23:43,-66.3849868774414,42.513729095459 443 | 2014-03-20 12:23:46,-66.3756103515625,42.5237503051758 444 | 2014-03-20 15:26:36,-66.449592590332,42.5710792541504 445 | 2014-03-20 16:30:04,-66.4717178344727,42.584831237793 446 | 2014-03-20 20:45:56,-66.4187622070313,42.5330390930176 447 | 2014-03-20 23:53:21,-66.3545913696289,42.500659942627 448 | 2014-03-21 01:55:48,-66.3874969482422,42.4983711242676 449 | 2014-03-21 04:57:27,-66.4865417480469,42.5498695373535 450 | 2014-03-21 05:57:34,-66.5059509277344,42.5634918212891 451 | 2014-03-21 07:01:37,-66.5050201416016,42.5554504394531 452 | 2014-03-21 08:10:26,-66.4961471557617,42.5377616882324 453 | 2014-03-21 09:17:37,-66.471076965332,42.5128517150879 454 | 2014-03-21 10:22:21,-66.4316329956055,42.4929695129395 455 | 2014-03-21 11:22:24,-66.4011917114258,42.4911613464355 456 | 2014-03-21 12:22:24,-66.3796691894531,42.4873008728027 457 | 2014-03-21 14:26:05,-66.4200134277344,42.48583984375 458 | 2014-03-21 15:27:51,-66.4417724609375,42.5061416625977 459 | 2014-03-21 16:30:24,-66.4667892456055,42.5253295898438 460 | 2014-03-21 17:35:09,-66.4944686889648,42.5426597595215 461 | 2014-03-21 19:41:56,-66.5073013305664,42.5297508239746 462 | 2014-03-21 20:41:56,-66.4891204833984,42.5206489562988 463 | 2014-03-21 23:50:34,-66.4159927368164,42.5258102416992 464 | 2014-03-22 01:50:41,-66.4164123535156,42.5178985595703 465 | 2014-03-22 02:51:48,-66.4341278076172,42.5208511352539 466 | 2014-03-22 07:00:07,-66.537483215332,42.557201385498 467 | 2014-03-22 08:04:56,-66.5489883422852,42.5474586486816 468 | 2014-03-22 09:05:00,-66.5456008911133,42.5288887023926 469 | 2014-03-22 10:14:16,-66.5221786499023,42.513069152832 470 | 2014-03-22 11:14:21,-66.4931106567383,42.5122299194336 471 | 2014-03-22 13:15:35,-66.4590377807617,42.5244102478027 472 | 2014-03-22 14:19:04,-66.4826126098633,42.5336494445801 473 | 2014-03-22 16:19:36,-66.5151977539063,42.563159942627 474 | 2014-03-22 19:23:22,-66.5438613891602,42.6050910949707 475 | 2014-03-22 20:24:36,-66.5428466796875,42.6228904724121 476 | 2014-03-22 23:28:33,-66.4767303466797,42.7019805908203 477 | 2014-03-23 00:28:57,-66.4418334960938,42.7164306640625 478 | 2014-03-23 01:29:53,-66.4032363891602,42.7388000488281 479 | 2014-03-23 02:30:54,-66.3818893432617,42.7511291503906 480 | 2014-03-23 03:31:06,-66.3774719238281,42.7628288269043 481 | 2014-03-23 05:36:47,-66.3644180297852,42.8162384033203 482 | 2014-03-23 08:41:25,-66.3245086669922,42.8274688720703 483 | 2014-03-23 09:44:57,-66.3008804321289,42.8545417785645 484 | 2014-03-23 10:47:05,-66.2809295654297,42.8759117126465 485 | 2014-03-23 11:47:09,-66.2565612792969,42.8874893188477 486 | 2014-03-23 12:47:33,-66.2292175292969,42.9006881713867 487 | 2014-03-23 13:47:35,-66.2004928588867,42.9129104614258 488 | 2014-03-23 14:48:57,-66.1824798583984,42.9334716796875 489 | 2014-03-23 15:49:00,-66.1861572265625,42.9694290161133 490 | 2014-03-23 16:51:27,-66.1911926269531,43.0107002258301 491 | 2014-03-23 18:56:05,-66.2030715942383,43.0953903198242 492 | 2014-03-23 19:58:27,-66.2048110961914,43.1451683044434 493 | 2014-03-23 21:01:04,-66.1954193115234,43.1907615661621 494 | 2014-03-23 22:03:32,-66.1588897705078,43.225269317627 495 | 2014-03-23 23:03:33,-66.1100311279297,43.2487297058105 496 | 2014-03-24 00:06:57,-66.0567779541016,43.2591285705566 497 | 2014-03-24 01:10:29,-66.0204391479492,43.2763404846191 498 | 2014-03-24 02:10:32,-66.0033493041992,43.3075714111328 499 | 2014-03-24 04:14:50,-66.0322570800781,43.3981399536133 500 | 2014-03-24 05:14:50,-66.0266723632813,43.4243392944336 501 | 2014-03-24 06:17:45,-66.0271377563477,43.464729309082 502 | 2014-03-24 07:20:26,-66.0045928955078,43.4933090209961 503 | 2014-03-25 08:20:32,-66.0083465576172,43.5047302246094 504 | 2014-03-25 13:18:08,-66.0086822509766,43.5033912658691 505 | 2014-03-25 14:18:52,-66.0335235595703,43.4842681884766 506 | 2014-03-25 15:23:45,-66.0698776245117,43.4524116516113 507 | 2014-03-25 16:28:24,-66.1076431274414,43.4163818359375 508 | 2014-03-25 17:31:41,-66.1584320068359,43.3917198181152 509 | 2014-03-25 19:43:22,-66.270751953125,43.3606109619141 510 | 2014-03-25 21:47:32,-66.3533020019531,43.3315582275391 511 | 2014-03-25 22:51:04,-66.3767318725586,43.3035583496094 512 | 2014-03-25 23:54:18,-66.3894805908203,43.266960144043 513 | 2014-03-26 00:54:47,-66.4004516601563,43.2280693054199 514 | 2014-03-26 01:54:52,-66.4024505615234,43.1844215393066 515 | 2014-03-26 02:56:23,-66.4096603393555,43.1446800231934 516 | 2014-03-26 04:00:19,-66.4109802246094,43.1117210388184 517 | 2014-03-26 05:06:52,-66.4167709350586,43.0841102600098 518 | 2014-03-26 07:19:46,-66.4372482299805,43.0390586853027 519 | 2014-03-26 08:24:39,-66.4592514038086,43.0263595581055 520 | 2014-03-26 10:36:04,-66.472541809082,42.9726104736328 521 | 2014-03-26 11:39:05,-66.4802474975586,42.938060760498 522 | 2014-03-26 12:39:49,-66.4846496582031,42.9032402038574 523 | 2014-03-26 13:39:49,-66.4835433959961,42.869571685791 524 | 2014-03-26 14:39:49,-66.4750213623047,42.856258392334 525 | 2014-03-26 15:41:54,-66.4749526977539,42.8450698852539 526 | 2014-03-26 17:48:21,-66.4689025878906,42.8081512451172 527 | 2014-03-26 20:55:09,-66.4930572509766,42.7645683288574 528 | 2014-03-26 21:55:12,-66.4862213134766,42.7667617797852 529 | 2014-03-26 22:57:10,-66.4856414794922,42.7572402954102 530 | 2014-03-27 01:02:28,-66.4674911499023,42.7387084960938 531 | 2014-03-27 03:04:56,-66.4294967651367,42.6913681030273 532 | 2014-03-27 06:11:18,-66.3688507080078,42.6209182739258 533 | 2014-03-27 07:17:13,-66.3665237426758,42.6034698486328 534 | 2014-03-27 08:17:58,-66.3800506591797,42.5882110595703 535 | 2014-03-27 09:19:26,-66.3977203369141,42.5706481933594 536 | 2014-03-27 10:19:32,-66.4270629882813,42.5553283691406 537 | 2014-03-27 11:26:35,-66.4399185180664,42.5337600708008 538 | 2014-03-27 12:26:40,-66.4347381591797,42.5128898620605 539 | 2014-03-27 13:34:08,-66.4266662597656,42.4877815246582 540 | 2014-03-27 14:39:22,-66.3937225341797,42.4633483886719 541 | 2014-03-27 15:43:14,-66.383186340332,42.4336814880371 542 | 2014-03-27 21:01:35,-66.3262481689453,42.4419212341309 543 | 2014-03-27 22:03:58,-66.373420715332,42.467700958252 544 | 2014-03-27 23:05:18,-66.4225082397461,42.4953918457031 545 | 2014-03-28 00:06:59,-66.4534912109375,42.5174407958984 546 | 2014-03-28 01:14:43,-66.4667663574219,42.5329895019531 547 | 2014-03-28 02:17:14,-66.4646987915039,42.5406188964844 548 | 2014-03-28 03:23:28,-66.4449462890625,42.5486717224121 549 | 2014-03-28 04:26:46,-66.4398193359375,42.5449104309082 550 | 2014-03-28 05:27:19,-66.4343719482422,42.5149116516113 551 | 2014-03-28 06:33:10,-66.4406280517578,42.4891700744629 552 | 2014-03-28 07:39:56,-66.4673004150391,42.468391418457 553 | 2014-03-28 09:52:15,-66.5511093139648,42.4580307006836 554 | 2014-03-28 10:56:27,-66.5905914306641,42.4574089050293 555 | 2014-03-28 12:00:14,-66.6362609863281,42.4643096923828 556 | 2014-03-28 13:03:24,-66.6938095092773,42.4736595153809 557 | 2014-03-28 17:06:06,-66.7465972900391,42.5107917785645 558 | 2014-03-28 21:17:22,-66.7301635742188,42.5743103027344 559 | 2014-03-29 00:25:24,-66.7617492675781,42.6344299316406 560 | 2014-03-29 01:26:15,-66.7729797363281,42.6401786804199 561 | 2014-03-29 02:32:24,-66.7770233154297,42.6293487548828 562 | 2014-03-29 03:33:33,-66.7842483520508,42.6046104431152 563 | 2014-03-29 04:39:29,-66.7734985351563,42.5706214904785 564 | 2014-03-29 05:47:27,-66.7555770874023,42.5390586853027 565 | 2014-03-29 07:49:21,-66.7402191162109,42.5195388793945 566 | 2014-03-29 09:53:48,-66.7604904174805,42.5415191650391 567 | 2014-03-29 10:54:43,-66.7739410400391,42.5612983703613 568 | 2014-03-29 11:55:58,-66.7956314086914,42.5621109008789 569 | 2014-03-29 13:58:44,-66.8058929443359,42.5289916992188 570 | 2014-03-29 15:02:56,-66.7978210449219,42.5151405334473 571 | 2014-03-29 16:03:00,-66.7751007080078,42.4987182617188 572 | 2014-03-29 17:04:10,-66.7352066040039,42.4984512329102 573 | 2014-03-29 20:13:59,-66.6720886230469,42.4865989685059 574 | 2014-03-29 23:28:27,-66.7120208740234,42.5177383422852 575 | 2014-03-30 00:34:58,-66.7082595825195,42.5299987792969 576 | 2014-03-30 01:35:30,-66.7069473266602,42.5255889892578 577 | 2014-03-30 02:35:33,-66.7056884765625,42.5114707946777 578 | 2014-03-30 03:35:36,-66.685546875,42.5054817199707 579 | 2014-03-30 04:35:36,-66.6574935913086,42.4984397888184 580 | 2014-03-30 05:40:39,-66.6261215209961,42.4838905334473 581 | 2014-03-30 09:51:13,-66.5473785400391,42.4657402038574 582 | 2014-03-30 10:51:16,-66.550407409668,42.4766807556152 583 | 2014-03-30 11:55:48,-66.595817565918,42.4770698547363 584 | 2014-03-30 12:57:49,-66.6331481933594,42.4890213012695 585 | 2014-03-30 13:59:45,-66.6443023681641,42.5136795043945 586 | 2014-03-30 15:07:19,-66.6425476074219,42.5265083312988 587 | 2014-03-30 16:08:16,-66.6245269775391,42.5337181091309 588 | 2014-03-30 18:14:24,-66.5577011108398,42.5299110412598 589 | 2014-03-30 19:14:28,-66.513786315918,42.5353088378906 590 | 2014-03-30 22:17:04,-66.4886703491211,42.5477981567383 591 | 2014-03-30 23:17:04,-66.5135803222656,42.5681686401367 592 | 2014-03-31 00:20:56,-66.5387725830078,42.5905914306641 593 | 2014-03-31 01:21:00,-66.5693283081055,42.6079216003418 594 | 2014-03-31 03:23:48,-66.6140899658203,42.6452293395996 595 | 2014-03-31 05:31:39,-66.5952682495117,42.6184692382813 596 | 2014-03-31 06:32:08,-66.5691680908203,42.5928382873535 597 | 2014-03-31 07:34:46,-66.5526885986328,42.5598411560059 598 | 2014-03-31 10:47:26,-66.5596694946289,42.5205116271973 599 | 2014-03-31 11:50:51,-66.5790481567383,42.5421714782715 600 | 2014-03-31 12:50:56,-66.6156997680664,42.5555000305176 601 | 2014-03-31 15:00:17,-66.6616821289063,42.5822486877441 602 | 2014-03-31 17:00:21,-66.657356262207,42.5726890563965 603 | 2014-03-31 19:00:28,-66.6555633544922,42.5627708435059 604 | 2014-03-31 21:04:32,-66.6360321044922,42.5653495788574 605 | 2014-03-31 22:06:36,-66.6515808105469,42.564811706543 606 | 2014-04-01 00:06:48,-66.6975173950195,42.5909996032715 607 | 2014-04-01 01:06:48,-66.718620300293,42.6029281616211 608 | 2014-04-01 02:06:52,-66.7417984008789,42.6130714416504 609 | 2014-04-01 04:06:54,-66.7799911499023,42.6118202209473 610 | 2014-04-01 05:11:04,-66.7929306030273,42.6011505126953 611 | 2014-04-01 06:15:14,-66.8158569335938,42.592098236084 612 | 2014-04-01 11:30:49,-66.7959976196289,42.5603790283203 613 | 2014-04-01 16:39:46,-66.8376922607422,42.5803413391113 614 | 2014-04-01 19:45:04,-66.7559661865234,42.5513687133789 615 | 2014-04-01 20:52:31,-66.7179107666016,42.5291595458984 616 | 2014-04-01 21:52:37,-66.6853332519531,42.518310546875 617 | 2014-04-01 22:55:13,-66.6652374267578,42.5142211914063 618 | 2014-04-01 23:56:04,-66.6466522216797,42.5228500366211 619 | 2014-04-02 00:59:04,-66.6595993041992,42.5250701904297 620 | 2014-04-02 04:06:04,-66.6750793457031,42.5106391906738 621 | 2014-04-02 06:11:08,-66.6526336669922,42.4819793701172 622 | 2014-04-02 07:17:51,-66.6201019287109,42.465461730957 623 | 2014-04-02 08:25:46,-66.5784378051758,42.4577102661133 624 | 2014-04-02 09:29:31,-66.5353164672852,42.450870513916 625 | 2014-04-02 10:35:19,-66.4901580810547,42.4537200927734 626 | 2014-04-02 11:38:11,-66.4648208618164,42.4646987915039 627 | 2014-04-02 14:49:18,-66.4859313964844,42.5199012756348 628 | 2014-04-02 15:53:29,-66.5163116455078,42.5471305847168 629 | 2014-04-02 17:53:44,-66.5363464355469,42.5861396789551 630 | 2014-04-02 18:54:12,-66.533073425293,42.5793304443359 631 | 2014-04-02 19:54:56,-66.4957275390625,42.5838088989258 632 | 2014-04-02 20:55:23,-66.4550170898438,42.6033782958984 633 | 2014-04-02 23:00:12,-66.3878479003906,42.6469802856445 634 | 2014-04-03 01:00:31,-66.3949813842773,42.6890602111816 635 | 2014-04-03 02:02:29,-66.4081878662109,42.721851348877 636 | 2014-04-03 03:04:12,-66.4152603149414,42.7651786804199 637 | 2014-04-03 05:04:16,-66.3905029296875,42.823429107666 638 | 2014-04-03 06:04:16,-66.3857116699219,42.8364486694336 639 | 2014-04-03 08:58:25,-66.3114700317383,42.8520584106445 640 | 2014-04-03 09:58:28,-66.2808532714844,42.860279083252 641 | 2014-04-03 11:01:06,-66.2563705444336,42.8677215576172 642 | 2014-04-03 12:06:52,-66.2493515014648,42.878101348877 643 | 2014-04-03 13:06:53,-66.2497634887695,42.8956298828125 644 | 2014-04-03 14:08:23,-66.2773666381836,42.9193382263184 645 | 2014-04-03 15:08:53,-66.2955780029297,42.9488792419434 646 | 2014-04-03 16:13:20,-66.313850402832,42.9863815307617 647 | 2014-04-03 17:13:35,-66.3260192871094,43.0230712890625 648 | 2014-04-03 18:15:31,-66.3258590698242,43.055850982666 649 | 2014-04-03 19:19:35,-66.3119812011719,43.0810585021973 650 | 2014-04-03 20:22:32,-66.2968063354492,43.1058006286621 651 | 2014-04-03 21:22:55,-66.2774276733398,43.1279716491699 652 | 2014-04-03 23:23:47,-66.2645111083984,43.158390045166 653 | 2014-04-04 03:31:55,-66.2836303710938,43.3379516601563 654 | 2014-04-04 05:37:26,-66.2104187011719,43.4353485107422 655 | 2014-04-04 06:42:04,-66.1509780883789,43.4554786682129 656 | 2014-04-04 07:43:32,-66.0870590209961,43.4603118896484 657 | 2014-04-04 08:46:04,-66.0100173950195,43.4541702270508 658 | 2014-04-04 09:46:29,-65.9934005737305,43.4765586853027 659 | 2014-04-04 10:46:32,-66.0084228515625,43.5041084289551 660 | 2014-04-04 11:46:32,-66.0085296630859,43.5043716430664 661 | 2014-04-04 15:38:56,-66.0115814208984,43.5057182312012 662 | 2014-04-04 16:39:00,-66.0084991455078,43.5046691894531 663 | 2014-04-05 04:32:54,-66.0094833374023,43.5044403076172 664 | 2014-04-05 05:36:15,-66.0149078369141,43.5065383911133 665 | 2014-04-05 06:36:20,-66.0125503540039,43.5042381286621 666 | 2014-04-05 07:43:00,-66.0042419433594,43.5026206970215 667 | 2014-04-05 08:43:15,-65.985710144043,43.5110893249512 668 | 2014-04-05 09:45:10,-65.9736785888672,43.4858207702637 669 | 2014-04-05 10:45:16,-65.9865570068359,43.4637908935547 670 | 2014-04-05 12:45:48,-65.9874267578125,43.4641990661621 671 | 2014-04-05 14:56:58,-65.9879302978516,43.4623489379883 672 | 2014-04-05 16:00:06,-66.0271301269531,43.4346389770508 -------------------------------------------------------------------------------- /Day2/HMM_Tutorial_Day2.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/Day2/HMM_Tutorial_Day2.pptx -------------------------------------------------------------------------------- /Day2/data/Eclipse_Sound_Map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/Day2/data/Eclipse_Sound_Map.jpg -------------------------------------------------------------------------------- /Day2/data/land.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/Day2/data/land.dbf -------------------------------------------------------------------------------- /Day2/data/land.prj: -------------------------------------------------------------------------------- 1 | PROJCS["NAD_1983_CSRS_UTM_Zone_21N",GEOGCS["GCS_North_American_1983_CSRS",DATUM["D_North_American_1983_CSRS",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-57.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] -------------------------------------------------------------------------------- /Day2/data/land.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/Day2/data/land.shp -------------------------------------------------------------------------------- /Day2/data/land.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/Day2/data/land.shx -------------------------------------------------------------------------------- /Day3/HMMs_DFO_TutorialDay3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/Day3/HMMs_DFO_TutorialDay3.pdf -------------------------------------------------------------------------------- /Day3/Tutorial_HMM_2022_Day3.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'HMM in Marine Sciences: model selection, covariates, hierarchical structures' 3 | author: "Marco Gallegos Herrada and Vianey Leos Barajas" 4 | output: 5 | bookdown::html_document2: 6 | number_sections: true 7 | highlight: tango 8 | editor_options: 9 | chunk_output_type: console 10 | --- 11 | 12 | 13 | ```{=html} 14 | 20 | ``` 21 | 22 | ```{r setup, include=FALSE} 23 | knitr::opts_chunk$set(echo = TRUE) 24 | knitr::opts_chunk$set(warning = FALSE) 25 | knitr::opts_chunk$set(cache = TRUE) 26 | knitr::opts_chunk$set(message = FALSE) 27 | ``` 28 | 29 | 30 | 31 | ```{r} 32 | library(readr) 33 | library(momentuHMM) 34 | library(ggplot2) 35 | library(dplyr) 36 | library(lubridate) 37 | library(data.tree) 38 | library(DiagrammeR) 39 | ``` 40 | 41 | # Tutorial objectives 42 | 43 | The goal of this tutorial is to explore how to fit hidden Markov models to accelerometer data, how to incorporate covariates into the transition probabilities, and the implementation of hierarchical Markov models to animal movement data. For the first two objectives, we will use 4 days of acceleration data obtained from a free-ranging blacktip reef shark at Palmyra Atoll in the central Pacific Ocean (data taken from Leos-Barajas et al. 2017). 44 | 45 | 46 | # Accelerometer data 47 | 48 | Accelerometer devices measure up to three axes, which can be described relative to the body of the animal: longitudinal (surge), lateral (sway) and dorsoventral (heave). These devices are becoming more prevalent in the fields of animal biologging data as they provide a means of measuring activity in a meaningful and quantitative way. From tri-axial acceleration data, we can also derive several measures that summarize effort or exertion and relate acceleration to activity levels such as overall dynamic body acceleration (ODBA) and vectorial dynamic body acceleration (VeDBA). These metrics can be used to reduce the dimensionality of three-dimension acceleration data while retaining important information. Further, because acceleration data is often at high temporal resolutions over time, it also naturally exhibits a large degree of autocorrelation, making it impossible to assume independence between sequential observations. As we have learned, HMMs can account for the autocorrelation present in the data while assuming that the data were generated according to a finite set of (unobserved) behaviors making them a good candidate model for this type of data structure. Today, we will fit an HMM to the ODBA of a blacktip shark, calculated every second. 49 | 50 | For the blacktip shark, we have time of day, water temperature, depth and ODBA. Since one of our goals is to use the time of observations (second of the day) as a covariate, we also need to extract this information from the time variable. 51 | 52 | 53 | ```{r} 54 | # Reading the data 55 | BlacktipB <- read_delim("data/BlacktipB.txt", 56 | delim = "\t", escape_double = FALSE, 57 | trim_ws = TRUE) 58 | # Let's transform the date/time info into a proper time format 59 | # In this case we need to extract the second of the day correspondent to each observation 60 | BlacktipB = BlacktipB %>% 61 | mutate(Time = as.POSIXct(Time,format = "%m/%d/%Y %H:%M")) %>% 62 | mutate(hour_to_sec = as.integer(seconds(hm(format(Time, format = "%H:%M"))))) %>% 63 | group_by(Time) %>% mutate(sec = row_number()) %>% ungroup() %>% 64 | mutate(sec = case_when(hour_to_sec == 53160 ~ as.integer(sec + 55), 65 | TRUE ~ sec), 66 | hour_to_sec = hour_to_sec + sec) 67 | 68 | head(BlacktipB) 69 | 70 | ``` 71 | 72 | 73 | # Fitting our model 74 | 75 | Looking at the ODBA values through the observed period, we find ODBA is unusually high at some times -- for this shark we assumed that values between 0 and 2 were consistent with what we expected. Because accommodating extreme values can pose a problem for identification of an adequate state-dependent distribution in our HMM, we removed them from the data set. However, note that in general, deciding whether to remove extreme values or not will more likely depend on whether we find appropriate distributional forms that can accommodate them. Generally, we need to make sure that extreme values are in fact some artefact of the data collection process, not representative of a behavior of interest, or inconsistent with what we are trying to capture as well. Removing data is not good general practice but instead we can assess on a case-by-case basis. 76 | 77 | We can see the original time series here across the four days: 78 | 79 | ```{r} 80 | BlacktipB %>% ggplot(aes(Time,ODBA)) + geom_line() 81 | 82 | ``` 83 | 84 | 85 | ```{r} 86 | 87 | BlacktipB = BlacktipB %>% filter(ODBA <= 2.0) 88 | 89 | ``` 90 | 91 | And now, the modified time series with values above 2.0 removed. Note that here we ignore the fact that we do not have data for these time points. 92 | 93 | Now, we are ready to start to look for models for this data! 94 | 95 | ```{r, echo=F} 96 | BlacktipB %>% ggplot(aes(Time,ODBA)) + geom_line() 97 | 98 | ``` 99 | 100 | 101 | Given our data, we are interested in finding possible behaviours through the observation process (ODBA). Let's take a quick look at the histogram of the observations. 102 | 103 | ```{r, echo=F} 104 | 105 | hist(BlacktipB$ODBA[BlacktipB$ODBA < .4],breaks=80,main="Histogram of ODBA", 106 | xlab = "ODBA") 107 | 108 | ``` 109 | 110 | 111 | As we have indicated before, the best way to start when fitting a hidden Markov model is to keep things simple. In this case, we will be considering 2 behavioral states, with gamma state-dependent distributions, and no covariates for the transition probability matrix. As mentioned in previous tutorials, now is time to implement the decisions that we have made so far. For the choice of initial parameter values we can take a quick peak at the data (e.g., using the plots above). From the plots above, we specify the means of our state-dependent distributions as 0.1 and 0.3. 112 | 113 | 114 | Now that the data is ready for modeling, we choose to fit a 2-state hidden Markov model. For this purpose, we first need to assign the class `momentuHMMData` to the data in order to be presentable for the functions related to `momentuHMM`. 115 | 116 | ```{r} 117 | BlacktipBData = prepData(BlacktipB,coordNames = NULL, 118 | covNames = "hour_to_sec") 119 | 120 | ``` 121 | 122 | Let's fit our model and take a look at the output of the fitted model. 123 | 124 | ```{r, cache=TRUE} 125 | fit1 = fitHMM(BlacktipBData,nbStates=2,dist=list(ODBA="gamma"),Par0 = list(ODBA=c(.1,.3,1,1))) 126 | 127 | fit1 128 | ``` 129 | 130 | We can also plot the results to obtain a visual representation of the fitted model. 131 | 132 | ```{r} 133 | plot(fit1,breaks = 80) 134 | ``` 135 | 136 | Let's look at the pseudo-residuals. 137 | 138 | ```{r} 139 | plotPR(fit1) 140 | ``` 141 | 142 | We can also compute the most likely sequence of states. 143 | 144 | ```{r, cache=TRUE} 145 | # identify most likely state using the Viterbi algorithm 146 | BlacktipB$state <- viterbi(fit1) 147 | 148 | # proportion of the behaviour states during the observed period 149 | table(BlacktipB$state)/length(BlacktipB$state) 150 | 151 | BlacktipB %>% mutate(day = day(Time)) %>% ggplot(aes(Time,state)) + facet_wrap(~day,scales = "free_x") + geom_point() 152 | ``` 153 | 154 | Let's include retryFits in the fitHMM function. This can take time to run. 155 | 156 | ```{r, cache=TRUE} 157 | set.seed(147) 158 | fit1_s2 <- fitHMM(BlacktipBData, 159 | nbState = 2, 160 | dist=list(ODBA="gamma"), 161 | Par0 = list(ODBA=c(.1,.3,1,1)), 162 | retryFits=10) 163 | fit1_s2 164 | ``` 165 | 166 | Seems nothing changed at all! 167 | 168 | Now let's go further and include a high perturbation in one of the initial values (instead of .1 and .3, let's do .1 and 2). Do we still have similar estimated coefficients and log likelihood? (no matter the initial values, the coefficients should be similar) 169 | 170 | ```{r, cache=TRUE} 171 | fit1_s2_long <- fitHMM(BlacktipBData, 172 | nbState = 2, 173 | dist=list(ODBA="gamma"), 174 | Par0 = list(ODBA=c(.1,2,1,1))) 175 | 176 | fit1_s2_long 177 | ``` 178 | 179 | Let's look at the pseudo-residuals. 180 | 181 | ```{r} 182 | plotPR(fit1_s2_long) 183 | ``` 184 | 185 | You may get warnings. 186 | 187 | We can see that there is high autocorrelation and some deviation from normality. 188 | 189 | We can also compute the most likely sequence of states. What can we infer from this? Is there something else we can say from this? According to fitted model, can we see if there is any interesting pattern? 190 | 191 | ```{r, cache=TRUE} 192 | # identify most likely state using the Viterbi algorithm 193 | BlacktipB$state_wildPar0 <- viterbi(fit1_s2_long) 194 | 195 | # proportion of the behaviour states during the observed period 196 | table(BlacktipB$state_wildPar0)/length(BlacktipB$state_wildPar0) 197 | 198 | BlacktipB %>% mutate(day = day(Time)) %>% ggplot(aes(Time,state_wildPar0)) + facet_wrap(~day,scales = "free_x") + geom_point() 199 | 200 | ``` 201 | 202 | Here we can see that there is only one state when we use these new starting values, this is an indication that there may be problems. 203 | 204 | # Incorporating covariates 205 | 206 | As in Leos-Barajas et al. 2017, we can incorporate other information that may help explain the values of ODBA. In this case, we consider the second of the day of every observation. Time of day is represented by two trigonometric functions with period 24 h, $cos(2\pi t/86,400)$ and $sin(2\pi t/86,400)$ (86 400 is the number of seconds in a day). Using the function cosinor, we can convert our data stream to something that is useful for us. As well, we need to provide the formula corresponding to the regression that will be stored in the transition probability values. 207 | 208 | ```{r, cache=TRUE} 209 | # formula corresponding to the regression coefficients for the transition probabilities 210 | formula = ~ cosinor(hour_to_sec, period = 86400) 211 | Par0_fit2 <- getPar0(model=fit1, formula=formula) 212 | 213 | fit2 = fitHMM(BlacktipBData,nbStates=2,dist=list(ODBA="gamma"),Par0 = Par0_fit2$Par,formula=formula) 214 | 215 | fit2 216 | ``` 217 | 218 | 219 | ```{r, cache=TRUE} 220 | plot(fit2,breaks=80) 221 | ``` 222 | 223 | Let's explore the results. Do the coefficients vary much? What about the ACF? Did the autocorrelation decrease with this innovation? 224 | 225 | ```{r} 226 | plotPR(fit2) 227 | ``` 228 | 229 | We can also take a quick look at the Akaike information criteria (AIC) for the two models to do a comparison. 230 | 231 | ```{r} 232 | 233 | AIC(fit1) 234 | AIC(fit2) 235 | 236 | ``` 237 | 238 | # Depth Data 239 | 240 | Tiger shark data were collected in Oahu, Hawai'i. The shark's depth was recorded in 0.5 m intervals every 2 s over a 23 day period, from March 9 to March 31, 2009. On some days, the tiger shark inhabited varied ranges of depth levels and performed many dives whereas other days it remained relatively constant in the water column and dove less. For sharks, movement in the water column is not easily segmented into types of dives. However, dives, or simply ascending or descending, can be an important part of a shark's behavior. We extracted a depth position every ten minutes from the available data record and sequentially computed the absolute change in depth position, $y^*_t = |d_t - d_{t-1}|$, for the tiger shark in order to understand how the depths inhabited by the shark differ across days. On some days the tiger shark tends to remain in the same part of the water column for long periods of time while on others, it tends to move up and down more frequently throughout the day. We processed the data to produce $M=144$ observations per day, across $K=21$ days, excluding the first and last days for which only partial data records were available. 241 | 242 | ```{r} 243 | 244 | # Read the data 245 | tigerShark <- read_csv("data/tigershark_depthchange10min.csv") 246 | tigerShark = tigerShark %>% mutate(abs_change_depth = abs(Depth - lag(Depth,default = 0))) 247 | head(tigerShark) 248 | 249 | ``` 250 | 251 | ```{r, cache=TRUE} 252 | tigerShark %>% 253 | filter(days != 9) %>% 254 | ggplot(aes(x=HST,y=Depth)) + facet_wrap(~days,scales = "free_x") + geom_line() + 255 | scale_x_datetime(breaks= "8 hour", date_labels = "%H:%M") + theme_minimal() 256 | 257 | 258 | tigerShark %>% filter(days != 9) %>% 259 | ggplot(aes(x=HST,y=2*abs_change_depth)) + facet_wrap(~days,scales = "free_x") + geom_line() + 260 | scale_x_datetime(breaks= "8 hour", date_labels = "%H:%M") + theme_minimal() 261 | 262 | ``` 263 | 264 | # Hierarchical Hidden Markov models 265 | 266 | The general idea of a hiearchical HMM is that there are (at least) two behavioral processes of interest but they manifest at different temporal scales. For instance, here we will look at both fine-scale vertical movement behavior and across day movement behavior as well. These are referred to as fine state-level (10 min) and coarse state-level behaviors (day). 267 | 268 | To fit these models in momentuHMM, we will introduce a new column called "level". 269 | 270 | ```{r} 271 | 272 | days_range = unique(tigerShark$days) 273 | tigerSharkData <- NULL 274 | 275 | for(i in days_range){ 276 | coarseInd <- data.frame(tigerShark %>% filter(days == i) %>% 277 | filter(row_number() == 1) %>% select(HST), 278 | days = i, 279 | level=c("1","2i"), 280 | abs_change_depth=NA) 281 | tmp <- rbind(coarseInd,tigerShark %>% filter(days == i) %>% mutate(level = "2") %>% 282 | select(HST,days,level,abs_change_depth)) 283 | tigerSharkData <- rbind(tigerSharkData,tmp) 284 | } 285 | 286 | head(tigerSharkData) 287 | 288 | tigerSharkData = prepData(tigerSharkData, 289 | coordNames = NULL, hierLevels = c("1","2i","2")) 290 | 291 | 292 | # summarize prepared data 293 | summary(tigerSharkData, dataNames = names(tigerSharkData)[-1]) 294 | 295 | ``` 296 | 297 | Note that 2i indicates the initial distribution in the fine state level for every time in the coarse state level, and 2 indicates the observations for the fine state level. 298 | 299 | However, one of the difficulties with hierarchical HMMs is the construction of the number of states, just like in regular HMMs! Here we choose three fine-scale states as that has been tested for this data to produce the best compromise between model fit and model complexity, and two coarse-scale states. 300 | 301 | ```{r} 302 | 303 | ### define hierarchical HMM 304 | ### states 1-3 = coarse state 1 (nontravelling) 305 | ### states 4-6 = coarse state 2 (travelling) 306 | hierStates <- data.tree::Node$new("tiger shark HHMM states") 307 | hierStates$AddChild(name="nontravelling") 308 | hierStates$nontravelling$AddChild(name="nt1", state=1) 309 | hierStates$nontravelling$AddChild(name="nt2", state=2) 310 | hierStates$nontravelling$AddChild(name="nt3", state=3) 311 | hierStates$AddChild(name="travelling") 312 | hierStates$travelling$AddChild(name="t1", state=4) 313 | hierStates$travelling$AddChild(name="t2", state=5) 314 | hierStates$travelling$AddChild(name="t3", state=6) 315 | 316 | plot(hierStates) 317 | 318 | ``` 319 | 320 | ```{r,eval=F} 321 | 322 | #Alternative way for specifying 323 | hierStates <- data.tree::as.Node(list(name="tiger shark HHMM states", 324 | nontravelling=list(nt1=list(state=1), 325 | nt2=list(state=2), 326 | nt3=list(state=3)), 327 | travelling=list(t1=list(state=4), 328 | t2=list(state=5), 329 | t3=list(state=6)))) 330 | 331 | ``` 332 | 333 | 334 | The name for any of the “children” added to a node are user-specified and are akin 335 | to the stateNames argument in fitHMM for a standard HMM. While these names are 336 | arbitrary, the name and state attributes must be unique. 337 | 338 | ```{r} 339 | 340 | # data stream distributions 341 | # level 1 = coarse scale (no data streams) 342 | # level 2 = fine scale (dive_duration, maximum_depth, dive_wiggliness) 343 | hierDist <- data.tree::Node$new("tiger shark HHMM dist") 344 | hierDist$AddChild(name="level1") 345 | hierDist$AddChild(name="level2") 346 | hierDist$level2$AddChild(name="abs_change_depth", dist="gamma") 347 | plot(hierDist) 348 | 349 | ``` 350 | 351 | The Node attribute dist is required in hierDist and specifies the probability distribution for each data stream at each level of the hierarchy (Figure 14. In this case, 352 | level1 (corresponding to coarse-scale observations with level=1) has no data streams, 353 | and each of the data streams for level2 (corresponding to fine-scale observations with 354 | level=2) is assigned a gamma distribution with an additional point-mass on zero to account for zero changes in depth. 355 | 356 | We did not include any covariates on the t.p.m. or initial distribution for either level of the hierarchy, but, for demonstration purposes, here is 357 | how we would use the hierFormula and hierFormulaDelta arguments to specify the 358 | t.p.m. and initial distribution formula for each level of the hierarchy in fitHMM: 359 | 360 | ```{r} 361 | 362 | # define hierarchical t.p.m. formula(s) 363 | hierFormula <- data.tree::Node$new("harbor porpoise HHMM formula") 364 | hierFormula$AddChild(name="level1", formula=~1) 365 | hierFormula$AddChild(name="level2", formula=~1) 366 | 367 | # define hierarchical initial distribution formula(s) 368 | hierFormulaDelta <- data.tree::Node$new("harbor porpoise HHMM formulaDelta") 369 | hierFormulaDelta$AddChild(name="level1", formulaDelta=~1) 370 | hierFormulaDelta$AddChild(name="level2", formulaDelta=~1) 371 | 372 | ``` 373 | 374 | We can assume the data stream probability distributions do not depend on the coarse-scale state, so we can constrain the state-dependent parameters for states 1 (“nt1”) and 4 (“t1”), states 2 (“nt2”) and 5 (“t2”), and states 3 (“nt3”) and 6 (“t3”) to be equal using the DM argument: 375 | 376 | ```{r} 377 | 378 | # defining starting values 379 | cd.mu0 = rep(c(5,50,100),hierStates$count) 380 | cd.sigma0 = rep(c(5,15,40),hierStates$count) 381 | cd.pi0 = rep(c(0.2,0.01,0.01),hierStates$count) 382 | 383 | Par0 = list(abs_change_depth = c(cd.mu0,cd.sigma0,cd.pi0)) 384 | 385 | nbStates <- length(hierStates$Get("state",filterFun=data.tree::isLeaf)) 386 | 387 | 388 | ``` 389 | 390 | ```{r} 391 | 392 | # constrain fine-scale data stream distributions to be same 393 | cd_DM <- matrix(cbind(kronecker(c(1,1,0,0,0,0),diag(3)), 394 | kronecker(c(0,0,1,1,0,0),diag(3)), 395 | kronecker(c(0,0,0,0,1,1),diag(3))), 396 | nrow=nbStates*3, 397 | ncol=9, 398 | dimnames=list(c(paste0("mean_",1:nbStates), 399 | paste0("sd_",1:nbStates), 400 | paste0("zeromass_",1:nbStates)), 401 | paste0(rep(c("mean","sd","zeromass"),each=3), 402 | c("_14:(Intercept)", 403 | "_25:(Intercept)", 404 | "_36:(Intercept)")))) 405 | DM = list(abs_change_depth = cd_DM) 406 | 407 | ``` 408 | 409 | ```{r} 410 | 411 | # get initial parameter values for data stream probability distributions 412 | Par <- getParDM(tigerSharkData,hierStates=hierStates,hierDist=hierDist, 413 | Par=Par0,DM=DM) 414 | 415 | # check hierarchical model specification and parameters 416 | checkPar0(tigerSharkData,hierStates=hierStates,hierDist=hierDist,Par0=Par, 417 | hierFormula=hierFormula,hierFormulaDelta=hierFormulaDelta, 418 | DM=DM) 419 | 420 | ``` 421 | 422 | When interpreting the output, we are looking at two parts: 423 | 424 | - the estimated state-dependent distribution parameters 425 | - the different transition probability matrices that define the differences at the coarse-scale 426 | 427 | ```{r, cache=TRUE} 428 | 429 | # fit hierarchical HMM 430 | hhmm <- fitHMM(data=tigerSharkData,hierStates=hierStates,hierDist=hierDist, 431 | #hierFormula=hierFormula,#hierFormulaDelta=hierFormulaDelta, 432 | Par0=Par,#hierBeta=hierBeta,hierDelta=hierDelta, 433 | DM=DM,nlmPar=list(hessian=FALSE)) 434 | hhmm 435 | 436 | ``` 437 | 438 | We can use the same functions as before to visualize our model results. 439 | 440 | ```{r} 441 | plot(hhmm) 442 | plotPR(hhmm) 443 | ``` 444 | 445 | # Exercises 446 | 447 | Generate new data streams from original datasets (overall mean in different time periods). Does the ACF changes between these data sets? How are they compared to the original data set? What can you say about this? 448 | 449 | - Instead of considering observations every second, create a new data set for 10 sec, another for 30 s and 1 min. Code below will generate such data sets. Fit a basic HMM for the each one of these new datasets. Did the ACF changed? does they seems to not break the conditional independence? (i.e., the ACF values are lower?). 450 | 451 | ```{r, eval=F} 452 | 453 | BlacktipB = BlacktipB %>% 454 | mutate(group_10s = case_when(sec <= 10 ~ 1, 455 | 10 < sec & sec <= 20 ~ 2, 456 | 20 < sec & sec <= 30 ~ 3, 457 | 30 < sec & sec <= 40~ 4, 458 | 40 < sec & sec <= 50 ~ 5, 459 | 50 < sec & sec <= 60 ~ 6, 460 | TRUE ~ -1), 461 | group_30s = case_when(sec <= 30 ~ 1, 462 | 30 < sec & sec <= 60 ~ 2, 463 | TRUE ~ -1)) %>% 464 | group_by(Time,group_10s) %>% mutate(ODBA_mean_10s = mean(ODBA)) %>% ungroup() %>% 465 | group_by(Time,group_30s) %>% mutate(ODBA_mean_30s = mean(ODBA)) %>% ungroup() %>% 466 | group_by(Time) %>% mutate(ODBA_mean_60s = mean(ODBA)) %>% 467 | mutate(hour_to_sec_10s = floor((hour_to_sec-1)/10+1), 468 | hour_to_sec_30s = floor((hour_to_sec-1)/30+1), 469 | hour_to_sec_60s = floor((hour_to_sec-1)/60+1)) 470 | 471 | BlacktipB_10s = BlacktipB %>% group_by(Time,group_10s) %>% filter(row_number() == 1) %>% 472 | ungroup() %>% select(Time,Depth,ODBA_mean_10s,hour_to_sec_10s) 473 | BlacktipB_30s = BlacktipB %>% group_by(Time,group_30s) %>% filter(row_number() == 1) %>% 474 | ungroup() %>% select(Time,Depth,ODBA_mean_30s,hour_to_sec_30s) 475 | BlacktipB_60s = BlacktipB %>% group_by(Time) %>% filter(row_number() == 1) %>% 476 | ungroup() %>% select(Time,Depth,ODBA_mean_60s,hour_to_sec_60s) 477 | 478 | BlacktipB = BlacktipB %>% select(Time,Depth,ODBA,hour_to_sec) 479 | 480 | 481 | ``` 482 | 483 | Fit a 3-state HMM with no covariates and fit another one using time as a covariate. What happents to the ACF? According to loglikelihood and AIC, which model is better? 484 | 485 | - Reproduce the analysis from the blacktip shark data, but now include three states. What about the ACF? Did something change compared to the 2-state HMM? Now include hour_to_sec as a covariate and fit a new model. What happen with the AIC values and the loglikelihood? According to these, what seems to be a better model? -------------------------------------------------------------------------------- /LectureSlides/HMMs_DFO_Day1 - Copy.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/LectureSlides/HMMs_DFO_Day1 - Copy.pptx -------------------------------------------------------------------------------- /LectureSlides/HMMs_DFO_Day1.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/LectureSlides/HMMs_DFO_Day1.pptx -------------------------------------------------------------------------------- /LectureSlides/HMMs_DFO_Day2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/LectureSlides/HMMs_DFO_Day2.pdf -------------------------------------------------------------------------------- /LectureSlides/HMMs_DFO_Day3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/LectureSlides/HMMs_DFO_Day3.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DFO 2022 Hidden Markov Model Workshop 2 | 3 | ## Description and format 4 | 5 | This workshop was developed by Marie Auger-Méthé, Vianey Leos Barajas, Ron Togunov, and Marco Antonio Gallegos Herrada for the Department of Fisheries and Oceans, Canada in October 2022. The goal of the workshop is to illustrate the application of hidden Markov models (HMMs) to movement data from marine animals to classify behaviours and identify behaviour-specific habitat associations. 6 | 7 | The workshop will be composed of three one-hour lectures and three three-hour tutorials in R. These lecture can be found on our youtube channel: https://www.youtube.com/playlist?list=PLYkxNfKA95Pzcp5xfJdQKl6xLQoXrP39x 8 | Each tutorial will be completed together over zoom and will begin with a 10-minute introduction over Zoom that will provide an overview of the tutorial objectives. 9 | 10 | ## Workshop learning objectives 11 | 12 | - Statistical framework for HMMs and their application to animal movement data 13 | - Selecting appropriate temporal resolution for HMM analysis 14 | - Interpolating missing locations (linear, crw, path segmentation, and multiple imputation) 15 | - Fit HMMs to animal movement data to identify behaviours 16 | - Integrating diving data-streams to identify more complex behaviours 17 | - Incorporate covariates on state transition probability to identify conditions that promote different behaviours 18 | - Integrating covariates on emission probabilities to model biased random walks 19 | - Modelling behaviour using accelerometer data 20 | - Fitting hierarchical HMMs 21 | 22 | ## Prerequisite experience 23 | 24 | - Intermediate R coding 25 | - Familiarity with animal movement/telemetry data 26 | 27 | ## Preparation/instructions 28 | 29 | - Download and unzip workshop zip from Github 30 | - Install all the required packages as described in 0_Installing_packages.Rmd 31 | - Make sure all packages are up-to-date as older versions may not work 32 | - View each lecture in advance of their respective workshop date 33 | - Create new R script in the DFO_HMM_2022 directory 34 | - Follow along with each days tutorial html files (e.g., "Day1/HMM_Tutorial_Day1.html") 35 | -------------------------------------------------------------------------------- /preWorkshopInfo/0_Installing_packages.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Installing packages" 3 | subtitle: "Tips to install some of the packages" 4 | author: "Joe Watson, Ron Togunov, & Marie Auger-Méthé" 5 | date: "26/07/2022" 6 | output: 7 | html_document: 8 | number_sections: true 9 | --- 10 | 11 | 12 | ```{r setup, include=FALSE} 13 | knitr::opts_chunk$set(echo = TRUE) 14 | ``` 15 | 16 | ## Installing packages: tips to install some of the packages 17 | 18 | Some of the packages we will use in the workshop are not available on CRAN and some require the installation of additional software and compilers. 19 | 20 | ### Compilers 21 | 22 | C++ compilers are needed. 23 | 24 | For Mac, installing Xcode is an easy way to install compilers. 25 | You can install Xcode directly from the App store (it's free). 26 | 27 | You can also install it via terminal, but because it is a very large program it's worth checking if you already have it installed. If not, open terminal and run: 28 | 29 | ```{r, eval=FALSE} 30 | xcode-select --install 31 | ``` 32 | 33 | For Windows, installing Rtools is an easy way to install compilers. Rtools is found [cran.r-project.org/bin/windows/Rtools](https://cran.r-project.org/bin/windows/Rtools/index.html) 34 | 35 | For Linux, the necessary compilers are installed by default with R. To double check they are installed run: 36 | 37 | ```{r, eval=FALSE} 38 | gcc --version 39 | ``` 40 | 41 | If nothing is returned, then they can be installed manually as follows: 42 | 43 | ```{r, eval=FALSE} 44 | sudo apt update 45 | sudo apt install build-essential 46 | ``` 47 | 48 | 49 | ### Required GIS software 50 | 51 | **The workshop is developed with latest version of gdal and geos. The workshop material will not work without them or if you are using outdated versions of these.** 52 | 53 | If you do not have these software already installed, please install them (see below). **If you already have `rgdal` and gdal installed, verify that the version that's already installed is adequate. Load the `rgdal` package and use the function rgdal function `GDALis3ormore()` in R. It should return TRUE. We want gdal to use the appropriate PROJ transformation software ([proj.org](https://proj.org/)), so in addition the rgdal function `PROJis6ormore()` should return TRUE. If either return FALSE, update your gdal.** 54 | *Note new version of some of these GIS software and packages (e.g., raster) have made significant changes and might affect other code.* 55 | 56 | 57 | On Mac, installing these is easiest done using homebrew ([brew.sh](https://brew.sh/)). With homebrew installed, open terminal and run: 58 | 59 | ```{r, eval=FALSE} 60 | brew tap osgeo/osgeo4mac && brew tap --repair 61 | brew install pkg-config 62 | brew install proj 63 | brew install geos 64 | brew install gdal 65 | ``` 66 | 67 | On Windows, express install osgeo4w by following the instruction found at [trac.osgeo.org/osgeo4w](https://trac.osgeo.org/osgeo4w/). This will install the PROJ, GDAL, and GEOS libraries. 68 | 69 | On Linux, run the following in the terminal: 70 | ```{r, eval=FALSE} 71 | sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable 72 | sudo apt-get update 73 | sudo apt-get install libudunits2-dev libgdal-dev libgeos-dev libproj-dev 74 | ``` 75 | 76 | 77 | ### Installing the latest version of the spatial packages 78 | 79 | The latest version of sf and terra are **required**. The workshop material **will not work without these**. These can be installed **after** the latest GIS software has been installed. 80 | 81 | ```{r, eval=FALSE} 82 | install.packages(c('sf', 'terra', 'tmap'), dep=TRUE) 83 | ``` 84 | 85 | We are trying to remove any usage of the package raster (this package is now replaced by terra), but since momentuHMM still uses raster, it is sometimes easier to use functions from the raster package. 86 | Thus, please install raster. 87 | 88 | ```{r, eval=FALSE} 89 | install.packages('raster', dep=TRUE) 90 | ``` 91 | 92 | 93 | ### Packages available on CRAN without special dependencies 94 | 95 | The remaining packages do not have special dependencies, and should be easily installed or updated via CRAN (using install.packages()): 96 | 97 | + momentuHMM 98 | + dplyr 99 | + tidyr 100 | + stringr 101 | + data.table 102 | + lubridate 103 | + units 104 | + diveMove 105 | + earthtide 106 | + corrplot 107 | + conicfit 108 | + car 109 | + mitools 110 | + doFuture 111 | + kableExtra 112 | + data.tree 113 | 114 | ### Check that all packages are installed 115 | 116 | Once all the packages are installed, you can check that they are properly installed by loading them. 117 | 118 | ```{r, warning=FALSE, message=FALSE} 119 | library(sf) # spatial data processing 120 | library(terra) # raster data processing 121 | library(tmap) # mapping spatial data 122 | library(sp) # old spatial package 123 | library(raster) # old raster package 124 | library(momentuHMM)# fitting HMMs 125 | library(dplyr) # data management 126 | library(tidyr) # data management 127 | library(stringr) # character string management 128 | library(data.table)# data management 129 | library(lubridate) # date management 130 | library(units) # physical measurement units management 131 | library(diveMove) # calculating dive metrics 132 | library(earthtide) # estimating tidal data 133 | library(corrplot) # calculating Pearson's correlation matrices 134 | library(conicfit) # fitting error ellipses (required by momentuHMM) 135 | library(car) # additional operations to Applied Regression 136 | library(mitools) # parallel processing 137 | library(doFuture) # parallel processing 138 | library(kableExtra)# produce visually appealing tables 139 | library(data.tree) 140 | library(DiagrammeR) 141 | ``` 142 | -------------------------------------------------------------------------------- /preWorkshopInfo/email.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MarieAugerMethe/DFO_HMM_2022/b67eddb2f02fa467fbaa4b1fdf872ebc170564c2/preWorkshopInfo/email.docx --------------------------------------------------------------------------------