R/dpqrdist.R

Defines functions is_discrete_dist xcbeta xqbeta xpbeta xcnbinom xqnbinom xpnbinom xcgeom xqgeom xpgeom xcpois xqpois xppois xcbinom xqbinom xpbinom xcf xqf xpf xcchisq xqchisq xpchisq xct xqt xpt xcgamma xqgamma xpgamma plot_multi_dist dpqrdist

Documented in dpqrdist xcbeta xcbinom xcchisq xcf xcgamma xcgeom xcnbinom xcpois xct xpbeta xpbinom xpchisq xpf xpgamma xpgeom xpnbinom xppois xpt xqbeta xqbinom xqchisq xqf xqgamma xqgeom xqnbinom xqpois xqt

# Note: one of d, p, q, or n must be a **named** argument.  This allows other things to 
# be in ... without causing issues for the d/p/q/r function called.
#' Distribution wrapper
#' 
#' Utility function wrapping up the d/p/q/r distribution functions
#' 
#' @param dist a character description of a distribution, for example 
#'   `"norm"`, `"t"`, or `"chisq"`
#' @param type one of `"x"`, `"p"`, `"q"`, or `"r"`
#' @param ... additional arguments passed on to underlying distribution function.
#'   Note that one of `d`, `p`, `q`, or `n` must 
#'   be a named argument in ...
#' @export
#' @examples
#' # 3 random draws from N(1,2)
#' dpqrdist("norm", "r", n = 3, mean = 1, sd = 2)
#' # These should all be the same
#' dpqrdist("norm", "d", x = 0) == dnorm(x = 0)
#' dpqrdist("norm", "p", q = 0, mean = 1, sd = 2) == pnorm(q = 0, mean = 1, sd = 2)
#' dpqrdist("norm", "q", p = 0.5, mean = 1, sd = 2) == qnorm(p = 0.5, mean = 1, sd = 2)
#' @importFrom purrr possibly map_dbl
 
dpqrdist <- function( dist, type = c("d","p","q","r"), ...) {
  type <- match.arg(type)
  dots <- list(...)
  distFunName <- paste0(type, dist)
  distFun <- rlang::as_function(distFunName)
  dist_dots <- dots[names(dots) %in% names(formals(distFunName))]
  first_name <- as.name(names(formals(distFunName))[[1]])
  first_val <- dist_dots[[first_name]]
  dist_dots[[first_name]] <- NULL
  # for the sake of some distribution functions that throw errors, for example when p = 0 or 1
  # we convert errors into NaNs [Note: is.na(NaN) is TRUE]
  dpqrfun <- purrr::possibly(distFun, otherwise = NaN)
  # make sure an output value is computed for each input, even if some throw errors
  res <- do.call(sapply, c(list(first_val, dpqrfun), dist_dots))
  if (length(res) > 0 & all(is.na(res))) {
    stop("No values could be computed. Did you specify all the required parameters?")
  }
  res
}


#' Illustrated probability calculations from distributions
#' 
#' Illustrated probability calculations from distributions
#' 
#' @param dist a character description of a distribution, for example 
#'   `"norm"`, `"t"`, or `"chisq"`
#' @param q a vector of quantiles
#' @param plot a logical indicating whether a plot should be created
#' @param verbose a logical
#' @param invisible a logical
#' @param digits the number of digits desired
#' @param xlim x limits
#' @param ylim y limits
# #' @param vlwd width of vertical lines
# #' @param vcol color of vertical lines
# #' @param rot angle for rotating text indicating probability
#' @param resolution Number of points used for detecting discreteness and generating plots.  
#'        The default value of 5000 should work well except for discrete distributions
#'        that have many distinct values, especially if these values are not evenly spaced.
#' @param ... Additional arguments, typically for fine tuning the plot.
#' @param return If `"plot"`, return a plot.  If `"values"`, return a vector of numerical values.
#' @param refinements A list of refinements to the plot.  See [ggformula::gf_refine()].
#' @details The most general function is `pdist` which can work with 
#' any distribution for which a p-function exists.  As a convenience, wrappers are 
#' provided for several common distributions.
#' @return A vector of probabilities; a plot is printed as a side effect.
#' @examples
#' pdist("norm", -2:2)
#' pdist("norm", seq(80,120, by = 10), mean = 100, sd = 10)
#' pdist("chisq", 2:4, df = 3)
#' pdist("f", 1, df1 = 2, df2 = 10)
#' pdist("gamma", 2, shape = 3, rate = 4)
#' @export

pdist <- function (dist = "norm", q, plot = TRUE, verbose = FALSE, invisible = FALSE, 
                   digits = 3L, 
                   xlim, ylim,
                   resolution = 500L,
                   return = c("values", "plot"),
                   ...,
                   refinements = list())
{
  
  return <- match.arg(return)
  
  dots <- list(...)
  
  # if (is.null(vlwd)) {
  #   vlwd <- if (is_discrete_dist( dist, ... )) 0 else 2
  # }
  
  p <- dpqrdist(dist, type = "p", q = q, ...) 
  
  if (verbose) {
    cat("Verbose output not yet implemented.\n")
  }
  
  res_plot <-
    do.call(
      gf_refine,
      c(list(
        plot_multi_dist(
          dist = dist, p = p, 
          xlim = xlim, ylim = ylim, 
          digits = digits, 
          resolution = resolution,
          ...)),
        refinements)
    )
  
  if (return == "plot") {
    return(res_plot)
  }
  if (plot) {
    print(res_plot)
  }
  if (invisible) { 
    return(invisible(p))
  }
  return(p)
}

#' Illustrated quantile calculations from distributions
#' 
#' Illustrated quantile calculations from distributions
#' 
#' @param dist a character description of a distribution, for example 
#'   `"norm"`, `"t"`, or `"chisq"`
#' @param p a vector of probabilities
#' @param plot a logical indicating whether a plot should be created
#' @param verbose a logical
#' @param invisible a logical
#' @param digits the number of digits desired
#' @param xlim x limits.  By default, these are chosen to show the central 99.8\% 
#'   of the distribution.
#' @param ylim y limits
# #' @param vlwd width of vertical lines
# #' @param vcol color of vertical lines
# #' @param rot angle for rotating text indicating probability
#' @param resolution number of points used for detecting discreteness and generating plots.  
#'   The default value of 5000 should work well except for discrete distributions
#'   that have many distinct values, especially if these values are not evenly spaced.
#' @param refinements A list of refinements to the plot.  See [ggformula::gf_refine()].
#' @param ... additional arguments, including parameters of the distribution
#'   and additional options for the plot.  To help with name collisions (eg `size` for binomial 
#'   distributions and `shape` for gamma distributions), argument names beginning `plot_` will
#'   be renamed to remove `plot_` and passed only to the plot.  The unprefixed version will 
#'   used as a parameter for the the distribution.
#' @param return If `"plot"`, return a plot.  If `"values"`, return a vector of numerical values.
#' @details The most general function is `qdist` which can work with 
#' any distribution for which a q-function exists.  As a convenience, wrappers are 
#' provided for several common distributions.
#' 
#' @return a vector of quantiles; a plot is printed as a side effect
#' @examples
#' qdist("norm", seq(.1, .9, by = 0.10), 
#'       title = "Deciles of a normal distribution", show.legend = FALSE,
#'       pattern = "rings")
#' xqnorm(seq(.2, .8, by = 0.20), mean = 100, sd = 10)
#' qdist("unif", .5)
#' xqgamma(.5, shape = 3, scale = 4)
#' xqgamma(.5, shape = 3, scale = 4, color = "black")
#' xqbeta(.5, shape1 = .9, shape2 = 1.4, dlwd = 1)
#' xqchisq(c(.25,.5,.75), df = 3)
#' xcbinom(c(0.80, 0.90), size = 1000, prob = 0.40)
#' # displayed as if continuous
#' xcbinom(c(0.80, 0.90), size = 5000, prob = 0.40)
#' xpbinom(c(480, 500, 520), size = 1000, prob = 0.48)
#' xpbinom(c(40, 60), size = 100, prob = 0.5)
#' xqpois(c(0.25, 0.5, 0.75), lambda = 12)
#' xcpois(0.50, lambda = 12)
#' xcpois(0.50, lambda = 12, refinements = list(scale_color_brewer(type = "qual", palette = 5)))
#' @export 

qdist <- function (dist = "norm", p, plot = TRUE, verbose = FALSE, invisible = FALSE, 
                   resolution = 500L,
                   digits = 3L, 
                   xlim, ylim,
                   return = c("values", "plot"),
                   refinements = list(),
                   ...
)
{
  return = match.arg(return)
  dots <- list(...)
  
  # if (is.null(vlwd)) {
  #   vlwd <- if (is_discrete_dist( dist, ... )) 0 else 2
  # }
  # 
  q <- dpqrdist(dist, type = "q", p = p, ...) 
  # adjust probs for discrete dists where requested p's might not be (exactly) possible
  p <- dpqrdist(dist, type = "p", q = q, ...)  
  if (verbose) {
    cat("Verbose output not yet implemented.\n")
  }
  
  res_plot <-  
    do.call(
      ggformula::gf_refine,
      c(list(
        plot_multi_dist(
          dist = dist, p = p, 
          xlim = xlim, ylim = ylim, 
          digits = digits, 
          resolution = resolution,
          ...)
      ), refinements)
    )
  
  if (return == "plot") return (res_plot)
  
  if (plot) {
    print(res_plot)
  }
  if (invisible) { 
    return(invisible(q))
  }
  return(q)
}


utils::globalVariables(c("i", "name", "p_all"))

plot_multi_dist <- 
  function(dist, p, q, xlim, ylim, digits = 3L, resolution = 500L,
           lower.tail = TRUE,
           dlwd = 0, 
           pattern = c("stripes", "rings"),
           ...) 
  {
    dots <- list(...)
    pattern <- match.arg(pattern)
    
    plot_dots <- dots[ ! names(dots) %in% names(formals(paste0("p",dist))) ]
    dist_dots <- dots[   names(dots) %in% names(formals(paste0("p",dist))) ]
    
    discrete <- do.call(is_discrete_dist, c(list(dist), dist_dots))
    
    if (missing(p)) {
      if (missing(q)) { stop( "one of p or q must be specified") }
      q <- sort(q)
      p <- dpqrdist(dist, type = "p", q = q, lower.tail = lower.tail, ...)
      p_less <- dpqrdist(dist, type = "p", q = q, lower.tail = TRUE, ...)
    } else {
      if (!missing(q)) {
        warning("Both p and q were specified.  I'm using p")
      }
      p <- sort(p)
      q <- sort(dpqrdist(dist, type = "q", p = p, lower.tail = lower.tail, ...))
      p_less <- dpqrdist(dist, type = "p", q = q, ...)
    }
    
    names(plot_dots) <- gsub("plot_", "", names(plot_dots)) 
    if ('lty' %in% names(plot_dots)) { plot_dots$linetype <- plot_dots$lty; plot_dots$lty <- NULL }
    if ('pch' %in% names(plot_dots)) { plot_dots$shape <- plot_dots$pch;    plot_dots$pch <- NULL }
    if ('cex' %in% names(plot_dots)) { plot_dots$size <- plot_dots$cex;     plot_dots$cex <- NULL }
    
    if (! 'xlab' %in% names(plot_dots)) { plot_dots$xlab <- "" }
    
    if (missing(xlim) || is.null(xlim)) {
      xlim_opts <- dpqrdist(dist, type = "q", p = c(0, 0.0001, 0.001, 0.01, 0.99, 0.999, 0.9999, 1), ...)
      if (is.matrix(xlim_opts)) {
        xlim <- c(min(xlim_opts[, 4], na.rm = TRUE), max(xlim_opts[,5], na.rm = TRUE))
      } else {
        xlim <- xlim_opts[4:5]
      }
      
      # extend range if it doesn't extend too far
      mid_width <- diff(xlim)
      xlim[1] <- xlim_opts[min(which(xlim[2] - xlim_opts < 1.8 * mid_width), na.rm = TRUE)]
      xlim[2] <- xlim_opts[max(which(xlim_opts - xlim[1] < 1.8 * mid_width), na.rm = TRUE)]
    }
    
    if (discrete) {
      xdata <- unique(dpqrdist(dist, type = "q", p = ppoints(resolution), ...))
      step = min(diff(xdata))
      xlim = c(-step/2, step/2) + xlim  # widen by half step in each direction
      fill <- seq( min(xdata) -1.5 * step , max(xdata) + 1.5*step, length.out = resolution)
      xdata <- c(xdata, fill) 
      xdata <- dpqrdist(dist, type = "q", p = dpqrdist(dist, type = "p", q = xdata, ...), ...)
      xdata <- sort(unique(xdata))
    } else {
      xdata <- seq(xlim[1], xlim[2], length.out = resolution)
      xdata <- dpqrdist(dist, type = "q", p = dpqrdist(dist, type = "p", q = xdata, ...), ...)
      xdata <- sort(unique(xdata))
    }
    
    # not a fix: xdata <- sort(xdata) 
    ydata <- dpqrdist(dist, type = "d", x = xdata, ...)
    ymax <- 1.1 * quantile(ydata, 0.95, na.rm = TRUE)
    if (missing(ylim)) {
      ylim = c(0, 1.4 * ymax)  # quantile(ydata, 0.95, na.rm = TRUE))
      # print(ylim)
    }
    
    # this could be funny if limits don't span q
    p_less <- sort(unique(c(0, p_less, 1)))
    q <- dpqrdist(dist, type = "q", p = p_less, ...) #  c(xlim[1], q, xlim[2])
    
    # if (discrete) {
    #   if (is.null(plot_dots$pch)) plot_dots$pch = 16
    # }
    
    
    
    # args <- c(
    #   list(
    #     ydata ~ xdata, 
    #     xlim = xlim, ylim = ylim, 
    #     xlab = "", 
    #     ylab = if (discrete) "probability" else "density" 
    #   ),
    #   plot_dots
    # )
    # 
    # res_plot <- do.call("xyplot", args)
    
    Groups <- 
      tibble::tibble(p = diff(p_less)) |>
      mutate(
        i = 1 : n(),
        name = if (pattern == "stripes") LETTERS[i] else LETTERS[ceiling(1 + abs(i - mean(i)))]
      ) |> 
      group_by(name) |>
      mutate(
        p_all = sum(p),
        label = paste(first(name), ":", formatC(p_all, format = "f", digits = digits), sep = "")
      )
    
    if (length(xdata) != length(ydata)) {
      stop("It looks like you have multiple parameter settingss specified for your distribution. 
           Plotting only works for one parameter setting.")
    }
    
    if (discrete) { 
      # q <- tail(q, -1)
      Ddensity <- 
        tibble::tibble(
          x = xdata, density = ydata, 
          group = sapply(xdata, function(x) {sum(x > q, na.rm = TRUE)})
        ) |>
        mutate(
          group = pmax(1, group),
          probability = Groups$label[group] 
        ) 
      
      # print(Ddensity)
      
      plot <- 
        do.call(
          gf_point, 
          c(list(density ~ x, color = ~ probability, group = ~ group, fill = ~ probability,
                 data = Ddensity), plot_dots)) |>
        gf_segment(density + 0 ~ x + x) |>
        gf_labs(x = "", y = "probability") |>
        gf_refine(
        scale_fill_viridis_d(end = 0.9),
        scale_color_viridis_d(end = 0.9)
      )
    
  } else {
    Ddensity <- 
      tibble::tibble(
        x = xdata, density = ydata, 
        group = sapply(xdata, function(x) {sum(x > q, na.rm = TRUE)})
      ) |>
      mutate(
        group = pmax(1, group),
        probability = Groups$label[group] # factor(group, labels = labels[sort(unique(group))])
      ) |>
      dplyr::filter(!is.na(probability))  # avoids issues when xlim is wider than support
    
    plot <- 
      do.call(gf_area, 
              c(list(density ~ x, fill = ~ probability, 
                     group = ~ group, data = Ddensity), plot_dots)) |>
      gf_refine(
        scale_fill_viridis_d(end = 0.9),
        scale_color_viridis_d(end = 0.9)
      )
  }  
  return(plot)
}


#' @rdname pdist
#' @inheritParams stats::pgamma 
#' @param log.p A logical indicating whether probabilities should be 
#'   returned on the log scale.
#' @seealso [qdist()], [xpnorm()], [xqnorm()].
#' @export
xpgamma <- function(q, shape, rate = 1, scale = 1/rate, 
                    lower.tail = TRUE, log.p = FALSE, ...) {
  if (!missing(rate) && !missing(scale)) {
    if (abs(rate * scale - 1) < 1e-15) 
      warning("specify 'rate' or 'scale' but not both")
    else stop("specify 'rate' or 'scale' but not both")
  }
  pdist("gamma", q = q, shape = shape, scale = scale,
        lower.tail = lower.tail, log.p = log.p, ...)
}
#' @rdname qdist
#' @inheritParams stats::qgamma
#' @param log.p A logical indicating whether probabilities should be 
#'   returned on the log scale.
#' @export
xqgamma <- function(p, shape, rate = 1, scale = 1/rate, 
                    lower.tail = TRUE, log.p = FALSE, ...) {
  if (!missing(rate) && !missing(scale)) {
    if (abs(rate * scale - 1) < 1e-15) 
      warning("specify 'rate' or 'scale' but not both")
    else stop("specify 'rate' or 'scale' but not both")
  }
  qdist("gamma", p = p, shape = shape, scale = scale,
        lower.tail = lower.tail, log.p = log.p,
        ...)
}
#' @rdname cdist
#' @inheritParams stats::qgamma
#' @param log.p A logical indicating whether probabilities should be 
#'   returned on the log scale.
#' @export
xcgamma <- function(p, shape, rate = 1, scale = 1/rate, 
                    lower.tail = TRUE, log.p = FALSE, ...) {
  if (!missing(rate) && !missing(scale)) {
    if (abs(rate * scale - 1) < 1e-15) 
      warning("specify 'rate' or 'scale' but not both")
    else stop("specify 'rate' or 'scale' but not both")
  }
  cdist("gamma", q = q, shape = shape, scale = scale,
        lower.tail = lower.tail, log.p = log.p,
        ...)
}

#' @rdname pdist
#' @inheritParams stats::pt
#' @param log.p A logical indicating whether probabilities should be 
#'   returned on the log scale.
#' @export
xpt <- function(q, df , ncp, lower.tail = TRUE, log.p = FALSE, ...)  
  if (missing(ncp)) {
    pdist("t", q = q, df = df, lower.tail = lower.tail, 
          log.p = log.p, ...)
  } else {
    pdist("t", q = q, df = df, ncp = ncp, lower.tail = lower.tail, 
          log.p = log.p, ...)
  }
#' @rdname qdist
#' @inheritParams stats::qt
#' @param log.p A logical indicating whether probabilities should be 
#'   returned on the log scale.
#' @export
xqt <- function(p, df , ncp, lower.tail = TRUE, log.p = FALSE, ...)  
  if (missing(ncp)) {
    qdist("t", p = p, df = df, lower.tail = lower.tail, 
          log.p = log.p, ...)
  } else {
    qdist("t", p = p, df = df, ncp = ncp, lower.tail = lower.tail, 
          log.p = log.p, ...)
  }



#' @rdname cdist
#' @inheritParams stats::pt
#' @param log.p A logical indicating whether probabilities should be 
#'   returned on the log scale.
#' @export
xct <- function(p, df , ncp, lower.tail = TRUE, log.p = FALSE, ...)  
  if (missing(ncp)) {
    cdist("t", p = p, df = df, lower.tail = lower.tail, 
          log.p = log.p, ...)
  } else {
    cdist("t", p = p, df = df, ncp = ncp, lower.tail = lower.tail, 
          log.p = log.p, ...)
  }

#' @rdname pdist
#' @export
xpchisq <- function(q, df, ncp = 0, lower.tail = TRUE, log.p = FALSE, ...)   
  pdist("chisq", q = q, df = df, ncp = ncp, lower.tail = lower.tail, 
        log.p = log.p, ...)
#' @rdname qdist
#' @export
xqchisq <- function(p, df, ncp = 0, lower.tail = TRUE, log.p = FALSE, ...)   
  qdist("chisq", p = p, df = df, ncp = ncp, lower.tail = lower.tail, 
        log.p = log.p, ...)
#' @rdname cdist
#' @export
xcchisq <- function(p, df, ncp = 0, lower.tail = TRUE, log.p = FALSE, ...)   
  cdist("chisq", p = p, df = df, ncp = ncp, lower.tail = lower.tail, 
        log.p = log.p, ...)

#' @rdname pdist
#' @inheritParams stats::pf
#' @export
xpf <- function(q, df1, df2, lower.tail = TRUE, log.p = FALSE, ...)  
  pdist("f", q = q, df1 = df1, df2 =df2, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname qdist
#' @inheritParams stats::qf
#' @export
xqf <- function(p, df1, df2, lower.tail = TRUE, log.p = FALSE, ...)  
  qdist("f", p = p, df1 = df1, df2 =df2, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname cdist
#' @inheritParams stats::qf
#' @export
xcf <- function(p, df1, df2, lower.tail = TRUE, log.p = FALSE, ...)  
  cdist("f", p = p, df1 = df1, df2 =df2, 
        lower.tail = lower.tail, log.p = log.p, ...)


#' @rdname pdist
#' @inheritParams stats::pbinom
#' @export
xpbinom <- function(q, size, prob, lower.tail = TRUE, log.p = FALSE, ...)  
  pdist("binom", q = q, size = size, prob = prob, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname qdist
#' @inheritParams stats::qbinom
#' @export
xqbinom <- function(p, size, prob, lower.tail = TRUE, log.p = FALSE, ...)  
  qdist("binom", p = p, size = size, prob = prob, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname cdist
#' @inheritParams stats::qbinom
#' @export
xcbinom <- function(p, size, prob, lower.tail = TRUE, log.p = FALSE, ...)  
  cdist("binom", p = p, size = size, prob = prob, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname pdist
#' @inheritParams stats::ppois
#' @export
xppois <- function(q, lambda, lower.tail = TRUE, log.p = FALSE, ...)  
  pdist("pois", q = q, lambda = lambda, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname qdist
#' @inheritParams stats::qpois
#' @export
xqpois <- function(p, lambda, lower.tail = TRUE, log.p = FALSE, ...)  
  qdist("pois", p = p, lambda = lambda, 
        lower.tail = lower.tail, log.p = log.p, ...)


#' @rdname cdist
#' @inheritParams stats::qpois
#' @export
xcpois <- function(p, lambda, lower.tail = TRUE, log.p = FALSE, ...)  
  cdist("pois", p = p, lambda = lambda, 
        lower.tail = lower.tail, log.p = log.p, ...)


#' @rdname pdist
#' @inheritParams stats::pgeom
#' @export
xpgeom <- function(q, prob, lower.tail = TRUE, log.p = FALSE, ...)  
  pdist("geom", q = q, prob = prob, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname qdist
#' @inheritParams stats::qgeom
#' @export
xqgeom <- function(p, prob, lower.tail = TRUE, log.p = FALSE, ...)  
  qdist("geom", p = p, prob = prob, 
        lower.tail = lower.tail, log.p = log.p, ...)


#' @rdname cdist
#' @inheritParams stats::qgeom
#' @export
xcgeom <- function(p, prob, lower.tail = TRUE, log.p = FALSE, ...)  
  cdist("geom", p = p, prob = prob, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname pdist
#' @inheritParams stats::pnbinom
#' @export
xpnbinom <- function(q, size, prob, mu, lower.tail = TRUE, log.p = FALSE, ...)  
  pdist("nbinom", q = q, size = size, prob =prob, mu = mu, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname qdist
#' @inheritParams stats::qnbinom
#' @export
xqnbinom <- function(p, size, prob, mu, lower.tail = TRUE, log.p = FALSE, ...)  
  qdist("nbinom", p = p, size = size, prob =prob, mu = mu, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname cdist
#' @inheritParams stats::qnbinom
#' @export
xcnbinom <- function(p, size, prob, mu, lower.tail = TRUE, log.p = FALSE, ...)  
  cdist("nbinom", p = p, size = size, prob =prob, mu = mu, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname pdist
#' @inheritParams stats::pbeta
#' @export
xpbeta <- function(q, shape1, shape2, ncp = 0, 
                   lower.tail = TRUE, log.p = FALSE, ...)  
  pdist("beta", q = q, shape1 = shape1, shape2 = shape2, ncp = 0, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname qdist
#' @inheritParams stats::qbeta
#' @export
xqbeta <- function(p, shape1, shape2, ncp = 0, 
                   lower.tail = TRUE, log.p = FALSE, ...)  
  qdist("beta", p = p, shape1 = shape1, shape2 = shape2, ncp = 0, 
        lower.tail = lower.tail, log.p = log.p, ...)

#' @rdname cdist
#' @inheritParams stats::qbeta
#' @export
xcbeta <- function(p, shape1, shape2, ncp = 0, 
                   lower.tail = TRUE, log.p = FALSE, ...)  
  cdist("beta", p = p, shape1 = shape1, shape2 = shape2, ncp = 0, 
        lower.tail = lower.tail, log.p = log.p, ...)


is_discrete_dist <- function(dist, resolution = 100L, ... ) {
  q <- dpqrdist(dist, type = "q", p = ppoints(resolution), ...) 
  # continuous dists should have all unique values
  # discrete dists will typically have many ties
  # discrete dists with many values may look continuous
  length(unique(q)) / length(q) <= 0.95
} 

Try the mosaic package in your browser

Any scripts or data that you put into this service are public.

mosaic documentation built on Nov. 10, 2023, 1:11 a.m.