setOldClass("memoised")
setOldClass("set")
.crops.class<-setClass("crops.class",representation(method="memoised",betas="set"))
crops.class<-function(method,betas)
{
.crops.class(method=method,betas=betas)
}
#' Summary of segmentations by penalty value
#'
#' @name segmentations
#'
#' @description Produces a summary of the segmentations for each penalty value in the form of a data frame.
#'
#' @docType methods
#'
#' @param object An instance of an S4 class produced by \code{\link{crops}}.
#'
#' @return A data frame containing the penalties, costs, penalised costs, and changepoint locations. Note - if no changepoints are detected in
#' the penalty interval [beta_min,beta_max], then the value returned is NULL.
#'
#' @rdname segmentations-methods
#'
#' @aliases segmentations,crops.class-method
#'
#' @seealso \code{\link{crops}}.
#'
#' @examples
#' # see the crops example
setGeneric("segmentations",function(object) {standardGeneric("segmentations")})
setMethod("segmentations",signature=list("crops.class"),
function(object)
{
# appease package checks
. <- NULL
segs <- Map(object@method,unlist(object@betas))
valid_segs <- Filter(function(x) length(x[[2]]) > 1, segs)
if(length(valid_segs) == 0)
{
return(NULL)
}
n <- segs %>% Map(function(.) .[[2]],.) %>% Map(length,.) %>% unlist %>% max
mat <- segs %>%
Map(function(.) .[[2]],.) %>%
Map(function(.) c(.,rep(NA,n-length(.))),.) %>%
Reduce(rbind,.,matrix(nrow=0,ncol=n),right=TRUE)
colnames(mat) <- Map(function(.) paste("cpt.",.,sep=""),1:n) %>% unlist
return(
Map(function(beta,seg) tibble(beta=beta,Qm=seg[[1]],Q=seg[[1]]+beta*length(seg[[2]]),
m=length(seg[[2]])),
unlist(object@betas),
segs) %>%
Reduce(add_row,.,tibble(beta=numeric(),Qm=numeric(),Q=numeric(),m=numeric())) %>%
cbind(.,mat)
)
})
#' Pretty printing for crops results
#'
#' @name print
#'
#' @description Pretty prints a summary of a crops result
#'
#' @docType methods
#'
#' @param x An instance of an S4 class produced by \code{\link{crops}}.
#'
#' @rdname print-methods
#'
#' @aliases print,crops.class-method
#'
#' @seealso \code{\link{crops}}.
#'
#' @examples
#' # see the crops example
#'
setMethod("print",signature=list("crops.class"),
function(x)
{
summary(x)
})
#' Visualisation of data, costs, penalty values and changepoint locations.
#'
#' @name plot
#'
#' @description Plot methods for an S4 object returned by \code{\link{crops}}. The plot can also be combined with the original data if required.
#'
#' @docType methods
#'
#' @param x An instance of an S4 class produced by \code{\link{crops}}.
#' @param y A dataframe containing the locations and values of the data points. The data plot is plotted below, and is aligned with, the changepoint locations.
#'
#' @return A ggplot object. Note - if no changepoints are detected in the penalty interval [beta_min,beta_max], then the value returned is NULL.
#'
#' @rdname plot-methods
#'
#' @aliases plot,crops.class,data.frame-method
#'
#' @seealso \code{\link{crops}}.
#'
#' @examples
#' # see the crops example
#'
#' @export
setMethod("plot",signature=list("crops.class","data.frame"),
function(x,y)
{
p1 <- plot(x)
p2 <- ggplot(data=y) + geom_line(aes(x=x,y=y))
return(plot_grid(p1,p2,ncol=1))
})
#' @name plot
#'
#' @docType methods
#'
#' @param x An instance of an S4 class produced by \code{\link{crops}}.
#'
#' @rdname plot-methods
#'
#' @aliases plot,crops.class,missing-method
#'
#' @examples
#' # see the crops example
#'
#' @export
setMethod("plot",signature=list("crops.class","missing"),
function(x)
{
# appease ggplot and tidyverse
. <- Q <- Qm <- m <- value <- dummy <- NULL
object <- x
df <- segmentations(object)
if(is.null(df))
{
return(NULL)
}
df <- cbind(df,data.frame("dummy"=1:nrow(df)))
p <- df %>%
subset(.,select = -c(beta,Q,Qm,m)) %>%
melt(., id=c("dummy")) %>%
.[complete.cases(.), ] %>%
ggplot(.,aes(x=value,y=dummy)) %>%
add(geom_point()) %>%
add(labs(x="location",y="penalty")) %>%
add(geom_hline(aes(yintercept=dummy))) %>%
add(scale_y_continuous(breaks = seq(1:nrow(df)),labels=signif(df$beta,digits=3),sec.axis = sec_axis( ~.,breaks = seq(1:nrow(df)),labels=signif(df$Qm,digits=4),name="unpenalised cost"))) %>%
add(theme_bw())
return(p)
})
#' Summary of crops result
#'
#' @name summary
#'
#' @description Prints a short summary of a crops result.
#'
#' @docType methods
#'
#' @param object An instance of an S4 class produced by \code{\link{crops}}.
#'
#' @rdname summary-methods
#'
#' @aliases summary,crops.class-method
#'
#' @seealso \code{\link{crops}}.
#'
#' @examples
#' # see the crops example
#'
setMethod("summary",signature=list("crops.class"),
function(object)
{
cat("crops analysis",sep="")
cat('\n',sep="")
cat('\n',sep="")
cat("minimum penalty value = ",min(object@betas)," : maximum penalty value = ",max(object@betas),sep="")
cat('\n',sep="")
segs <- segmentations(object)
if(is.null(segs))
{
cat("no segmentations found in the penalty interval [",min(object@betas),",",max(object@betas),"]",sep="")
cat('\n',sep="")
}
else
{
cat("number of segmentations calculated : ",nrow(segs),sep="")
cat('\n',sep="")
cat("least number of changepoints = ",min(segs$m), " : maximum number of changepoints = ",max(segs$m),sep="")
cat('\n',sep="")
}
invisible()
})
#' Remove duplicate entries from a crops result
#'
#' @name unique
#'
#' @description Removes duplicate entries from a crops result. A duplicate entry is one having the same number of changepoints as another entry.
#' Note that the changepoint locations and the associated penalty and cost values are not taken into consideration. The \code{unique} function can be useful
#' for simplifying plots and the details produced by \code{segmentations}.
#'
#' @docType methods
#'
#' @param x An instance of an S4 class produced by \code{\link{crops}}.
#'
#' @return An instance of the S4 class type \code{crops.class}. This is the same type as produced by the \code{\link{crops}} function.
#'
#' @rdname unique-methods
#'
#' @aliases unique,crops.class-method
#'
#'
setMethod("unique",signature=list("crops.class"),
function(x)
{
# appease package checks
. <- NULL
object<-x
hash_map <- new.env()
keys <- object@betas %>%
unlist %>%
Map(object@method,.) %>%
Map(function(.) .[2],.) %>%
Map(as.character,.)
key_value_pairs <- Map(tuple,keys,object@betas %>% unlist)
hash_map <-
key_value_pairs %>%
Reduce(function(pair,map) {map[[pair[[1]]]] <- pair[[2]]; return(map);},
.,
hash_map,right=TRUE)
object@betas <-
Map(function(key) hash_map[[key]],
hash_map %>% ls) %>%
unname %>%
as.set
return(object)
})
#' Subset crops results based on penalty values
#'
#' @name subset
#'
#' @description Removes entries from a crops result that fall outside a specified range of penalty values.
#' The \code{subset} function can be useful for simplifying plots and the details produced by \code{segmentations}.
#'
#' @docType methods
#'
#' @param x An instance of an S4 class produced by \code{\link{crops}}.
#' @param beta_min A positive numeric value specifying the minimum penalty value for entries in the crops result. Default value is 0.
#' @param beta_max A positive numeric value specifying the maximum penalty value for entries in the crops result. Default value is Inf.
#'
#' @return An instance of the S4 class type \code{crops.class}. This is the same type as produced by the \code{\link{crops}} function.
#'
#' @rdname subset-methods
#'
#' @aliases subset,crops.class-method
#'
#'
setMethod("subset",signature=list("crops.class"),
function(x,beta_min=0,beta_max=Inf)
{
# appease package checks
. <- NULL
object <- x
object@betas %<>%
unlist %>%
Filter(function(.) . <= beta_max & . >= beta_min,.) %>%
as.set
return(object)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.