#'
#' @title Sorting and reordering data frames, vectors or matrices
#' @description Sorts a data frame using a specified alphanumeric or numeric sort key
#' @details Serverside assign function dataFrameSortDS is called by
#' clientside function ds.dataFrameSort. A vector or a matrix can be
#' added to, or coerced into, a data frame (using function [ds.dataFrame])
#' and this means that they too can be sorted/reordered using ds.dataFrameSort.
#' Fundamentally, the function [ds.dataFrameSort] will sort a specified
#' data frame on the serverside using a sort key also on the serverside.
#' For more details see help for the clientside function: [ds.dataFrameShort]
#' @param df.name a character string providing the name for the serverside
#' data.frame to be sorted. This parameter is fully specified by the equivalent
#' argument in ds.dataFrameShort and further details can be found at
#' help("ds.dataFrameSort").
#' @param sort.key.name a character string providing the name for the sort key.
#' This will be a serverside vector which may sit inside the data frame to be
#' sorted or independently in the serverside analysis environment. But, if it
#' sits outside the data frame it must then be the same length as the data frame.
#' This parameter is fully specified by the equivalent argument
#' in ds.dataFrameShort and further details can be found at help("ds.dataFrameSort").
#' @param sort.descending logical, if TRUE the data.frame will be sorted
#' by the sort key in descending order. Default = FALSE (sort order ascending).
#' This parameter is fully specified by the equivalent argument
#' in ds.dataFrameShort and further details can be found at help("ds.dataFrameSort").
#' @param sort.method A character string taking one of the values: "default",
#' "d", "alphabetic", "a", "numeric", "n", or NULL. Default value is "default".
#' This parameter is fully specified by the equivalent argument
#' in ds.dataFrameShort and further details can be found at help("ds.dataFrameSort").
#' @return the appropriately re-sorted data.frame will be written to the serverside
#' R environment as a data.frame named according to the <newobj> argument(or with
#' default name 'dataframesort.newobj') if no name is specified
#' @author Paul Burton, with critical error identification by
#' Leire Abarrategui-Martinez, for DataSHIELD Development Team, 2/4/2020
#' @export
#'
dataFrameSortDS <- function(df.name=NULL,sort.key.name=NULL,sort.descending,sort.method){
# Check Permissive Privacy Control Level.
dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana'))
#########################################################################
# DataSHIELD MODULE: CAPTURE THE nfilter SETTINGS
thr <- dsBase::listDisclosureSettingsDS()
#nfilter.tab <- as.numeric(thr$nfilter.tab)
#nfilter.glm <- as.numeric(thr$nfilter.glm)
nfilter.subset <- as.numeric(thr$nfilter.subset)
nfilter.string <- as.numeric(thr$nfilter.string)
nfilter.stringShort <- as.numeric(thr$nfilter.stringShort)
#nfilter.kNN <- as.numeric(thr$nfilter.kNN)
#datashield.privacyLevel <- as.numeric(thr$datashield.privacyLevel)
#########################################################################
# DISCLOSURE TRAPS
df.name.chars <- strsplit(df.name,split="")
if(length(df.name.chars[[1]])>nfilter.stringShort){
studysideMessage <- "df.name argument could hide active code - please use shorter name"
stop(studysideMessage, call. = FALSE)
}
sort.key.name.chars <- strsplit(sort.key.name,split="")
if(length(sort.key.name.chars[[1]])>nfilter.stringShort){
studysideMessage <- "sort.key.name argument could hide active code - please use shorter name"
stop(studysideMessage, call. = FALSE)
}
df.name.2 <- paste0("data.frame(",df.name,")")
df2sort <- eval(parse(text=df.name.2), envir = parent.frame())
sort.key <- eval(parse(text=sort.key.name), envir = parent.frame())
# TYPE CHECK
if(any(class(sort.key) %in% 'factor')){
studysideMessage <- "specified sort.key variable is of type 'factor'"
stop(studysideMessage, call. = FALSE)
}
# DISCLOSURE TRAPS
if(dim(df2sort)[1]<nfilter.subset){
studysideMessage <- "specified data.frame to sort is shorter than minimum subset size"
stop(studysideMessage, call. = FALSE)
}
if(length(sort.key)<nfilter.subset){
studysideMessage <- "specified sort.key variable is shorter than minimum subset size"
stop(studysideMessage, call. = FALSE)
}
if((sort.method=="alphabetic") || ((sort.method=="default") && is.character(sort.key))){
sort.key.2.use<-as.character(sort.key)
key.order <- stringr::str_order(sort.key.2.use, decreasing = sort.descending, na_last = TRUE)
}else{
#PUT na.last in here
sort.key.2.use<-as.numeric(sort.key)
if(sort.descending)
{
key.ranks <- rank(sort.key.2.use,ties.method="average",na.last=FALSE)
key.ranks <-(length(key.ranks)+1)-key.ranks
}else{
key.ranks <- rank(sort.key.2.use,ties.method="average",na.last=TRUE)
}
key.order <- order(key.ranks)
}
df.sorted <- df2sort[key.order,]
return(df.sorted)
}
# ASSIGN FUNCTION
# dataFrameSortDS
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.