Skip to content

Commit 84ae59c

Browse files
author
Raphael Sonabend
authored
Merge pull request #252 from alan-turing-institute/as_distribution
add as.Distribution.matrix
2 parents 7967cb1 + 899e002 commit 84ae59c

21 files changed

+194
-28
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ Meta
1010
docs/
1111
revdep/
1212
CRAN-RELEASE
13+
.vscode/
14+
*.o
15+
*.so
16+
*.dll

DESCRIPTION

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: distr6
22
Title: The Complete R6 Probability Distributions Interface
3-
Version: 1.5.3
3+
Version: 1.5.4
44
Authors@R:
55
c(person(given = "Raphael",
66
family = "Sonabend",
@@ -172,6 +172,7 @@ Collate:
172172
'Wrapper_Scale.R'
173173
'Wrapper_TruncatedDistribution.R'
174174
'Wrapper_VectorDistribution.R'
175+
'as.Distribution.R'
175176
'assertions.R'
176177
'c.Distribution.R'
177178
'decomposeMixture.R'

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ S3method("+",Distribution)
55
S3method("-",Distribution)
66
S3method("[",ParameterSet)
77
S3method("[",VectorDistribution)
8+
S3method(as.Distribution,matrix)
89
S3method(as.ParameterSet,data.table)
910
S3method(as.ParameterSet,list)
1011
S3method(as.data.table,ParameterSet)
@@ -96,6 +97,7 @@ export(VectorDistribution)
9697
export(Wald)
9798
export(Weibull)
9899
export(WeightedDiscrete)
100+
export(as.Distribution)
99101
export(as.MixtureDistribution)
100102
export(as.ParameterSet)
101103
export(as.ProductDistribution)

NEWS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
# distr6 1.5.4
2+
3+
* Added `as.Distribution.matrix` for converting matrices to a `VectorDistribution` of `WeightedDiscrete` distributions
4+
* Added `...` to `dstrs` to allow decorator argument to be passed through
5+
6+
# distr6 1.5.3
7+
8+
* Internal changes only
9+
110
# distr6 1.5.2
211

312
* Fixed bug in extracting distributions from vector distributions

R/Distribution.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ Distribution <- R6Class("Distribution",
451451
if (private$.log) {
452452
pdqr <- private$.pdf(data, log = log)
453453
} else {
454-
if (!("CoreStatistics" %in% self$decorators)) {
454+
if ("CoreStatistics" %nin% self$decorators) {
455455
stop("No analytical method for log available.
456456
Use CoreStatistics decorator to numerically estimate this.")
457457
} else {
@@ -522,7 +522,7 @@ Use CoreStatistics decorator to numerically estimate this.")
522522
if (private$.log) {
523523
pdqr <- private$.cdf(data, log.p = log.p, lower.tail = lower.tail)
524524
} else {
525-
if (!("CoreStatistics" %in% self$decorators)) {
525+
if ("CoreStatistics" %nin% self$decorators) {
526526
stop("No analytical method for log.p or lower.tail available. Use CoreStatistics
527527
decorator to numerically estimate this.")
528528
} else {
@@ -589,7 +589,7 @@ decorator to numerically estimate this.")
589589
if (private$.log) {
590590
pdqr <- private$.quantile(data, log.p = log.p, lower.tail = lower.tail)
591591
} else {
592-
if (!("CoreStatistics" %in% self$decorators)) {
592+
if ("CoreStatistics" %nin% self$decorators) {
593593
stop("No analytical method for log.p or lower.tail available. Use CoreStatistics
594594
decorator to numerically estimate this.")
595595
} else {

R/ParameterSet.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ ParameterSet <- R6Class("ParameterSet",
128128
print = function(hide_cols = c("settable"), ...) {
129129
ps <- private$.parameters
130130
ps$support <- lapply(ps$support, function(x) x$strprint())
131-
print(subset(ps, select = !(names(ps) %in% hide_cols)))
131+
print(subset(ps, select = names(ps) %nin% hide_cols))
132132
},
133133

134134
#' @description

R/ParameterSetCollection.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ ParameterSetCollection <- R6Class("ParameterSetCollection",
5858
print = function(hide_cols = c("settable"), ...) {
5959
psc <- as.data.table(self)
6060
psc$support <- lapply(psc$support, function(x) x$strprint())
61-
print(subset(psc, select = !(names(psc) %in% hide_cols)))
61+
print(subset(psc, select = names(psc) %nin% hide_cols))
6262
},
6363

6464
#' @description

R/Wrapper_VectorDistribution.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,10 @@ or `distlist` should be used.")
223223

224224
if (!is.null(shared_params)) {
225225
if (distribution == "Geometric") {
226-
shared_params <- shared_params[!(names(shared_params) %in% "trials")]
226+
shared_params <- shared_params[names(shared_params) %nin% "trials"]
227227
}
228228
if (distribution == "NegativeBinomial") {
229-
shared_params <- shared_params[!(names(shared_params) %in% "form")]
229+
shared_params <- shared_params[names(shared_params) %nin% "form"]
230230
}
231231
shared_params <- rep(list(shared_params), length(params))
232232
names(shared_params) <- names(paramlst)

R/as.Distribution.R

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#' @title Coerce matrix to vector of WeightedDiscrete
2+
#' @description Coerces matrices to a [VectorDistribution] containing
3+
#' [WeightedDiscrete] distributions. Number of distributions are the number
4+
#' of rows in the matrix, number of `x` points are number of columns in the
5+
#' matrix.
6+
#' @param obj [matrix]. Column names correspond to `x` in [WeightedDiscrete],
7+
#' so this method only works if all distributions (rows in the matrix) have the
8+
#' same points to be evaluated on. Elements correspond to either the pdf
9+
#' or cdf of the distribution (see below).
10+
#' @param fun Either `"pdf"` or `"cdf"`, passed to [WeightedDiscrete] and tells
11+
#' the constructor if the elements in `obj` correspond to the pdf or cdf of
12+
#' the distribution.
13+
#' @param decorators Passed to [VectorDistribution].
14+
#' @return A [VectorDistribution]
15+
#' @export
16+
#' @examples
17+
#' pdf <- runif(200)
18+
#' mat <- matrix(pdf, 20, 10)
19+
#' mat <- t(apply(mat, 1, function(x) x / sum(x)))
20+
#' colnames(mat) <- 1:10
21+
#' as.Distribution(mat, fun = "pdf")
22+
as.Distribution <- function(obj, fun, decorators = NULL) {
23+
UseMethod("as.Distribution")
24+
}
25+
26+
#' @rdname as.Distribution
27+
#' @export
28+
as.Distribution.matrix <- function(obj, fun, decorators = NULL) {
29+
if (is.null(colnames(obj))) {
30+
stop("'obj' must have column names")
31+
}
32+
33+
if (fun %nin% c("pdf", "cdf")) {
34+
stop("'fun' should be one of 'pdf', 'cdf'")
35+
}
36+
37+
x <- as.numeric(colnames(obj))
38+
obj <- apply(obj, 1, function(.x) {
39+
out <- list(.x)
40+
names(out) <- fun
41+
out
42+
})
43+
44+
VectorDistribution$new(
45+
distribution = "WeightedDiscrete",
46+
params = obj,
47+
shared_params = list(x = x),
48+
decorators = decorators
49+
)
50+
}

R/helpers.R

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
`%nin%` <- function(x, table) {
2+
!(x %in% table)
3+
}
4+
15
assertThat <- function(x, cond, errormsg) {
26
if (cond) {
37
invisible(x)
@@ -215,7 +219,7 @@ getR6Call <- function() {
215219
calls <- as.list(match.call(definition = sys.function(sys.parent(2L)),
216220
call = sys.call(sys.parent(3L)),
217221
envir = parent.frame(4L)))[-1]
218-
calls <- calls[!(names(calls) %in% "decorators")]
222+
calls <- calls[names(calls) %nin% "decorators"]
219223
# prevent lazy evaluation
220224
lapply(calls, eval.parent, n = 5)
221225
}

R/helpers_pdq.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pdqr_returner <- function(pdqr, simplify, name) {
6464
call_C_base_pdqr <- function(fun, x, args, lower.tail = TRUE, log = FALSE, vec) {
6565
type <- substr(fun, 1, 1)
6666

67-
if (!(type %in% c("d", "p", "q", "r"))) {
67+
if (type %nin% c("d", "p", "q", "r")) {
6868
stop("Function must start with one of: {d, p, q, r}.")
6969
}
7070

R/lines.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,19 @@ lines.Distribution <- function(x, fun, npoints = 3000, ...) {
6363
if ("cdf" %in% fun & is.null(x$.__enclos_env__$private$.cdf)) {
6464
message("This distribution does not have a cdf expression. Use the
6565
FunctionImputation decorator to impute a numerical cdf.")
66-
fun <- fun[!(fun %in% c("cdf", "survival", "hazard", "cumhazard"))]
66+
fun <- fun[fun %nin% c("cdf", "survival", "hazard", "cumhazard")]
6767
}
6868

6969
if ("pdf" %in% fun & is.null(x$.__enclos_env__$private$.pdf)) {
7070
message("This distribution does not have a pdf expression. Use the
7171
FunctionImputation decorator to impute a numerical pdf.")
72-
fun <- fun[!(fun %in% c("pdf", "hazard"))]
72+
fun <- fun[fun %nin% c("pdf", "hazard")]
7373
}
7474

7575
if ("quantile" %in% fun & is.null(x$.__enclos_env__$private$.quantile)) {
7676
message("This distribution does not have a quantile expression. Use the
7777
FunctionImputation decorator to impute a numerical quantile.")
78-
fun <- fun[!(fun %in% c("quantile"))]
78+
fun <- fun[fun %nin% c("quantile")]
7979
}
8080

8181
if (length(fun) == 0) {

R/plot_distribution.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,19 @@ plot.Distribution <- function(x, fun = c("pdf", "cdf"), npoints = 3000,
8383
if (any(c("cdf", "survival", "hazard", "cumhazard") %in% fun) & !isCdf(x)) {
8484
message("This distribution does not have a cdf expression.
8585
Use the FunctionImputation decorator to impute a numerical cdf.")
86-
fun <- fun[!(fun %in% c("cdf", "survival", "hazard", "cumhazard"))]
86+
fun <- fun[fun %nin% c("cdf", "survival", "hazard", "cumhazard")]
8787
}
8888

8989
if (any(c("pdf", "hazard") %in% fun) & !isPdf(x)) {
9090
message("This distribution does not have a pdf expression.
9191
Use the FunctionImputation decorator to impute a numerical pdf.")
92-
fun <- fun[!(fun %in% c("pdf", "hazard"))]
92+
fun <- fun[fun %nin% c("pdf", "hazard")]
9393
}
9494

9595
if (("quantile" %in% fun) & !isQuantile(x)) {
9696
message("This distribution does not have a quantile expression.
9797
Use the FunctionImputation decorator to impute a numerical quantile.")
98-
fun <- fun[!(fun %in% c("quantile"))]
98+
fun <- fun[fun %nin% c("quantile")]
9999
}
100100

101101
if (length(fun) == 0) {
@@ -132,7 +132,7 @@ Use the FunctionImputation decorator for better accuracy.")
132132
}
133133

134134
if (any(c("cdf", "survival", "hazard", "cumhazard", "quantile") %in% fun) &
135-
!("cdf" %in% colnames(plotStructure))) {
135+
"cdf" %nin% colnames(plotStructure)) {
136136
plotStructure$cdf <- x$cdf(plotStructure$points)
137137
}
138138
if (any(c("pdf", "hazard") %in% fun)) {

R/simulateEmpiricalDistribution.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#' @export
2020
simulateEmpiricalDistribution <- function(EmpiricalDist, n, seed = NULL) {
2121

22-
if (!(getR6Class(EmpiricalDist) %in% c("Empirical", "EmpiricalMV"))) {
22+
if (getR6Class(EmpiricalDist) %nin% c("Empirical", "EmpiricalMV")) {
2323
stop("For Distributions that are not Empirical use $rand.")
2424
}
2525

R/sugar.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,18 @@ dstr <- function(d, ..., pars = NULL) {
5959

6060
#' @rdname dstr
6161
#' @export
62-
dstrs <- function(d, pars = NULL) {
62+
dstrs <- function(d, pars = NULL, ...) {
6363

6464
if (length(d) == 1) {
6565
if (is.null(pars)) {
6666
stop("pars' cannot be NULL if 'd' is length 1.")
6767
} else {
68-
VectorDistribution$new(distribution = d, params = pars)
68+
VectorDistribution$new(distribution = d, params = pars, ...)
6969
}
7070
} else {
7171
if (is.null(pars)) {
7272
pars <- vector("list", length(d))
7373
}
74-
VectorDistribution$new(mapply(dstr, d, pars = pars))
74+
VectorDistribution$new(mapply(dstr, d, pars = pars, ...))
7575
}
7676
}

man/as.Distribution.Rd

Lines changed: 39 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/distr6-package.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/dstr.Rd

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/.gitignore

Lines changed: 0 additions & 3 deletions
This file was deleted.

tests/testthat/helpers.R

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,11 @@ autotest_vec_sdistribution <- function(sdist, pars) {
258258
} else {
259259
if (sdist$name == "Geometric" & !is.null(pars$trials)) {
260260
vdist <- VectorDistribution$new(distribution = sdist$name,
261-
params = rep(list(pars[!(names(pars) %in% "trials")]), 3),
261+
params = rep(list(pars[names(pars) %nin% "trials"]), 3),
262262
shared_params = list(trials = pars$trials))
263263
} else if (sdist$name == "NegativeBinomial" & !is.null(pars$form)) {
264264
vdist <- VectorDistribution$new(distribution = sdist$name,
265-
params = rep(list(pars[!(names(pars) %in% "form")]), 3),
265+
params = rep(list(pars[names(pars) %nin% "form"]), 3),
266266
shared_params = list(form = pars$form))
267267
} else {
268268
vdist <- VectorDistribution$new(distribution = sdist$name,
@@ -476,3 +476,8 @@ expect_equal_distribution <- function(d1, d2) {
476476
p2$support <- rsapply(p2$support, "strprint")
477477
expect_equal(p1, p2)
478478
}
479+
480+
expect_distribution <- function(d, class) {
481+
expect_is(d, "Distribution")
482+
expect_is(d, "Distribution")
483+
}

0 commit comments

Comments
 (0)