Pragmastat / R

The R implementation provides all toolkit functions as a lightweight package with minimal dependencies. Each function implements the exact mathematical definition from the toolkit, using R’s built-in vector operations for efficient computation.

Demo usage of R functions:

x <- c(1, 2, 3, 4, 5, 6, 273)
center(x) # 4
spread(x) # 3
volatility(x) # 0.75
precision(x) # 2.2677868380553634

shift(x, x - 10) # 10
ratio(x, x / 10) # 10

x <- c(-3, -2, -1, 0, 1, 2, 3)
disparity(x, x * 10) # 0
disparity(x, x - 10) # 5
disparity(x * 10, x * 10 - 100) # 5

For quick use without installation, copy individual functions directly into scripts. Each function is self-contained and requires only base R:

center <- function(x) {
  n <- length(x)
  if (n == 0) {
    stop("Input vector cannot be empty")
  }
  pairwise_averages <- outer(x, x, "+") / 2
  median(pairwise_averages[upper.tri(pairwise_averages, diag = TRUE)])
}

spread <- function(x) {
  n <- length(x)
  if (n == 0) {
    stop("Input vector cannot be empty")
  }
  if (n == 1) {
    return(0)
  }
  pairwise_diffs <- outer(x, x, "-")
  pairwise_abs_diffs <- abs(pairwise_diffs)
  median(pairwise_abs_diffs[upper.tri(pairwise_abs_diffs, diag = FALSE)])
}

volatility <- function(x) {
  center_val <- center(x)
  if (center_val == 0) {
    stop("Volatility is undefined when Center equals zero")
  }
  spread(x) / abs(center_val)
}

precision <- function(x) {
  n <- length(x)
  if (n == 0) {
    stop("Input vector cannot be empty")
  }
  2 * spread(x) / sqrt(n)
}

med_shift <- function(x, y) {
  if (length(x) == 0 || length(y) == 0) {
    stop("Input vectors cannot be empty")
  }
  pairwise_shifts <- outer(x, y, "-")
  median(pairwise_shifts)
}

med_ratio <- function(x, y) {
  if (length(x) == 0 || length(y) == 0) {
    stop("Input vectors cannot be empty")
  }
  if (any(y <= 0)) {
    stop("All values in y must be strictly positive")
  }
  pairwise_ratios <- outer(x, y, "/")
  median(pairwise_ratios)
}

med_spread <- function(x, y) {
  n <- length(x)
  m <- length(y)
  if (n == 0 || m == 0) {
    stop("Input vectors cannot be empty")
  }
  spread_x <- spread(x)
  spread_y <- spread(y)
  (n * spread_x + m * spread_y) / (n + m)
}

med_disparity <- function(x, y) {
  med_spread_val <- med_spread(x, y)
  if (med_spread_val == 0) {
    return(Inf)
  }
  med_shift(x, y) / med_spread_val
}

For regular use, install the complete package from GitHub. This provides all functions with documentation and examples:

install.packages("remotes") # If 'remotes' is not installed
remotes::install_github("AndreyAkinshin/pragmastat", subdir = "r/pragmastat")