#' @name pnp_rangebagging
#' @title Internal function for rangebagging in plug-and-play SDMs.
#' @description This function both fits rangebagging models \insertCite{Drake2015-sb}{S4DM} and projects those distributions to new covariates.
#' @param data dataframe of covariates
#' @param method one of either "fit" or "predict"
#' @param object fitted object returned by a pnp_... function. Only needed when method = "predict"
#' @param v Integer. Number of votes to use in the aggregation, default is 100.
#' @param d Integer. Number of dimensions (i.e. covariates) to use in aggregations, default is 2.
#' @param p Numeric. Fraction of observations (i.e. occurrences) to use in each replicate aggregation. Default is 0.5
#' @details For fitting, an object is not required (and will be ignored). For prediction, parameters v,p,and d are not needed and will be ignored.
#' @import geometry
#' @keywords internal
#' @references
#' \insertAllCited{}
pnp_rangebagging <- function(data, method, object = NULL, v = 100, d = 2, p = 0.5){
#Code to check inputs
#Code for fitting
if(method == "fit"){
models <- list()
n <- dim(data)
for(i in 1:v){
#randomly sample d covariates
vars <- sample.int(n[2],
size = d,
replace = FALSE)
x0 <- data[,vars]
if(d == 1) {
#sample some proportion of occurrences, specified by p
x1 <- x0[sample(n[1],
ceiling(p * n[1]),
replace = FALSE)]
#for one d, model is just min/max
models[[i]] <- list(vars = vars,
endpoints = c(min(x1),
max(x1)),
data=x1)
}else{
x1 <- x0[sample(n[1],
ceiling(p*n[1]),
replace=FALSE),]
#THIS DOESNT REALLY DO ANYTHING USEFUL SINCE WE REFIT CONVULL IN FXN RB
idx <- unique(as.vector(convhulln(x1, options='Pp')))
endpoints <- x1[idx,]
models[[i]] <- list(vars = vars,
endpoints = endpoints,
data = unique(x1))
}
}
model <- list(rangebag_models = models,
method = "rangebagging")
class(model) <- "pnp_estimate"
return(model)
}
#Code for predicting
if(method == "predict"){
# set parameters
v <- length(object$rangebag_models)
d <- ifelse(is.null(dim(object$rangebag_models[[1]]$endpoints)), 1, dim(object$rangebag_models[[1]]$endpoints)[2])
n <- dim(data)
# make empty output
prediction <- numeric(n[1])
# remove any variables without variation, since rangebagging requires variation
# actually, this variation should only be needed for fitting, no predicting
# sds <- apply(X = data,MARGIN = 2,FUN = sd)
#
# if(any(sds == 0)){
#
# message(length(which(sds==0)), " variables have no variation, dropping variables ", names(sds)[which(sds==0)])
#
# preds_to_remove <- names(sds)[which(sds==0)]
#
# preds_to_keep <- names(sds)[which(sds!=0)]
#
# data <- data[preds_to_keep]
#
# n <- dim(data)
#
# # clean dimensionality
#
# if(n[2] < d){
#
# message("Updating dimensionality")
#
# d <- n[2]
#
# }
}
#Do bagging
for(i in 1:v){
#print(i) # counter for troubleshooting
if(d == 1){
test.pts <-
(object$rangebag_models[[i]]$endpoints[1] <
data[,object$rangebag_models[[i]]$vars]) &
(data[,object$rangebag_models[[i]]$vars] <
object$rangebag_models[[i]]$endpoints[2])
prediction <- prediction + test.pts
}else{
test.dat <- as.matrix(data[,object$rangebag_models[[i]]$vars])
tri.pts <- tsearchn(x = as.matrix(object$rangebag_models[[i]]$data),
t = delaunayn(object$rangebag_models[[i]]$data),
xi = test.dat)
#tri.pts <- tsearchn(as.matrix(models[[i]]$endpoints), delaunayn(models[[i]]$endpoints), test.dat)
test.pts <- !is.na(tri.pts$p[,1])
prediction <- prediction + test.pts
}
}
prediction <- (prediction/v)
return(log(prediction))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.