## ----setup, include=FALSE----------------------------------------------------- knitr::opts_chunk$set(echo = TRUE, global.par=TRUE, fig.path = ".", fig.pos = 'h', fig.height = 2.7, fig.width = 4, fig.align = "center") knitr::opts_knit$set(global.par = TRUE) ## redo benchmarking or use existing figure? REDOLONG <- FALSE times <- 100 ## ---- include=FALSE----------------------------------------------------------- par(mai=c(.5,.5,.3,.5),mgp=c(1.2,.3,0),tcl=-.25, cex.main=.75) ## ---- eval=FALSE-------------------------------------------------------------- # simple_backtrace <- function (imax, jumps = 0) { # end <- length(imax) # end of the first segment = end of the data # ends <- c(end) # initiate vector # while (end > 1) { # end <- imax[end] - jumps # end of previous segment # ends <- c(end, ends) # note the order, new end is prepended # } # ends # } ## ----dpsegdemo, fig.cap="Segmentation of a growth curve (*E. coli* in M9 minimal medium) by `dpseg`. Vertical lines indicate segment starts (dashed red) and ends (solid black). The `predict` method returns the piecewise linear model (dashed yellow).\\label{fig:dpseg}"---- library(dpseg) type <- "var" # use the (default) scoring, -var(residuals(lm(y~x))) jumps <- FALSE # allow discrete jumps between segments? P <- 1e-4 # break-point penalty, use higher P for longer segments # get example data `oddata` - bacterial growth measured as optical density OD x <- oddata$Time y <- log(oddata[,"A2"]) # note: exponential growth -> log(y) is linear # NOTE: the scoring function results are stored as a matrix for re-use below segs <- dpseg(x=x, y=y, jumps=jumps, P=P, type=type, store.matrix=TRUE) print(segs) plot(segs) lines(predict(segs),lty=2, lwd=3, col="yellow") ## ---- eval=FALSE-------------------------------------------------------------- # # use options frames, and res to control file size # movie(segs, format="gif", file.name="movie", path="pkg/vignettes/figures", # frames=seq(1,length(x),3), delay=.3,res=50) ## ----movie, echo=FALSE, fig.cap="Animation of the progress of the algorithm through the data (gray circles and right y-axis). The black vertical line is the current position $j$, and the black circles are the values of the scoring function $\\text{score}(i,j)$ for all $i0] for ( i in irng ) { idx = i-(j-maxl) sij = ifelse(i==1&jumps==1, S0, S[i-jumps]) si[idx] = sij + score(x, y, i, j) - P } S[j] = max(si) idx = which.max(si) imax[j] = idx + (j-maxl) } imax } ## SCORING FUNCTION score <- function(x, y, k, l) -var(residuals(lm(y[k:l]~x[k:l]))) ## backtracing backtrace <- function(imax, jumps=0) { end = length(imax) # end of last segment ends = end while( end>1 ) { end = imax[end] - jumps ends = c(end, ends) } ends[1] <- ends[1] + jumps # note: start of first segment ends } ## ---- include=FALSE----------------------------------------------------------- par(mai=c(.5,.5,.3,.5),mgp=c(1.2,.3,0),tcl=-.25, cex.main=.75) ## ---- eval=TRUE, echo=TRUE, fig.cap="Correction segmentation (horizontal lines) for a primitive test case."---- # simple test case k1=1 k2=.05 k3=-.5 y1 <- k1*1:5 y2 <- k2*1:5 + k1*5 y3 <- k3*1:5 + k2*5 + k1*5 set.seed(1) ym <- c(y1, y2, y3) nsd <- .25 # noise, standard deviation y <- ym + rnorm(length(ym), 0, nsd) # add noise x <- 1:length(y) ## run recursion JUMPS = 0 imax = recursion(x, y, maxl=length(x), jumps=JUMPS, P=0, minl=3, S0=1) ## backtrace ends = backtrace(imax, jumps=JUMPS) print(ends) ## plot plot(x,y) lines(x,ym) legend("bottom", title="slopes:", legend=paste(k1,k2,k3,sep=", "), bty="n") abline(v=ends) ## ---- echo=FALSE, eval=TRUE--------------------------------------------------- ## for development only: silently reload data to test code jumps <- FALSE # allow discrete jumps between segments? P <- 1e-4 # break-point penalty, use higher P for longer segments # get example data `oddata` - bacterial growth measured as optical density OD x <- oddata$Time y <- log(oddata[,"A2"]) # note: exponential growth -> log(y) is linear