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, and returns a double.
The purpose of this design is to pre-calculate certain constants that remain invariant during permutation.
When using Rcpp, the parameters for different inherit
are listed as follows. Note that the names can be customized, and the types can be replaced with auto
(thanks to the support for generic lambdas in C++14). See examples.
inherit | Parameter 1 | Parameter 2 |
"twosample" | const NumericVector& sample_1 | const NumericVector& sample_2 |
"ksample" | const NumericVector& combined_sample | const IntegerVector& one_based_group_index |
"paired" | const NumericVector& sample_1 | const NumericVector& sample_2 |
"rcbd" | const NumericMatrix& block_as_column_data | |
"association" | const NumericVector& sample_1 | const NumericVector& sample_2 |
"table" | const IntegerMatrix& contingency_table |
When using R, the parameters should be the R equivalents of these.
Note
statistic
should not cause errors or return missing values.The data is permuted in-place. Therefore, modifications to the data within
statistic
may lead to incorrect results. Since R has copy-on-modify semantics but C++ does not, it is recommended to pass const references when using Rcpp indefine_pmt
, as shown in the table above.
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: 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 = "[](const auto& x, const auto& y) {
auto m = x.length();
auto n = y.length();
return [=](const auto& x, const auto& y) {
return sum(x) / m - sum(y) / n;
};
}"
)
# equivalent
# rcpp <- define_pmt(
# inherit = "twosample", n_permu = 1e5,
# statistic = "[](const NumericVector& x, const NumericVector& y) {
# R_xlen_t m = x.length();
# R_xlen_t n = y.length();
# return [m, n](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.146 0.000 0.146
system.time(rcpp$test(x, y))
#> user system elapsed
#> 0.009 0.000 0.009
# }