Load bcpa
, and a few other handy packages:
require(magrittr)
require(lubridate)
require(bcpa)
We simulate some data with four phases / three change points: surface to medium to deep to surface, that occur at fixed times.
<- 100
n.obs = (Sys.time() - dhours(runif(n.obs, 0, n.obs))) %>% sort
time
<- 50; d2 <- 100
d1 <- 25; t2 <- 65; t3 <- 85
t1 <- 1; sd2 <- 5; sd3 <- 10
sd1
<- difftime(time, min(time), units="hours") %>% as.numeric
dtime <- cut(dtime, c(-1, t1, t2, t3, 200), labels = c("P1","P2","P3","P4"))
phases <- c(0,d1,d2,0)[phases]
means <- c(sd1,sd2,sd3,sd1)[phases]
sds <- rnorm(n.obs,means, sds)
depth # make all depths positive!
<- abs(depth)
depth <- data.frame(time, depth) mydata
The structure of the data is very simple:
head(mydata)
## time depth
## 1 2022-05-23 08:36:42 0.32192527
## 2 2022-05-23 09:13:09 0.78383894
## 3 2022-05-23 09:40:42 1.57572752
## 4 2022-05-23 10:08:49 0.64289931
## 5 2022-05-23 10:24:15 0.08976065
## 6 2022-05-23 11:44:36 0.27655075
Plot simulated depth data
with(mydata, plot(time, depth, type = "o"))
Perform the window sweep. Note that you specify the response variable (depth
) and the time variable (time
):
<- WindowSweep(mydata, variable = "depth", time.var = "time", windowsize = 25, windowstep = 1, progress=FALSE) depth.ws
Here are some plots and the summary of the change point analysis:
plot(depth.ws, ylab = "Depth (m)")
plot(depth.ws, type = "flat", cluster = 8, ylab = "Depth (m)")
ChangePointSummary(depth.ws, cluster = 8)
## $breaks
## X1 middle size modelmode middle.POSIX
## 1 1 25.46224 27 4 2022-05-24 09:58:01
## 2 2 62.47157 18 4 2022-05-25 22:46:30
## 3 3 84.46078 12 4 2022-05-26 20:34:54
##
## $phases
## t.cut mu.hat s.hat rho.hat t0 t1 interval
## 1 (-1,25.5] 3.681865 11.256694 1.4733085237 -1.00000 25.46224 26.46224
## 2 (25.5,62.5] 50.063357 4.367361 0.0005596285 25.46224 62.47157 37.00933
## 3 (62.5,84.5] 91.941686 17.048889 0.0883214493 62.47157 84.46078 21.98921
## 4 (84.5,98.9] 6.434163 22.852427 0.0613947945 84.46078 98.86528 14.40450
This is a pretty artificial example, but it works well.
Comments
The BCPA was originally formulated to analyze irregular movement data collected on marine mammals, but in essence it simply reduced movement data (X-Y-Time) to a univariate time-series. There are - in my opinion - better (i.e. more informative and more robust) tools for dealing with movement data specifically, (e.g. at https://github.com/EliGurarie/smoove), but the BCPA might still be useful for irregular univariate time series. An example (again from marine mammals) is depth data. A recent update to BCPA makes this analysis somewhat smoother. Here is an example on simulated data.
Note - to date this is available only on the GitHub version of BCPA, i.e. the first step is:
The code for this example can also be found in the help file for the
WindowSweep()
function.