Skip to content

Instantly share code, notes, and snippets.

@njtierney
Last active September 20, 2024 10:35
Show Gist options
  • Save njtierney/a3565ff9525b7fa175f3a52e2881d692 to your computer and use it in GitHub Desktop.
Save njtierney/a3565ff9525b7fa175f3a52e2881d692 to your computer and use it in GitHub Desktop.
sample.int <- function(n, size = n, replace = FALSE, prob = NULL,
prob_method = c("sequential", "marginal", "poisson"),
useHash = (n > 1e7 && !replace && is.null(prob) && size <= n/2)){
stopifnot(length(n) == 1L)
replace_or_no_prob <- is.null(prob) || replace
if (replace_or_no_prob){
size <- size %||% n
if (useHash) {
## will work with size > n/2 but may be slow.
stopifnot(is.null(prob), !replace)
.Internal(sample2(n, size))
} else {
.Internal(sample(n, size, replace, prob))
}
} else {
size <- size %||% sum(prob)
if (length(prob) != n) {
stop("incorrect number of probabilities")
}
prob_method <- match.arg(prob_method)
switch(
prob_method,
sequential = .Internal(sample(n, size, replace, prob)),
marginal = sample.pps(n, size, prob),
# using `sample()` to permute selected items
poisson = sample(which(runif(n) <= prob * size/sum(prob)))
)
}
}
@njtierney
Copy link
Author

njtierney commented Sep 19, 2024

Potential refactor removing use of else and only using if

sample.int <- function(n, size = n, replace = FALSE, prob = NULL,
                       prob_method = c("sequential", "marginal", "poisson"),
                       useHash = (n > 1e7 && !replace && is.null(prob) && size <= n/2)){
  
  stopifnot(length(n) == 1L)
  if (replace || is.null(prob)) {
    size <- size %||% n
    if (useHash) {
      ## will work with size > n/2 but may be slow.
      stopifnot(is.null(prob), !replace)
      return(.Internal(sample2(n, size)))
    } 
      return(.Internal(sample(n, size, replace, prob)))
  }
    size <- size %||% sum(prob)
    if (length(prob) != n) {
      stop("incorrect number of probabilities")
    }
    prob_method <- match.arg(prob_method)
    switch(
      prob_method,
      sequential = .Internal(sample(n, size, replace, prob)),
      marginal = sample.pps(n, size, prob),
      # using `sample()` to permute selected items 
      poisson = sample(which(runif(n) <= prob * size/sum(prob)))
    )
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment