Skip to contents

Construct test objects in a unified way.

Usage

pmt(key, ...)

pmts(
  which = c("all", "onesample", "twosample", "ksample", "multcomp", "paired", "rcbd",
    "association", "table")
)

define_pmt(
  inherit = c("twosample", "ksample", "paired", "rcbd", "association", "table"),
  statistic,
  rejection = c("lr", "l", "r"),
  scoring = "none",
  n_permu = 10000,
  name = "User-Defined Permutation Test",
  alternative = NULL,
  depends = character(),
  plugins = character(),
  includes = character()
)

Arguments

key

a character string specifying the test. Check pmts() for valid keys.

...

extra parameters passed to the constructor.

which

a character string specifying the desired tests.

inherit

a character string specifying the type of permutation test.

statistic

definition of the test statistic. See Details.

rejection

a character string specifying where the rejection region is.

scoring

one of: - a character string in c("none", "rank", "vw", "expon") specifying the scoring system - a function that takes a numeric vector and returns an equal-length score vector

n_permu

an integer indicating number of permutations for the permutation distribution. If set to 0, all permutations will be used.

name

a character string specifying the name of the test.

alternative

a character string describing the alternative hypothesis.

depends, plugins, includes

passed to Rcpp::cppFunction().

Value

a test object corresponding to the specified key.

a data frame containing keys and corresponding tests implemented in this package.

a test object based on the specified statistic.

Details

The test statistic can be defined using either R or Rcpp, with the statistic parameter specified as:

  • R: a function returning a closure that returns a double.

  • Rcpp: a character string defining a captureless lambda (since C++11) returning another lambda that captures by value, accepts parameters of the same type as const references, and returns a double.

When using Rcpp, the parameters for different inherit are listed as follows. Note that the parameter names are for illustration only.

  • "twosample": (Rcpp::NumericVector sample_1, Rcpp::NumericVector sample_2)

  • "ksample": (Rcpp::NumericVector combined_sample, Rcpp::IntegerVector one_based_group_index)

  • "paired": (Rcpp::NumericVector sample_1, Rcpp::NumericVector sample_2)

  • "rcbd": (Rcpp::NumericMatrix block_as_column_data)

  • "association": (Rcpp::NumericVector sample_1, Rcpp::NumericVector sample_2)

  • "table": (Rcpp::IntegerMatrix contingency_table)

Defining the test statistic using R follows a similar approach. The purpose of this design is to pre-calculate certain constants that remain invariant during permutation.

Examples

pmt("twosample.wilcoxon")
#> <Wilcoxon>
#>   Inherits from: <TwoSampleLocationTest>
#>   Public:
#>     alternative: active binding
#>     conf_int: active binding
#>     conf_level: active binding
#>     correct: active binding
#>     data: active binding
#>     estimate: active binding
#>     initialize: function (type = c("permu", "asymp"), alternative = c("two_sided", 
#>     method: active binding
#>     n_permu: active binding
#>     null_value: active binding
#>     p_value: active binding
#>     plot: function (style = c("graphics", "ggplot2"), ...) 
#>     print: function () 
#>     scoring: active binding
#>     statistic: active binding
#>     test: function (...) 
#>     type: active binding
#>   Private:
#>     .alternative: two_sided
#>     .autoplot: function (...) 
#>     .calculate: function () 
#>     .calculate_extra: function () 
#>     .calculate_n_permu: function () 
#>     .calculate_p: function () 
#>     .calculate_p_permu: function () 
#>     .calculate_score: function () 
#>     .calculate_side: function () 
#>     .calculate_statistic: function () 
#>     .compile_statistic_closure: function () 
#>     .conf_int: NULL
#>     .conf_level: 0.95
#>     .correct: TRUE
#>     .data: NULL
#>     .define: function () 
#>     .estimate: NULL
#>     .link: +
#>     .method: default
#>     .n_permu: 10000
#>     .name: Two-Sample Wilcoxon Test
#>     .null_value: 0
#>     .on_alternative_change: function () 
#>     .on_conf_level_change: function () 
#>     .on_method_change: function () 
#>     .on_n_permu_change: function () 
#>     .on_null_value_change: function () 
#>     .on_scoring_change: function () 
#>     .on_type_change: function () 
#>     .p_value: NULL
#>     .param_name: location shift
#>     .plot: function (...) 
#>     .preprocess: function () 
#>     .print: function () 
#>     .raw_data: NULL
#>     .scoring: rank
#>     .side: NULL
#>     .statistic: NULL
#>     .statistic_func: NULL
#>     .type: permu

pmts("ksample")
#>              key              class                         test
#> 1 ksample.oneway             OneWay One-Way Test for Equal Means
#> 2     ksample.kw      KruskalWallis          Kruskal-Wallis Test
#> 3     ksample.jt JonckheereTerpstra     Jonckheere-Terpstra Test

x <- rnorm(5)
y <- rnorm(5, 1)

t <- define_pmt(
    inherit = "twosample",
    scoring = base::rank, # equivalent to "rank"
    statistic = function(...) function(x, y) sum(x)
)$test(x, y)$print()
#> 
#>  	 User-Defined Permutation Test 
#> 
#> scoring: custom    type: permu(10000)    method: default
#> statistic = 19, p-value = 0.09 (± 0.005609059 at 95% confidence)

t$scoring <- function(x) qnorm(rank(x) / (length(x) + 1)) # equivalent to "vw"
t$print()
#> 
#>  	 User-Defined Permutation Test 
#> 
#> scoring: custom    type: permu(10000)    method: default
#> statistic = -2.38528, p-value = 0.0654 (± 0.004845626 at 95% confidence)

t$n_permu <- 0
t$print()
#> 
#>  	 User-Defined Permutation Test 
#> 
#> scoring: custom    type: permu(252)    method: default
#> statistic = -2.38528, p-value = 0.06349206

# \donttest{
r <- define_pmt(
    inherit = "twosample",
    n_permu = 1e5,
    statistic = function(x, y) {
        m <- length(x)
        n <- length(y)
        function(x, y) sum(x) / m - sum(y) / n
    }
)

rcpp <- define_pmt(
    inherit = "twosample",
    n_permu = 1e5,
    statistic = "[](NumericVector x, NumericVector y) {
        R_len_t m = x.size();
        R_len_t n = y.size();
        return [=](const NumericVector& x, const NumericVector& y) -> double {
            return sum(x) / m - sum(y) / n;
        };
    }"
)

options(LearnNonparam.pmt_progress = FALSE)
system.time(r$test(x, y))
#>    user  system elapsed 
#>   0.143   0.000   0.143 
system.time(rcpp$test(x, y))
#>    user  system elapsed 
#>   0.009   0.000   0.008 
# }