| Title: | Analyze and Visualize Pragmatic Context Assessment Tool Data |
|---|---|
| Description: | Provides a reproducible workflow for importing, validating, classifying, summarizing, visualizing, and reporting responses to the 14-item Pragmatic Context Assessment Tool (pCAT). The package preserves the instrument's two-part response structure, supports original and updated Consolidated Framework for Implementation Research (CFIR) mappings, describes team agreement and disagreement, compares repeated assessments, and creates implementation action-planning outputs. It does not calculate or claim a validated total pCAT scale score. The instrument is described by Robinson and Damschroder (2023) <doi:10.1186/s43058-022-00380-5>; updated CFIR mappings are from Domlyn et al. (2026) <doi:10.1186/s43058-026-00956-5>. |
| Authors: | Lilac Li [aut, cph] (URL: https://www.unk.edu/academics/management/lilac-li.php), Jae Man Park [cre, cph] (URL: https://www.linkedin.com/in/jae-man-park/) |
| Maintainer: | Jae Man Park <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.0.1 |
| Built: | 2026-10-04 10:03:26 UTC |
| Source: | https://github.com/jaemanp/pcatr |
Tools for importing, validating, classifying, summarizing, comparing, and visualizing responses to the 14-item Pragmatic Context Assessment Tool (pCAT). The package preserves the separate direction and effect responses and does not calculate or claim a validated total scale score.
The package supports the original CFIR mapping, the updated 2022 CFIR mapping, team agreement diagnostics, repeated assessments, barrier-focused action-plan tables, and an optional Shiny analysis dashboard.
pcat_items, pcat_validate,
pcat_classify, and pcat_summarise.
Validates and classifies responses, creates item-level summaries and consensus diagnostics, and optionally creates a barrier-focused action plan.
pcat_analyse( data, group_vars = NULL, respondent_id = "respondent_id", key_cols = NULL, require_complete = FALSE, neutral_effect = c("flag", "allow", "set_missing"), validation_action = c("none", "warn", "error"), strict = FALSE, suppress_below = NULL, agreement_threshold = 0.6, polarization_min = 0.2, minimum_n = 2L, include_action_plan = TRUE, barrier_threshold = 0.5, strong_barrier_threshold = 0.2, include_approximate = FALSE ) ## S3 method for class 'pcat_analysis' print(x, ...)pcat_analyse( data, group_vars = NULL, respondent_id = "respondent_id", key_cols = NULL, require_complete = FALSE, neutral_effect = c("flag", "allow", "set_missing"), validation_action = c("none", "warn", "error"), strict = FALSE, suppress_below = NULL, agreement_threshold = 0.6, polarization_min = 0.2, minimum_n = 2L, include_action_plan = TRUE, barrier_threshold = 0.5, strong_barrier_threshold = 0.2, include_approximate = FALSE ) ## S3 method for class 'pcat_analysis' print(x, ...)
data |
Long-format pCAT response data. |
group_vars |
Optional character vector of grouping columns, such as
|
respondent_id |
Name of the respondent identifier column. |
key_cols |
Columns defining one assessment for validation. When omitted, available project, site, team, timepoint, assessment date, and respondent identifiers are used. |
require_complete |
Logical; require exactly one response to every pCAT item 1–14 within each assessment. |
neutral_effect |
How to handle a neutral direction paired with any recorded effect: flag it, allow it, or set the effect to missing. |
validation_action |
Whether validation findings generate no condition, a warning, or an error. |
strict |
Logical; treat warnings as invalid when setting the validation
object's |
suppress_below |
Optional positive minimum respondent count. Numeric summary results and the derived modal classification below this threshold are replaced with missing values. |
agreement_threshold |
One finite number from zero through one giving the minimum dominant-side share used for a consensus label. |
polarization_min |
One finite number from zero through one giving the minimum barrier and facilitator shares required to label an item polarized. |
minimum_n |
Minimum number of valid direction responses required for a consensus label. |
include_action_plan |
Logical; create a barrier-focused action-plan table. |
barrier_threshold |
One finite number from zero through one giving the minimum barrier prevalence for action-plan inclusion. |
strong_barrier_threshold |
One finite number from zero through one giving the minimum strong-barrier prevalence for action-plan inclusion. |
include_approximate |
Logical; include the source table's non-identical Relative Priority to Relative Advantage approximation. |
x |
A |
... |
Additional arguments, currently ignored by the print method. |
The result retains validation findings and all denominators needed for transparent reporting. It does not calculate an overall pCAT scale score. Small-cell suppression hides numeric analytic measures and the derived modal classification in summary tables; respondent-level classified data are retained in the result and must be governed separately.
pcat_analyse() returns a list of class pcat_analysis with
components validation, classified, summary,
consensus, action_plan, and settings. The print method
returns x invisibly.
analysis <- pcat_analyse( pcat_example_data(), group_vars = c("site_id", "timepoint"), require_complete = TRUE, validation_action = "none" ) analysis head(analysis$summary)analysis <- pcat_analyse( pcat_example_data(), group_vars = c("site_id", "timepoint"), require_complete = TRUE, validation_action = "none" ) analysis head(analysis$summary)
Runs a bundled Shiny interface for uploading a non-sensitive long-format CSV, validating and classifying responses, viewing issues and a profile plot, and exporting classified data.
pcat_app()pcat_app()
The application is an analysis interface, not a secure survey-collection platform. Do not upload protected health information or sensitive direct identifiers.
The value returned by shiny::runApp().
if (interactive()) { if (requireNamespace("shiny", quietly = TRUE)) { pcat_app() } }if (interactive()) { if (requireNamespace("shiny", quietly = TRUE)) { pcat_app() } }
Combines direction and effect responses into strong barrier, weak barrier, neutral, weak facilitator, and strong facilitator categories. It retains explicit states for invalid responses and missing effect responses.
pcat_classify( data, validation_action = c("none", "warn", "error"), attach_items = TRUE )pcat_classify( data, validation_action = c("none", "warn", "error"), attach_items = TRUE )
data |
Long-format response data or a |
validation_action |
Condition behavior used when raw data must first be validated. |
attach_items |
Logical; attach item wording and CFIR metadata. |
Strength categories are assigned only when both direction and effect validation are valid. A neutral row with an invalid effect remains directionally neutral but has an invalid strength and no complete five-category classification.
The numeric pcat_display_code ranges from -2 to +2 and is supplied only
for descriptive plotting and transition displays. It is not a validated scale
score and should not be summed into an overall pCAT score.
A data frame of class pcat_classified.
classified <- pcat_classify(pcat_example_data()) head(classified)classified <- pcat_classify(pcat_example_data()) head(classified)
Returns the 14-item pCAT dictionary, a long-form mapping table, response-code definitions, synthetic example data, or source-derived candidate ERIC strategy links.
pcat_items(cfir_version = c("both", "original", "2022")) pcat_construct_map( cfir_version = c("both", "original", "2022"), include_secondary = TRUE ) pcat_response_options() pcat_example_data() pcat_strategy_candidates( construct = NULL, tier = c("all", "1", "2"), include_approximate = FALSE )pcat_items(cfir_version = c("both", "original", "2022")) pcat_construct_map( cfir_version = c("both", "original", "2022"), include_secondary = TRUE ) pcat_response_options() pcat_example_data() pcat_strategy_candidates( construct = NULL, tier = c("all", "1", "2"), include_approximate = FALSE )
cfir_version |
Mapping version to return: both source versions, the original CFIR, or the updated 2022 CFIR. |
include_secondary |
Logical; retain secondary item-to-construct links. The 2026 supplementary mapping gives item 10 a secondary Funding link. |
construct |
Optional original-CFIR or source-table construct name used to filter candidate strategies. |
tier |
Candidate strategy endorsement tier: all, tier 1, or tier 2. |
include_approximate |
Logical; include the source table's non-identical Relative Priority to Relative Advantage approximation. |
pcat_items() keeps one primary updated-CFIR construct per item for
item-level reporting. pcat_construct_map() exposes every retained
item-construct link. Candidate strategies are prompts for local deliberation,
not automatically selected or validated prescriptions.
A data frame. pcat_items() has one row per pCAT item;
pcat_construct_map() has one row per item-construct link.
pcat_items("both") pcat_construct_map("2022") pcat_response_options() head(pcat_example_data()) pcat_strategy_candidates("Available Resources", tier = "1")pcat_items("both") pcat_construct_map("2022") pcat_response_options() head(pcat_example_data()) pcat_strategy_candidates("Available Resources", tier = "1")
Creates a publication-quality diverging bar chart. Barriers are plotted to the left, facilitators to the right, and the neutral share is printed at the center. Percentages use complete five-category responses as the denominator.
pcat_palette() plot_pcat_profile( data, group_vars = NULL, label = c("cfir_original_construct", "cfir_2022_construct", "item_text", "item_id"), label_width = 42L, facet_ncol = NULL, facet_label = c("values", "names_values"), show_neutral = TRUE, show_n = TRUE, base_size = 11, label_size = 8.5, legend_position = "bottom", title = "pCAT barrier-facilitator profile", subtitle = NULL, caption = NULL, palette = pcat_palette() ) plot_pcat_heatmap( data, respondent_id = "respondent_id", facet_vars = NULL, facet_ncol = NULL, facet_label = c("values", "names_values"), base_size = 11, title = "pCAT respondent-by-item profile", subtitle = NULL, caption = paste("Missing, invalid, effect-incomplete, or absent item records are", "shown in light grey."), palette = pcat_palette() ) plot_pcat_change( data, from = NULL, to = NULL, respondent_id = "respondent_id", facet_vars = NULL, display = c("transition", "delta"), facet_ncol = NULL, facet_label = c("values", "names_values"), base_size = 11, title = "Paired pCAT change", subtitle = NULL, caption = NULL, ... )pcat_palette() plot_pcat_profile( data, group_vars = NULL, label = c("cfir_original_construct", "cfir_2022_construct", "item_text", "item_id"), label_width = 42L, facet_ncol = NULL, facet_label = c("values", "names_values"), show_neutral = TRUE, show_n = TRUE, base_size = 11, label_size = 8.5, legend_position = "bottom", title = "pCAT barrier-facilitator profile", subtitle = NULL, caption = NULL, palette = pcat_palette() ) plot_pcat_heatmap( data, respondent_id = "respondent_id", facet_vars = NULL, facet_ncol = NULL, facet_label = c("values", "names_values"), base_size = 11, title = "pCAT respondent-by-item profile", subtitle = NULL, caption = paste("Missing, invalid, effect-incomplete, or absent item records are", "shown in light grey."), palette = pcat_palette() ) plot_pcat_change( data, from = NULL, to = NULL, respondent_id = "respondent_id", facet_vars = NULL, display = c("transition", "delta"), facet_ncol = NULL, facet_label = c("values", "names_values"), base_size = 11, title = "Paired pCAT change", subtitle = NULL, caption = NULL, ... )
data |
Output from |
group_vars |
Optional grouping columns used for facets. |
label |
Item label field. |
label_width |
Approximate character width used to wrap item labels. |
facet_ncol |
Number of facet columns. |
facet_label |
Whether facet strips show values only or names and values. |
show_neutral |
Print the neutral percentage at the center. |
show_n |
Include the complete-response denominator in the neutral label. |
base_size |
Base text size. |
label_size |
Text size for item labels. |
legend_position |
Position of the shared legend. |
title, subtitle, caption
|
Optional plot annotations. |
palette |
Named color vector. See |
respondent_id |
Respondent identifier column in paired output. |
facet_vars |
Optional grouping columns used for facets. |
from, to
|
Required only when |
display |
Display transition categories or the descriptive delta code. |
... |
Passed to |
A named character vector of color values.
A ggplot object.
A ggplot object.
A ggplot object.
Runs checks of the instrument dictionary, validation, classification, summaries, reshaping, longitudinal comparison, action planning, the standard analysis wrapper, and plotting.
pcat_self_test(verbose = TRUE)pcat_self_test(verbose = TRUE)
verbose |
Print one line per check. |
A data frame with check names and results, invisibly.
Reads standard pCAT CSV files, standardizes user column names, creates entry templates, writes CSV templates, and converts responses between long and wide layouts.
pcat_read_csv( path, layout = c("auto", "long", "wide"), item_prefix = "item", na = c("", "NA") ) pcat_standardize( data, respondent_id = "respondent_id", item_id = "item_id", direction = "direction", effect = "effect", project_id = NULL, site_id = NULL, team_id = NULL, role = NULL, timepoint = NULL, assessment_date = NULL, comment = NULL, keep_original = TRUE ) pcat_template( format = c("long", "wide"), n_respondents = 1L, include_item_text = TRUE ) pcat_write_template( path, format = c("long", "wide"), n_respondents = 1L, include_item_text = TRUE, overwrite = FALSE ) pcat_wide_to_long(data, item_prefix = "item") pcat_long_to_wide(data, id_cols = NULL, item_prefix = "item")pcat_read_csv( path, layout = c("auto", "long", "wide"), item_prefix = "item", na = c("", "NA") ) pcat_standardize( data, respondent_id = "respondent_id", item_id = "item_id", direction = "direction", effect = "effect", project_id = NULL, site_id = NULL, team_id = NULL, role = NULL, timepoint = NULL, assessment_date = NULL, comment = NULL, keep_original = TRUE ) pcat_template( format = c("long", "wide"), n_respondents = 1L, include_item_text = TRUE ) pcat_write_template( path, format = c("long", "wide"), n_respondents = 1L, include_item_text = TRUE, overwrite = FALSE ) pcat_wide_to_long(data, item_prefix = "item") pcat_long_to_wide(data, id_cols = NULL, item_prefix = "item")
path |
Input or output CSV path, depending on the function. |
layout |
Input layout: auto-detected, long, or wide. |
item_prefix |
Prefix used before item numbers in wide response columns. |
na |
Character values interpreted as missing when reading a CSV. |
data |
A data frame. |
respondent_id, item_id, direction, effect
|
Source column names, supplied as character strings, for the four required fields. |
project_id, site_id, team_id, role, timepoint, assessment_date, comment
|
Optional source column names supplied as character strings. |
keep_original |
Logical; retain source columns whose names differ from the standard names. |
format |
Output layout, either long or wide. |
n_respondents |
Positive number of blank respondent records. |
include_item_text |
Logical; include item wording in a long entry template. |
overwrite |
Logical; replace an existing output file. |
id_cols |
Columns defining one assessment row in wide output. |
Standard long data require respondent_id, item_id,
direction, and effect. Standard wide response names follow
item01_direction, item01_effect, through item 14. Free-text
comments should be reviewed for sensitive information before analysis or
sharing.
A data frame, except pcat_write_template(), which invisibly returns the
normalized output path.
long <- pcat_template("long", n_respondents = 2) wide <- pcat_long_to_wide(long, id_cols = c("respondent_id", "timepoint")) pcat_wide_to_long(wide) template_path <- tempfile("pcat_template_", fileext = ".csv") pcat_write_template( template_path, format = "long", n_respondents = 2 ) imported <- pcat_read_csv(template_path) head(imported)long <- pcat_template("long", n_respondents = 2) wide <- pcat_long_to_wide(long, id_cols = c("respondent_id", "timepoint")) pcat_wide_to_long(wide) template_path <- tempfile("pcat_template_", fileext = ".csv") pcat_write_template( template_path, format = "long", n_respondents = 2 ) imported <- pcat_read_csv(template_path) head(imported)
Creates item-level summaries, team agreement and disagreement diagnostics, paired longitudinal transitions, and barrier-focused action-plan tables.
pcat_summarise( data, group_vars = NULL, respondent_id = "respondent_id", suppress_below = NULL ) pcat_consensus( data, group_vars = NULL, agreement_threshold = 0.6, polarization_min = 0.2, minimum_n = 2L ) pcat_change( data, timepoint = "timepoint", from, to, id_cols = NULL ) pcat_action_plan( data, group_vars = NULL, barrier_threshold = 0.5, strong_barrier_threshold = 0.2, include_strategy_candidates = TRUE, include_approximate = FALSE )pcat_summarise( data, group_vars = NULL, respondent_id = "respondent_id", suppress_below = NULL ) pcat_consensus( data, group_vars = NULL, agreement_threshold = 0.6, polarization_min = 0.2, minimum_n = 2L ) pcat_change( data, timepoint = "timepoint", from, to, id_cols = NULL ) pcat_action_plan( data, group_vars = NULL, barrier_threshold = 0.5, strong_barrier_threshold = 0.2, include_strategy_candidates = TRUE, include_approximate = FALSE )
data |
Raw, validated, classified, or previously summarized pCAT data, as appropriate for the function. |
group_vars |
Optional character vector of grouping columns such as site and timepoint. |
respondent_id |
Respondent identifier column name. |
suppress_below |
Optional positive minimum respondent count. Numeric
analytic measures and the derived |
agreement_threshold |
One finite number from zero through one giving the minimum dominant-side share used for a consensus label. |
polarization_min |
One finite number from zero through one giving the minimum barrier and facilitator shares required to label an item polarized. |
minimum_n |
Minimum number of valid direction responses. |
timepoint |
Timepoint column name. |
from, to
|
Earlier and later timepoint values. |
id_cols |
Columns identifying paired respondent-item records. |
barrier_threshold |
One finite number from zero through one giving the minimum barrier prevalence for action-plan inclusion. |
strong_barrier_threshold |
One finite number from zero through one giving the minimum strong-barrier prevalence for action-plan inclusion. |
include_strategy_candidates |
Logical; join source-derived candidate ERIC strategies where a direct construct link is available. |
include_approximate |
Logical; include the non-identical Relative Priority to Relative Advantage approximation. |
Directional percentages (pct_barrier, pct_neutral,
pct_facilitator, pct_effect_missing, and
pct_complete_class) use eligible records
with a valid direction and denominator n_valid_direction. Complete
five-category percentages use only eligible records with a complete
direction-plus-effect classification and denominator n_complete_class.
The directional n_neutral count can therefore exceed
n_neutral_complete when a neutral direction has an invalid effect.
All five complete-category counts are derived from pcat_class5 and
partition n_complete_class. Report both denominators when they differ.
pct_complete_class is the proportion of valid-direction records with a
complete five-category classification.
Means, medians, and change values based on pcat_display_code are
strictly descriptive. Candidate strategies require local stakeholder review
and are not automatic prescriptions. Small-cell suppression hides numeric
analytic measures and modal_class; it applies only to the returned
summary table and does not de-identify source or classified data.
When barrier or facilitator percentages are unavailable,
pcat_consensus() reports polarized = NA; unavailable data are not
treated as evidence that a cell is nonpolarized.
A data frame with a function-specific class and documented denominator attributes where applicable.
classified <- pcat_classify(pcat_example_data()) summary <- pcat_summarise( classified, group_vars = c("site_id", "timepoint") ) pcat_consensus(summary) pcat_change( classified, from = "planning", to = "mid_implementation" ) pcat_action_plan( summary, group_vars = c("site_id", "timepoint") )classified <- pcat_classify(pcat_example_data()) summary <- pcat_summarise( classified, group_vars = c("site_id", "timepoint") ) pcat_consensus(summary) pcat_change( classified, from = "planning", to = "mid_implementation" ) pcat_action_plan( summary, group_vars = c("site_id", "timepoint") )
Locates the technical user guide installed with pcatR. The guide defines
the package's data schema, validation rules, denominators, descriptive
classification logic, privacy cautions, and reporting expectations.
pcat_user_guide(format = c("pdf", "html"), open = interactive())pcat_user_guide(format = c("pdf", "html"), open = interactive())
format |
Guide format: PDF or HTML. |
open |
Logical; open the guide with the operating system's default application. |
The normalized guide path, invisibly.
path <- pcat_user_guide("html", open = FALSE) path if (interactive()) { pcat_user_guide("html", open = TRUE) }path <- pcat_user_guide("html", open = FALSE) path if (interactive()) { pcat_user_guide("html", open = TRUE) }
Checks identifiers, item numbers, direction and effect values, duplicate keys, neutral responses with recorded effects, missing effects for barrier or facilitator directions, and optional 14-item completeness.
pcat_validate( data, key_cols = NULL, require_complete = FALSE, neutral_effect = c("flag", "allow", "set_missing"), action = c("warn", "error", "none"), strict = FALSE ) ## S3 method for class 'pcat_validation' print(x, ...) pcat_validation_data(x, valid_rows_only = FALSE) pcat_validation_issues(x, level = c("all", "row", "assessment"))pcat_validate( data, key_cols = NULL, require_complete = FALSE, neutral_effect = c("flag", "allow", "set_missing"), action = c("warn", "error", "none"), strict = FALSE ) ## S3 method for class 'pcat_validation' print(x, ...) pcat_validation_data(x, valid_rows_only = FALSE) pcat_validation_issues(x, level = c("all", "row", "assessment"))
data |
Long-format pCAT response data. Required columns are
|
key_cols |
Columns defining one assessment. When omitted, available project, site, team, timepoint, assessment date, and respondent identifiers are used. |
require_complete |
Logical; require exactly one row for every item 1–14 within each assessment. |
neutral_effect |
How to handle a neutral direction paired with any recorded effect: flag it, allow it, or set the effect to missing. |
action |
Whether validation findings generate a warning, an error, or no condition. |
strict |
Logical; treat warnings as invalid when setting the object's
|
x |
A |
... |
Additional arguments, currently ignored by the print method. |
valid_rows_only |
Logical; retain only rows without row-level errors. |
level |
Return all issues, row-level issues, or assessment-completeness issues. |
The default behavior flags a neutral response paired with either effect code as
a warning because effect strength is not applicable when direction is neutral.
Validation findings remain available in structured form even when
action = "none".
pcat_validate() returns a pcat_validation object. The extractor
functions return data frames. The print method returns x invisibly.
dat <- pcat_example_data() val <- pcat_validate(dat, require_complete = TRUE, action = "none") val head(pcat_validation_data(val)) pcat_validation_issues(val)dat <- pcat_example_data() val <- pcat_validate(dat, require_complete = TRUE, action = "none") val head(pcat_validation_data(val)) pcat_validation_issues(val)
pcat_write_analysis() writes a reproducible directory containing an
analysis manifest, validation findings, optional classified responses, item
summaries, consensus diagnostics, an optional action-plan worksheet, analysis
settings, session information, and an optional profile PDF.
pcat_save_profile_pdf() places one grouping combination on each page.
It validates every page before writing a temporary PDF and replaces the target
only after the complete temporary file is nonempty. An existing directory is
rejected as an output path before any backup or output operation.
pcat_write_analysis( x, path, overwrite = FALSE, include_profile_pdf = TRUE, include_classified = TRUE, profile_label = c( "cfir_original_construct", "cfir_2022_construct", "item_text", "item_id" ) ) pcat_save_profile_pdf( data, path, group_vars = NULL, overwrite = FALSE, width = 11, height = 8.5, title_prefix = "pCAT profile", ... )pcat_write_analysis( x, path, overwrite = FALSE, include_profile_pdf = TRUE, include_classified = TRUE, profile_label = c( "cfir_original_construct", "cfir_2022_construct", "item_text", "item_id" ) ) pcat_save_profile_pdf( data, path, group_vars = NULL, overwrite = FALSE, width = 11, height = 8.5, title_prefix = "pCAT profile", ... )
x |
A |
path |
Output directory for |
overwrite |
Logical; replace files previously generated by pcatR in the output directory. Unrelated files are retained. |
include_profile_pdf |
Logical; include a multi-page profile PDF in the analysis export. |
include_classified |
Logical; write respondent-item classifications to
|
profile_label |
Item-label field used in the exported profile PDF. |
data |
Raw, validated, or classified pCAT data. |
group_vars |
Grouping columns defining one PDF page. |
width, height
|
Positive finite PDF page dimensions in inches. |
title_prefix |
Prefix used in profile page titles. |
... |
Additional arguments passed to |
If summary tables were created with suppress_below, the classified
response file and profile PDF do not automatically inherit that suppression.
Review respondent-level and graphical outputs under the applicable privacy and
disclosure rules before dissemination. When overwrite = TRUE, only
known files generated by pcat_write_analysis() are removed before the
new export is written. If profile-page construction or writing fails,
pcat_save_profile_pdf() identifies the affected group, removes its
temporary file, and leaves any existing target unchanged.
The normalized output directory or file path, invisibly.
analysis <- pcat_analyse( pcat_example_data(), group_vars = c("site_id", "timepoint"), validation_action = "none" ) analysis_dir <- tempfile("pcat_analysis_") pcat_write_analysis( analysis, path = analysis_dir, include_profile_pdf = FALSE, include_classified = FALSE ) list.files(analysis_dir) profile_path <- tempfile("pcat_profiles_", fileext = ".pdf") pcat_save_profile_pdf( analysis$classified, path = profile_path, group_vars = c("site_id", "timepoint"), label = "item_id" )analysis <- pcat_analyse( pcat_example_data(), group_vars = c("site_id", "timepoint"), validation_action = "none" ) analysis_dir <- tempfile("pcat_analysis_") pcat_write_analysis( analysis, path = analysis_dir, include_profile_pdf = FALSE, include_classified = FALSE ) list.files(analysis_dir) profile_path <- tempfile("pcat_profiles_", fileext = ".pdf") pcat_save_profile_pdf( analysis$classified, path = profile_path, group_vars = c("site_id", "timepoint"), label = "item_id" )