Skip to content

Commit 5c90149

Browse files
Merge pull request #66 from wjakethompson/object-conversion
Add functionality for converting objects to `measrdcm` objects
2 parents 985616e + 4d29864 commit 5c90149

File tree

13 files changed

+300
-31
lines changed

13 files changed

+300
-31
lines changed

.lintr

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ exclusions: list(
66
"R/stanmodels.R",
77
"R/import-standalone-obj-type.R",
88
"R/import-standalone-types-check.R",
9-
"R/zzz-class-dcm-estimate.R" = list(
10-
line_length_linter = Inf
11-
),
129
"R/dep-fit-dcm.R" = list(
1310
line_length_linter = Inf
1411
),

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: measr
22
Title: Bayesian Psychometric Measurement Using 'Stan'
3-
Version: 1.0.0.9000
3+
Version: 1.0.0.9001
44
Authors@R: c(
55
person("W. Jake", "Thompson", , "wjakethompson@gmail.com", role = c("aut", "cre"),
66
comment = c(ORCID = "0000-0001-7339-0300")),

NAMESPACE

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export(as_label)
1919
export(as_name)
2020
export(bic)
2121
export(cdi)
22+
export(cmdstanr)
2223
export(create_profiles)
2324
export(crum)
2425
export(dcm_estimate)
@@ -31,17 +32,22 @@ export(enquos)
3132
export(fit_m2)
3233
export(fit_ppmc)
3334
export(get_parameters)
35+
export(gqs)
3436
export(hdcm)
3537
export(independent)
3638
export(lcdm)
3739
export(loglik_array)
3840
export(loo)
3941
export(loo_compare)
42+
export(mcmc)
4043
export(measr_dcm)
4144
export(measr_examples)
4245
export(measr_extract)
46+
export(measrdcm)
47+
export(optim)
4348
export(prior)
4449
export(reliability)
50+
export(rstan)
4551
export(rvar_mad)
4652
export(rvar_max)
4753
export(rvar_mean)

R/zxx-class-stan-classes.R

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,71 @@
1-
# Define classes for estimation methods ----------------------------------------
2-
stanmethod <- S7::new_class("stanmethod", package = "measr")
3-
4-
mcmc <- S7::new_class("mcmc", parent = stanmethod, package = "measr")
5-
optim <- S7::new_class("optim", parent = stanmethod, package = "measr")
6-
gqs <- S7::new_class("gqs", parent = stanmethod, package = "measr")
7-
1+
#' S7 classes for estimation specifications
2+
#'
3+
#' The constructors for Stan back-ends and methods are exported to support
4+
#' extensions to measr, for example converting other models to `measrfit`
5+
#' objects. We do not expect or recommend calling these functions directly
6+
#' unless you are converting objects, or creating new methods for measrfit
7+
#' objects.
8+
#'
9+
#' @details
10+
#' ## Back-end classes
11+
#'
12+
#' There are two classes for estimation backends, which define the package that
13+
#' should be used, or was used, to estimate a model.
14+
#' The `rstan()` class indicates use of `{rstan}`, whereas `cmdstanr()`
15+
#' indicates use of `{cmdstanr}`.
16+
#' Both classes inherit from `measr::stanbackend`.
17+
#'
18+
#' ## Method classes
19+
#'
20+
#' The method classes define which estimation method should be used, or was
21+
#' used, for a model.
22+
#' The `mcmc()` class indicates the use of Markov chain Monte Carlo via
23+
#' [rstan::sampling()] when using `{rstan}` or the
24+
#' [`$sample()`][cmdstanr::sample()] method of the
25+
#' [CmdStanModel][cmdstanr::CmdStanModel] class when using `{cmdstanr}`.
26+
#' The `optim()` class indicates the use maximum-likelihood via
27+
#' [rstan::optimizing()] when using `{rstan}` or the
28+
#' [`$optimize()`][cmdstanr::optimize()] method of the
29+
#' [CmdStanModel][cmdstanr::CmdStanModel] class when using `{cmdstanr}`.
30+
#' Finally, there is a `gqs()` class for use when a model has previously been
31+
#' estimated and were are interested in calculating generated quantities (e.g.,
32+
#' [score()], [loglik_array()]).
33+
#' The `gqs()` class indicates the use of [rstan::gqs()] when using `{rstan}`
34+
#' and the [`$generate_quantities()`][cmdstanr::generate_quantities()] method of
35+
#' the [CmdStanModel][cmdstanr::CmdStanModel] class when using `{cmdstanr}`.
36+
#' All method classes inherit from `measr::stanmethod`.
37+
#'
38+
#' @return An [S7 object][S7_object()] with the corresponding class.
39+
#' @rdname stan-classes
40+
#' @name stan-classes
41+
#' @examples
42+
#' rstan()
43+
#'
44+
#' mcmc()
45+
NULL
846

947
# Define classes for backends --------------------------------------------------
1048
stanbackend <- S7::new_class("stanbackend", package = "measr")
1149

50+
#' @export
51+
#' @rdname stan-classes
1252
rstan <- S7::new_class("rstan", parent = stanbackend, package = "measr")
53+
54+
#' @export
55+
#' @rdname stan-classes
1356
cmdstanr <- S7::new_class("cmdstanr", parent = stanbackend, package = "measr")
57+
58+
# Define classes for estimation methods ----------------------------------------
59+
stanmethod <- S7::new_class("stanmethod", package = "measr")
60+
61+
#' @export
62+
#' @rdname stan-classes
63+
mcmc <- S7::new_class("mcmc", parent = stanmethod, package = "measr")
64+
65+
#' @export
66+
#' @rdname stan-classes
67+
optim <- S7::new_class("optim", parent = stanmethod, package = "measr")
68+
69+
#' @export
70+
#' @rdname stan-classes
71+
gqs <- S7::new_class("gqs", parent = stanmethod, package = "measr")

R/zzz-class-dcm-estimate.R

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,15 @@
4141
#' * For `backend = "rstan"`, arguments are passed to [rstan::sampling()]
4242
#' or [rstan::optimizing()].
4343
#' * For `backend = "cmdstanr"`, arguments are passed to the
44-
#' [`$sample()`](https://mc-stan.org/cmdstanr/reference/model-method-sample.html)
45-
#' or
46-
#' [`$optimize()`](https://mc-stan.org/cmdstanr/reference/model-method-optimize.html)
47-
#' methods of the
48-
#' [CmdStanModel](https://mc-stan.org/cmdstanr/reference/CmdStanModel.html)
49-
#' class.
44+
#' [`$sample()`][cmdstanr::sample()] or
45+
#' [`$optimize()`][cmdstanr::optimize()] methods of the
46+
#' [CmdStanModel][cmdstanr::CmdStanModel] class.
5047
#'
5148
#' @concept Bayesian
5249
#' @concept DCM
5350
#' @concept Stan
51+
#' @concept Cmd
52+
#' @concept Model
5453
#'
5554
#' @returns A `measrdcm` object.
5655
#' @export
@@ -173,8 +172,8 @@ dcm_estimate <- function(dcm_spec, data, missing = NA, identifier = NULL,
173172
#' @param backend The name of the backend used to fit the model.
174173
#' @param model The fitted Stan model. This will object of class
175174
#' [rstan::stanfit-class] if `backend = "rstan"` and
176-
#' [`CmdStanMCMC`](https://mc-stan.org/cmdstanr/reference/CmdStanMCMC.html)
177-
#' if `backend = "cmdstanr"` was specified when fitting the model.
175+
#' [`CmdStanMCMC`][cmdstanr::CmdStanMCMC] if `backend = "cmdstanr"` was
176+
#' specified when fitting the model.
178177
#' @param respondent_estimates An empty list for adding estimated person
179178
#' parameters after fitting the model.
180179
#' @param fit An empty list for adding model fit information after fitting the
@@ -194,7 +193,7 @@ dcm_estimate <- function(dcm_spec, data, missing = NA, identifier = NULL,
194193
measrfit <- S7::new_class("measrfit", package = "measr",
195194
properties = list(
196195
model_spec = S7::new_property(
197-
class = S7::S7_object,
196+
class = S7::class_any,
198197
setter = function(self, value) {
199198
if (!is.null(self@model_spec)) {
200199
stop("@model_spec is read-only", call. = FALSE)
@@ -214,8 +213,7 @@ measrfit <- S7::new_class("measrfit", package = "measr",
214213
}
215214
),
216215
stancode = S7::new_property(
217-
class = S7::new_S3_class(class = c("glue", "character")),
218-
default = glue::glue(),
216+
class = S7::class_character,
219217
setter = function(self, value) {
220218
if (!is.null(self@stancode)) {
221219
stop("@stancode is read-only", call. = FALSE)
@@ -226,7 +224,7 @@ measrfit <- S7::new_class("measrfit", package = "measr",
226224
),
227225
method = S7::new_property(
228226
class = stanmethod,
229-
default = optim(),
227+
default = NULL,
230228
setter = function(self, value) {
231229
if (!is.null(self@method)) {
232230
stop("@method is read-only", call. = FALSE)
@@ -247,7 +245,7 @@ measrfit <- S7::new_class("measrfit", package = "measr",
247245
),
248246
backend = S7::new_property(
249247
class = stanbackend,
250-
default = rstan(),
248+
default = NULL,
251249
setter = function(self, value) {
252250
if (!is.null(self@backend)) {
253251
stop("@backend is read-only", call. = FALSE)
@@ -325,8 +323,59 @@ measrfit <- S7::new_class("measrfit", package = "measr",
325323
}
326324
)
327325

326+
#' S7 class for measrdcm objects
327+
#'
328+
#' The `measrdcm` constructor is exported to facilitate the conversion of other
329+
#' model objects (e.g., `stanfit`) to `measrdcm` objects. We do not expect or
330+
#' recommend calling this function directly, unless you are creating a method
331+
#' for converting to `measrdcm`. Rather, to create a `measrdcm` object, one
332+
#' should use [dcm_estimate()].
333+
#'
334+
#' @param model_spec The model specification used to estimate the model.
335+
#' @param data The data used to estimate the model.
336+
#' @param stancode The model code in *Stan* language.
337+
#' @param method The method used to fit the model.
338+
#' @param algorithm The name of the algorithm used to fit the model.
339+
#' @param backend The name of the backend used to fit the model.
340+
#' @param model The fitted Stan model. This will object of class
341+
#' [rstan::stanfit-class] if `backend = "rstan"` and
342+
#' [`CmdStanMCMC`][cmdstanr::CmdStanMCMC] if `backend = "cmdstanr"` was
343+
#' specified when fitting the model.
344+
#' @param respondent_estimates An empty list for adding estimated person
345+
#' parameters after fitting the model.
346+
#' @param fit An empty list for adding model fit information after fitting the
347+
#' model.
348+
#' @param criteria An empty list for adding information criteria after fitting
349+
#' the model.
350+
#' @param reliability An empty list for adding reliability information after
351+
#' fitting the model.
352+
#' @param file Optional name of a file which the model objects was saved to
353+
#' or loaded from.
354+
#' @param version The versions of measr, *Stan*, and rstan or cmdstanr that were
355+
#' used to fit the model.
356+
#'
357+
#' @concept Stan
358+
#'
359+
#' @returns A `measrdcm` object.
360+
#' @seealso [dcm_estimate()].
361+
#' @export
362+
#'
363+
#' @examples
364+
#' qmatrix <- tibble::tibble(
365+
#' att1 = sample(0:1, size = 15, replace = TRUE),
366+
#' att2 = sample(0:1, size = 15, replace = TRUE),
367+
#' att3 = sample(0:1, size = 15, replace = TRUE),
368+
#' att4 = sample(0:1, size = 15, replace = TRUE)
369+
#' )
370+
#'
371+
#' spec <- dcm_specify(qmatrix = qmatrix)
372+
#'
373+
#' measrdcm(spec)
328374
measrdcm <- S7::new_class("measrdcm", parent = measrfit, package = "measr",
329375
properties = list(
330-
model_spec = S7::new_property(class = dcmstan::dcm_specification)
376+
model_spec = S7::new_property(
377+
class = dcmstan::dcm_specification,
378+
default = NULL
379+
)
331380
)
332381
)

_pkgdown.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ reference:
8383
- title: internal
8484
contents:
8585
- measr_examples
86+
- measrdcm
87+
- stan-classes
8688

8789
articles:
8890
- title: Get started

inst/WORDLIST

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CDM
44
CDMs
55
CMD
66
Cai
7+
Cmd
78
CmdStan
89
CmdStanModel
910
CmdStanR
@@ -18,12 +19,16 @@ Gabry
1819
Gelman
1920
Gierl
2021
Kiado
22+
Kreiner
2123
Kruskal's
2224
Kullback
2325
LCDM
2426
Leibler
2527
Liu
28+
Makransky
29+
Marais
2630
Maydeu
31+
Mesbah
2732
Metaprogramming
2833
Mplus
2934
Netlify
@@ -34,13 +39,15 @@ PPMCs
3439
Petrov
3540
RMSEA
3641
RStan
42+
Rasch
3743
Roussos
3844
Rtools
3945
Rupp
4046
SRMSR
4147
Schwarz
4248
Sinharay
4349
Templin
50+
Thissen
4451
Tian
4552
Vehtari
4653
WAIC

man/dcm_estimate.Rd

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

0 commit comments

Comments
 (0)