Abstract
This document provides conventions for writing R functions for data quality assessments in dataquieR. It focuses on function families, standard argument names, input handling, result objects, and documentation. Development workflow and source style are documented on separate policy pages.
Code developed in teams, especially code intended for a larger community, needs to be comprehensible for all contributors and users. This page describes the function-level conventions for dataquieR indicator, preparation, report, and utility functions.
Development workflow, branch and release rules, CRAN-related testing
policy, and the reusable prompt used for dataquieR development sessions
are documented in dataquieR
development policy and reusable prompt. Source style is defined by
the package lintr configuration and summarized in dataquieR and QIF linting
policy.
This page focuses on stable interfaces: standard argument names, metadata handling, input validation, result slots, and documentation expectations.
Indicator functions perform data quality assessments and usually
return dataquieR_result objects. Their names use the data
quality dimension as prefix:
int_: Integritycom_: Completenesscon_: Consistencyacc_: Accuracydes_: Descriptive functions. Strictly speaking, these
functions do not compute indicator metrics. In the broader
report-function sense, however, they create descriptive results for one
entity or for a group of entities such as variables, segments, or data
frames.pro_: Legacy applicability functions. Currently, this
mainly covers pro_applicability_matrix(), which is retained
for compatibility and should be treated as a soft-deprecation candidate.
It is not part of the current dq_report2() report flow. The
future contract is tracked in dataquieR
issue #978.Indicator functions may address different metadata entities. Item-level functions commonly work on one or more measurement variables. Dataframe, segment, cross-item, and variable-group level functions use the corresponding metadata levels.
Report-facing functions use prefixes such as dq_, or S3
method names such as print.*, summary.*, and
plot.*. The central report entry point is
dq_report2(). It prepares report inputs, plans and
evaluates applicable indicator calls, and stores the results in a
dataquieR_resultset2.
Indicator functions should be callable directly, but they must also
work when called from dq_report2(). This requires stable
argument names and predictable result slots.
Use prep_ for exported preparation helpers intended for
users or report authors. Use util_ for internal helpers.
Internal helpers are not part of the public user API and should normally
be used through package code rather than via ::: from
external scripts. Internal util_ helpers should normally
have Roxygen comments for developer documentation and use
@noRd when they are not intended to create public manual
pages.
Use established argument names when a function accepts one of the standard concepts. Do not invent near-synonyms for existing concepts. The current Roxygen templates in the package are the primary source for exact wording:
.template_function_indicator.template_function_developer.template_function_report_planThe following argument names are standard in current indicator and report code. Not every function needs all of them, but when the concept applies, use the standard name.
Arguments ending in _vars refer to columns in
study_data. In undecorated functions, these arguments are
interpreted in terms of the active label_col. The
zzz_*.R decorators allow matching through any label column
available in the metadata.
The standard argument order for indicator functions is tested in the package. When present, use:
resp_vars, group_vars, time_vars, co_vars,
study_data, label_col, item_level, meta_data, meta_data_v2
Metadata-level arguments are equivalent input concepts. They may be
supplied as data frames, fully qualified file names, URLs, or references
to data frames already registered in the data-frame cache or registry.
Use prep_list_dataframes() to inspect which data frames are
currently registered. This applies to item_level,
meta_data, dataframe_level,
segment_level, cross_item_level, and the
matching meta_data_* aliases.
| Argument | Convention |
|---|---|
study_data |
Study data. Passing a data.frame is the most intuitive
and common option. In registry or external-data contexts,
study_data may also be a character value naming a
registered data frame, a fully qualified file name, or a URL. |
item_level |
Argument name for item-level metadata. This may be a
data.frame, a registry reference, a fully qualified file
name, or a URL, depending on context. |
meta_data |
Valid alternative argument name for item_level. This
name has existed for a long time and remains part of the interface; it
accepts the same input forms as item_level. |
meta_data_v2 |
Optional shortcut for loading workbook-like metadata. If supplied,
current code purges the data-frame cache or registry and calls
prep_load_workbook_like_file(). In realistic workflows,
users may omit it and control the metadata/data-frame registry
manually. |
label_col |
Metadata attribute used for labels in individual outputs. In full reports, label choice can depend on the use-case context. |
resp_vars |
Selected response or measurement variables. This is most common for item-level indicator functions. If missing or empty, functions commonly operate on all applicable variables. |
group_vars |
Variables whose influence on the response or outcome may itself indicate a data quality problem, for example examiner effects or device effects on measured values. Only functions that support grouped assessments need this argument. |
time_vars |
Variables indicating measurement time points, for example for time-course plots. |
co_vars |
Covariables with expected or known effects on the outcome. They are
used for adjustment so that assessments of group_vars
effects are not distorted, for example when one examiner mostly measured
blood pressure in young women and another examiner mostly measured blood
pressure in older men. |
dataframe_level, segment_level,
cross_item_level, item_computation_level |
Current metadata-level names. These are one level of input concepts, not subordinate to item-level metadata. |
meta_data_dataframe, meta_data_segment,
meta_data_cross_item,
meta_data_item_computation |
Supported aliases used by existing APIs and templates. |
`cross-item_level` |
Supported alias reflecting the standard metadata workbook sheet name. Do not rename it away when compatibility with workbook names matters. |
flip_mode |
Generic plotting/output option influencing figure orientation.
dataquieR controls figure orientation; the default favors
taller-than-wide output for A4 printing, and flip_mode can
change this. |
threshold_value |
Compatibility argument in older functions. Do not use it for new behavior; prefer grading rules. |
specific_args |
Named list of function-specific report-call arguments. This is
relevant for, and defined by, dq_report* report calls. |
arg_overrides |
Named list of arguments to pass to all applicable indicator calls.
This is relevant for, and defined by, dq_report* report
calls. |
Additional function-specific arguments are allowed when the concept is genuinely specific to the check.
Study data are usually supplied as data.frame objects.
The usual structure is wide: one observational unit per row and one
variable per column. Column names are variable names and must be
unique.
Study variable names are defined by the study setup, not by dataquieR programmers. They may therefore be non-syntactic R names. R supports arbitrary column names when code explicitly allows them; implementations must not assume syntactic names unless they validate and document that limitation. In repeated-measurement settings, a systematic suffix indicating measurement order is useful where this is part of the study convention.
Metadata describe expected characteristics of study data and the report context. They can include item-level attributes, dataframe-level metadata, segment-level metadata, cross-item metadata, and computed-item metadata.
For current metadata concepts and examples, use the metadata tutorials, in particular Annotation of Metadata.
When code refers to known metadata columns or attributes, use the constants defined by dataquieR. For example, prefer:
meta_data[[VAR_NAMES]]
meta_data[[DATA_TYPE]]
over string literals such as meta_data[["VAR_NAMES"]],
and prefer bracket access over $ access for programmatic
metadata handling.
Do not hard-code study variable names, expected variable-list lengths, data-frame names, embedded metadata values, or new threshold logic in indicator implementations. Function behavior should be controlled by explicit arguments, metadata, grading rules, or report planning.
All function arguments are user input and must be validated carefully. Use current preparation and validation helpers instead of reimplementing shared input checks.
prep_prepare_dataframes() is the public preparation
entry point. Internal code can use helpers such as:
util_prepare_dataquieR_inputs()util_prepare_item_level_metadata()util_expect_data_frame()util_expect_scalar()util_correct_variable_use()util_stop_if_not()util_error(), util_warning(), and
util_message()These helpers should be preferred because they preserve dataquieR condition classes and report behavior.
For examples, use existing package code and the current Roxygen
templates rather than small artificial examples on this page. Good
starting points are current indicator implementations in
QualityIndicatorFunctions/R, especially functions whose
signatures inherit from .template_function_indicator.
Indicator functions return named lists that are validated or coerced
as dataquieR_result objects. Result names and result-slot
classes are enforced by tests and utility functions such as
util_dataquieR_result() and
ALLOWED_DATAQUIER_RESULT_NAMES.
The general result-slot naming scheme is:
<Category><Level/Entity><Result Class>
Categories include:
Modified: modified study data or metadataFlagged: flagged study dataLevels or entities include:
Summary: item-level or overall summariesDataframeSegmentVariableGroupStudyResultOtherResult classes include:
Table: machine-readable data.frameData: human-readable display data, often derived from a
table slotPlot: a ggplot2 objectPlotList: a named list of plotsStudyData: study-data-like outputDetails: supporting detail outputSlots/Slot: structured report-slot
metadataSummaries/Summary: compact summariesCommon result names include:
SummaryTableSummaryDataSummaryPlotSummaryPlotListReportSummaryTableDataframeTableDataframeDataDataframeDataListSegmentTableSegmentDataSegmentDataListVariableGroupTableVariableGroupDataVariableGroupPlotListResultTableResultDataOtherTableOtherDataPlotlyPlotDataTypePlotListModifiedMetaDataModifiedStudyDataFlaggedStudyDataScalarValue_*OtherData and OtherTable are allowed result
slots for extensions that do not fit a more specific entity. Prefer a
more specific slot name when one clearly applies, but do not treat
Other* slots as deprecated.
*Table output*Table slots are machine-readable. Where applicable, use
technical metric column names following the indicator-metric convention,
for example PCT_int_sts_element, NUM_*,
FLG_*, GRADING, or CLS_*.
The table should contain a stable entity column such as
Variables, VAR_NAMES, DF_NAME,
Segment, or another entity-specific identifier.
Variables is used for labels in many item-level summaries.
VAR_NAMES should contain variable names, not labels.
Columns can carry a description attribute for
report-table header tooltips. Columns containing rendered labels, for
example htmltools::HTML() objects, should provide plain
text labels through the attributes expected by the report helpers.
*Data output*Data slots are human-readable display data. They are
often derived from the corresponding *Table slot by
translating metric names, formatting percentages, and selecting columns
relevant for report display. Use existing helpers such as
util_make_data_slot_from_table_slot() where applicable.
ReportSummaryTableReportSummaryTable is a structured summary table used by
report summaries and overview visualizations. It is validated by
dedicated utility code and should contain numeric summary values except
for the entity columns and explicitly supported metadata columns.
Depending on its dimensions, it can be visualized as text, as a bar
chart, or as a balloon plot or heatmap. A table with only one row and
one column can be rendered as text. A table with only one row or only
one column can be rendered as a bar chart. Tables with multiple rows and
columns can be rendered as balloon plots or heatmaps.
Columns of data.frame outputs that can later be rendered
in a dq_report() or dq_report2() table should
carry an explicit DATA_TYPE attribute. This applies
especially to SummaryTable, SummaryData,
ReportSummaryTable, DataframeTable,
DataframeData, SegmentTable,
SegmentData, ResultTable, and
ResultData outputs.
Use constants defined by dataquieR rather than string literals. Ordinary numeric, factor, string, date, and datetime columns should use the matching metadata data type constants. Result-specific types should be made explicit as well:
SummaryData[["Missing codes N (%)"]] <- sprintf(
"%i (%.1f)",
n_missing,
p_missing
)
attr(SummaryData[["Missing codes N (%)"]], DATA_TYPE) <-
DATA_TYPE_NUMBER_PAREN
SummaryTable$GRADING <- n_measurements_p < threshold_value
attr(SummaryTable$GRADING, DATA_TYPE) <- DATA_TYPE_LOGICAL
SummaryTable$N <- n_measurements
attr(SummaryTable$N, DATA_TYPE) <- DATA_TYPES$INTEGER
SummaryData$Variables <- variable_labels
attr(SummaryData$Variables, DATA_TYPE) <- DATA_TYPES$STRING
Use DATA_TYPE_NUMBER_PAREN for compact count/percentage
columns such as "12 (3.4)" or "12 (3.4%)".
Report tables can then sort and filter these columns numerically by the
percentage in parentheses, with the leading count as a tie breaker for
sorting. Use DATA_TYPE_LOGICAL for boolean result columns,
including GRADING columns where displayed
0/1 values mean
FALSE/TRUE. Use
DATA_TYPES$INTEGER, DATA_TYPES$FLOAT,
DATA_TYPES$STRING, and the other values from
DATA_TYPES for data types that are part of the metadata
concept. Use separate DATA_TYPE_* constants only for
report-specific display types that are not ordinary metadata data types,
such as DATA_TYPE_NUMBER_PAREN and
DATA_TYPE_LOGICAL.
Indicator metric columns are numeric until they are converted by a
grading rule. Columns that already contain a classification, for example
CLS_*, should be typed as categorical or factor-like result
columns.
Output should allow readers to understand tables and graphs without
consulting other sources. Functions that create figures should support
flip_mode. Add a flip_mode formal and use
util_coord_flip() when building the plot; see
acc_distributions() for a current example.
Data quality related output should:
Findings that cross grading rules can usually only be highlighted
later, because grading rules may be exchanged after a function has
computed its figure. If a figure needs grading-dependent highlighting,
make that part dynamic. See the quosures used by
con_contradictions_redcap() for an example of dynamic
figure behavior.
See also the Color concept.
Exported dataquieR functions have two documentation routes:
Standard parameter documentation should use the current package templates where possible:
.template_function_indicator.template_function_developer.template_function_report_planInternal utility functions should carry Roxygen documentation and use
@noRd. Do not add examples for these helpers; examples
inflate the already large package documentation and increase
package-check time.
Code style is governed by
QualityIndicatorFunctions/.lintr, run through
Rscript .lint.R, and summarized in dataquieR and QIF linting
policy.
Important local choices include:
%>%,# nolint comments for justified
exceptions,util_error(), util_warning(), and
util_message() in package implementation code instead of
direct base conditions,return() where it improves readability,
especially for early exits.Use dq_report2() and dq_report_by() for
current report workflows. Avoid documenting older defunct interfaces as
current workflows.
Older result names and compatibility arguments may still exist in package code. When maintaining them, keep behavior compatible and document new development against the current conventions above.