Diff of /R/dirichlet.R [000000] .. [d9ee58]

Switch to unified view

a b/R/dirichlet.R
1
#' Generate a matrix of `n` rows of sets of probabilities 
2
#' generated from the Dirichlet distribution, each row 
3
#' summing to 1. Uses the alternative \eqn{\mu} \eqn{\phi} 
4
#' parameterisation for the Dirichlet distribution, 
5
#' representing means and precision.
6
#' 
7
#' @param n Number of sets of probabilities (defaults to 1)
8
#' @param mu Vector of mean values for each probability in the set
9
#' (defaults to c(0.001, 0.029. 0.7)). Must be greater than 0 and 
10
#' finite, and contain at least two values.
11
#' @param phi Parameter representing precision, where precision is 
12
#' 1/variance. Must be positive and finite. Defaults to 10.
13
#'
14
#' @examples rdirichlet_alt(n = 3, mu = c(0.001, 0.029, 0.7), phi = 10)
15
#' 
16
#' @export 
17
#' 
18
#' @import checkmate
19
#' @importFrom stats rgamma
20
#' 
21
rdirichlet_alt <- function(
22
  n = 1, 
23
  mu = c(0.3, 0.3, 0.3), 
24
  phi = 10
25
) {
26
27
  ### Check and convert inputs
28
29
  # True if n is "close to an integer"
30
  checkmate::assert_integerish(
31
    n, lower = 1, , upper = 10^7, len = 1, any.missing = FALSE
32
  )
33
34
  # mu should be a numeric vector in the range [0, 1)
35
  checkmate::assert_vector(
36
    mu, min.len = 2, strict = TRUE, any.missing = FALSE
37
  )
38
  checkmate::assert_numeric(
39
    mu, lower = 10^-7, upper = 1 - 10^-7
40
  )
41
42
  # phi should be a positive number
43
  checkmate::assert_number(phi, lower = 10^-7, finite = TRUE)
44
45
  # Make n actually an integer
46
  n <- as.integer(n)
47
48
  # Shape parameter (alpha) from mu and phi; alpha_0 = phi
49
  alpha <- phi * mu / mu[1]
50
  no_probs <- length(mu)
51
52
  # Dirichlet is a set of normalised independent gamma(alpha, 1)
53
  draws_mx <- matrix(
54
    stats::rgamma(n * no_probs, alpha), 
55
    ncol = no_probs, 
56
    byrow = TRUE
57
  )
58
  # Each set should sum to 1
59
  draws_mx <- draws_mx / rowSums(draws_mx)
60
61
  return(draws_mx)
62
}
63