Skip to content

Commit

Permalink
Merge pull request #34 from wjakethompson/update-vignettes
Browse files Browse the repository at this point in the history
Update vignettes
  • Loading branch information
wjakethompson committed Sep 20, 2023
2 parents e84f57f + 082f72a commit 7210ec9
Show file tree
Hide file tree
Showing 35 changed files with 697 additions and 78 deletions.
1 change: 1 addition & 0 deletions .github/workflows/pkgdown.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
any::pkgdown
any::tidyverse
local::.
upgrade: 'TRUE'
needs: website

- name: Build site
Expand Down
10 changes: 9 additions & 1 deletion .lintr
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
linters: linters_with_defaults()
linters: linters_with_defaults(
indentation_linter = NULL
)
exclusions: list(
"R/stanmodels.R",
"R/fit-dcm.R" = list(
line_length_linter = Inf
),
"vignettes/measr.Rmd" = list(
commented_code_linter = Inf
),
"vignettes/articles/data-raw/example-data.R" = list(
object_usage_linter = Inf
)
)
encoding: "UTF-8"
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

* Fixed bug in the LCDM specification of constraints for level-3 and above interaction terms.

* Functions for evaluating estimated models (e.g., `fit_ppmc()`, `reliability()`) no longer recalculate indices if they have previously been saved to the model object. This behavior can be overwritten with `force = TRUE`.

* Updates to documentation
* A new article on model evaluation has been added.
* The model estimation article has been updated to use the same data set as the model evaluation article.
* More detailed installation instructions have been added to the getting started vignette.

# measr 0.3.1

* Added a `NEWS.md` file to track changes to the package.
Expand Down
16 changes: 14 additions & 2 deletions R/loo-methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,19 @@ loo::loo_compare
#' @inheritParams loo::loo
#' @param x A [measrfit] object.
#' @param ... Additional arguments passed to [loo::loo.array()].
#' @param force If the LOO criterion has already been added to the model object
#' with [add_criterion()], should it be recalculated. Default is `FALSE`.
#'
#' @return The object returned by [loo::loo.array()].
#'
#' @export
loo.measrfit <- function(x, ..., r_eff = NA) { #nolint
loo.measrfit <- function(x, ..., r_eff = NA, force = FALSE) { #nolint
model <- check_model(x, required_class = "measrfit", name = "x")

if (!is.null(model$criteria$loo) && !force) {
return(model$criteria$loo)
}

if (model$method != "mcmc") {
rlang::abort("error_bad_method",
message = glue::glue("LOO-CV is only available for models ",
Expand All @@ -45,13 +51,19 @@ loo.measrfit <- function(x, ..., r_eff = NA) { #nolint
#'
#' @param x A [measrfit] object.
#' @param ... Additional arguments passed to [loo::waic.array()].
#' @param force If the WAIC criterion has already been added to the model object
#' with [add_criterion()], should it be recalculated. Default is `FALSE`.
#'
#' @return The object returned by [loo::waic.array()].
#'
#' @export
waic.measrfit <- function(x, ...) { #nolint
waic.measrfit <- function(x, ..., force = FALSE) { #nolint
model <- check_model(x, required_class = "measrfit", name = "x")

if (!is.null(model$criteria$waic) && !force) {
return(model$criteria$waic)
}

if (model$method != "mcmc") {
rlang::abort("error_bad_method",
message = glue::glue("WAIC is only available for models ",
Expand Down
9 changes: 8 additions & 1 deletion R/m2-methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ dcm2::fit_m2
#' described by Hansen et al. (2016) and Liu et al. (2016).
#'
#' @inheritParams dcm2::fit_m2
#' @param force If the \ifelse{html}{\out{M<sub>2</sub>}}{\eqn{M_2}} has already
#' been saved to the model object with [add_fit()], should it be recalculated.
#' Default is `FALSE`.
#'
#' @return A data frame created by [dcm2::fit_m2()].
#'
Expand All @@ -33,10 +36,14 @@ dcm2::fit_m2
#' )
#'
#' fit_m2(rstn_mdm_lcdm)
fit_m2.measrdcm <- function(model, ci = 0.9, ...) {
fit_m2.measrdcm <- function(model, ..., ci = 0.9, force = FALSE) {
model <- check_model(model, required_class = "measrdcm", name = "model")
ci <- check_double(ci, lb = 0, ub = 1, inclusive = FALSE, name = "ci")

if (!is.null(model$fit$m2) && !force) {
return(model$fit$m2)
}

item_order <- levels(model$data$data$item_id)
dat <- model$data$data %>%
tidyr::pivot_wider(names_from = "item_id", values_from = "score") %>%
Expand Down
1 change: 1 addition & 0 deletions R/model-evaluation.R
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ add_fit <- function(x, method = c("m2", "ppmc"), overwrite = FALSE,
# determine if/which ppmc need to be run
dots <- list(...)
run_ppmc <- existing_ppmc_check(model, method, dots, overwrite)
run_ppmc$args$force <- TRUE

if (run_m2) {
model$fit$m2 <- fit_m2(model, ci = ci)
Expand Down
32 changes: 31 additions & 1 deletion R/ppmc.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#' Multiple checks can be provided in order to calculate more than one check
#' simultaneously (e.g., `item_fit = c("conditional_prob", "odds_ratio")`).
#' See details.
#' @param force If all requested PPMCs have already been added to the model
#' object using [add_fit()], should they be recalculated. Default is `FALSE`.
#'
#' @details
#' Posterior predictive model checks (PPMCs) use the posterior distribution of
Expand Down Expand Up @@ -102,7 +104,8 @@
fit_ppmc <- function(model, ndraws = NULL, probs = c(0.025, 0.975),
return_draws = 0,
model_fit = c("raw_score"),
item_fit = c("conditional_prob", "odds_ratio")) {
item_fit = c("conditional_prob", "odds_ratio"),
force = FALSE) {
model <- check_model(model, required_class = "measrdcm", name = "object")
total_draws <- posterior::ndraws(posterior::as_draws(model))
ndraws <- check_integer(ndraws, lb = 1, ub = total_draws,
Expand All @@ -117,6 +120,33 @@ fit_ppmc <- function(model, ndraws = NULL, probs = c(0.025, 0.975),
rlang::arg_match(item_fit, multiple = TRUE)
}

# check for existing fit analyses
check_ppmc <- existing_ppmc_check(model = model, method = "ppmc",
dots = list(ndraws = ndraws,
probs = probs,
return_draws = return_draws,
model_fit = model_fit,
item_fit = item_fit),
overwrite = force)
if (!check_ppmc$run && !force) {
requested <- list(model_fit = model_fit,
item_fit = item_fit)
requested[sapply(requested, is.null)] <- NULL

res <- mapply(
function(x, nm, model) {
element <- model$fit$ppmc[[nm]][x]
rlang::set_names(element, nm = x)
return(element)
},
requested, names(requested),
MoreArgs = list(model = model), SIMPLIFY = FALSE, USE.NAMES = TRUE
)

return(res)
}


if (length(model_fit) == 0 && length(item_fit) == 0) return(list())

clean_qmatrix <- model$data$qmatrix %>%
Expand Down
13 changes: 11 additions & 2 deletions R/reliability.R
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#' Estimate the reliability of psychometric models
#'
#' @param model The estimated model to be evaluated.
#' @param ... Unused. For future extensions.
#' @param force If reliability information has already been added to the model
#' object with [add_reliability()], should it be recalculated. Default is
#' `FALSE`.
#'
#' @export
reliability <- function(model) {
reliability <- function(model, ...) {
UseMethod("reliability")
}

Expand Down Expand Up @@ -62,7 +66,12 @@ reliability <- function(model) {
#' )
#'
#' reliability(rstn_mdm_lcdm)
reliability.measrdcm <- function(model) {
reliability.measrdcm <- function(model, ..., force = FALSE) {
if ((!is.null(model$reliability) && length(model$reliability) > 0) &&
!force) {
return(model$reliability)
}

# coerce model into a list of values required for reliability
obj <- reli_list(model)
att_names <- model$data$qmatrix %>%
Expand Down
6 changes: 6 additions & 0 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
CDMs
CMD
Cai
CmdStan
CmdStanModel
CmdStanR
Cui
DCM
DCMs
Expand Down Expand Up @@ -72,13 +74,17 @@ posteriori
ppp
pre
psychometrics
resave
rlang
rstan
subtype
subtypes
tetrachoric
tibble
tibbles
toolchain
tunnelled
tunnelling
warmup
κ
λ
8 changes: 6 additions & 2 deletions man/fit_m2.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion man/fit_ppmc.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion man/loo.measrfit.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions man/reliability.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion man/waic.measrfit.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pkgdown/_pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,7 @@ reference:

news:
releases:
- text: "Version 0.3.1"
href: https://www.wjakethompson.com/blog/measr/2023-06-measr-0.3.1/
- text: "Version 0.2.1"
href: https://www.wjakethompson.com/blog/measr/2023-04-measr-0.2.1/
4 changes: 4 additions & 0 deletions tests/testthat/test-m2-methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,8 @@ test_that("m2 works", {
dplyr::select(m2, "rmsea", "95% CI"))
expect_equal(measr_extract(m2_mod, "srmsr"),
dplyr::select(m2, "srmsr"))

# recalculating returns same object
m2_recalc <- fit_m2(m2_mod)
expect_identical(m2_recalc, m2_mod$fit$m2)
})
8 changes: 7 additions & 1 deletion tests/testthat/test-mcmc.R
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ test_that("loo and waic can be added to model", {

expect_identical(measr_extract(lw_model, "loo"), lw_model$criteria$loo)
expect_identical(measr_extract(lw_model, "waic"), lw_model$criteria$waic)

expect_identical(lw_model$criteria$loo, loo(lw_model))
expect_identical(lw_model$criteria$waic, waic(lw_model))
})

test_that("model comparisons work", {
Expand Down Expand Up @@ -245,10 +248,13 @@ test_that("model fit can be added", {
expect_equal(names(test_model$fit$ppmc$item_fit$odds_ratio),
c("item_1", "item_2", "obs_or", "ppmc_mean", "2.5%", "97.5%",
"samples", "ppp"))
expect_identical(test_model$fit$ppmc, fit_ppmc(test_model,
model_fit = NULL,
item_fit = "odds_ratio"))

# nothing new does nothing
test_model2 <- add_fit(test_model, method = "ppmc", model_fit = NULL,
item_fit = NULL)
item_fit = NULL)
expect_identical(test_model, test_model2)

# now add ppmc raw score and conditional probs -- other fit should persist
Expand Down
2 changes: 2 additions & 0 deletions tests/testthat/test-reliability.R
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,6 @@ test_that("reliability can be added to model object", {
agreement = "bs"),
dplyr::select(dina_mod$reliability$eap_reliability,
"attribute", informational = "rho_i", "rho_bs"))

expect_identical(dina_mod$reliability, reliability(dina_mod))
})
1 change: 1 addition & 0 deletions vignettes/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.html
*.R
articles/*_cache/*

0 comments on commit 7210ec9

Please sign in to comment.