The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
CARWatch turns app log exports into a study table with one planned position for every participant, study day, and saliva sample. The original log events remain unchanged. If information is missing or inconsistent, conversion produces a review report instead of silently guessing.
For studies stored as one folder per participant, pass a named vector of folders. The names become participant identifiers.
library(carwatch)
fixture <- system.file("extdata", "parity", "v1.0.0", package = "carwatch")
participant_dirs <- c(VP01 = file.path(fixture, "raw", "VP01"))
imported <- read_raw_logs_from_participant_dirs(
participant_dirs,
create_report = TRUE
)
raw_logs <- imported$raw_logs
head(imported$source_audit)
#> # A tibble: 1 × 8
#> participant participant_folder source archive_member logical_source_file
#> <chr> <fs::path> <chr> <chr> <chr>
#> 1 VP01 …/parity/v1.0.0/raw/VP01 /priv… <NA> carwatch_parity_VP…
#> # ℹ 3 more variables: raw_event_count <int>, status <chr>, reason <chr>The source audit records which CSV or ZIP input was selected and why another candidate was skipped.
The first pass reconstructs the registrations, study days, and
planned samples. Use errors = "warn" so unresolved cases
are returned for review.
first_pass <- convert_raw_logs(
raw_logs,
errors = "warn",
create_report = TRUE
)
first_pass$report$issues
#> # A tibble: 0 × 15
#> # ℹ 15 variables: participant <chr>, day <chr>, sample_id <chr>, code <chr>,
#> # registration <int>, registration_day <int>, sample_position <int>,
#> # issue_id <chr>, message <chr>, details <chr>, proposed_action <chr>,
#> # proposed_action_description <chr>, resolution_status <chr>,
#> # user_decision <chr>, user_decision_value <chr>For a real study, save the report with
write_conversion_report(). Enter one allowed decision per
issue in the CSV, or use conversion_report_editor() for an
interactive review. Then read the decisions and rerun conversion against
the same raw logs:
write_conversion_report(first_pass$report, "conversion-issues.csv")
decisions <- read_conversion_report("conversion-issues.csv")
study_results <- convert_raw_logs(
raw_logs,
issue_decisions = decisions,
errors = "raise"
)The bundled fixture has no unresolved issues, so its first-pass results can be used directly here.
study_results <- first_pass$results
as_study_days(study_results)
#> # A tibble: 1 × 17
#> participant day date awakening_time awakening_type
#> <chr> <chr> <dttm> <dttm> <chr>
#> 1 VP01 D1 2025-05-15 00:00:00 2025-05-15 06:06:40 spontaneous_awakeni…
#> # ℹ 12 more variables: mismatch_summary <chr>, registration <int>,
#> # study_name <chr>, registration_day <int>, registration_sources <chr>,
#> # possible_reregistration <lgl>, day_compliant <lgl>,
#> # expected_sample_count <int>, recorded_sample_count <int>,
#> # assessed_sample_count <int>, compliant_sample_count <int>,
#> # non_compliant_samples <chr>
head(as_sample_events(study_results))
#> # A tibble: 2 × 32
#> participant day sample sampling_time barcode recorded_sample
#> <chr> <chr> <chr> <dttm> <chr> <chr>
#> 1 VP01 D1 tube-a 2025-05-15 06:06:40 barcode-a tube-a
#> 2 VP01 D1 tube-b 2025-05-15 06:36:40 barcode-b tube-b
#> # ℹ 26 more variables: sampling_time_source <chr>, sample_position <int>,
#> # day_expected <int>, day_scanned <int>, schedule_type <chr>,
#> # expected_interval_min <dbl>, actual_interval_min <dbl>,
#> # scheduled_sampling_time <dttm>, time_deviation_min <dbl>,
#> # sample_compliant <lgl>, awakening_time <dttm>, awakening_type <chr>,
#> # registration <int>, study_name <chr>, registration_day <int>,
#> # registration_sources <chr>, possible_reregistration <lgl>, …
summarize_compliance(study_results)
#> # A tibble: 2 × 8
#> sample_position total_samples assessed_samples compliant_samples
#> <int> <int> <int> <int>
#> 1 1 1 1 1
#> 2 2 1 1 1
#> # ℹ 4 more variables: non_compliant_samples <int>, unassessed_samples <int>,
#> # missing_sampling_time <int>, compliance_rate <dbl>Complete Study Results use a three-header CSV format so day-, sample-, and variable-level information remains unambiguous.
results_file <- tempfile(fileext = ".csv")
write_study_results(study_results, results_file)
restored <- read_study_results(results_file)
restored
#> <carwatch_results: complete; 1 participants; 41 fields>
#> # A tibble: 1 × 42
#> participant v1 v2 v3 v4 v5 v6
#> <chr> <dttm> <dttm> <chr> <chr> <int> <chr>
#> 1 VP01 2025-05-15 00:00:00 2025-05-15 06:06:40 spontan… <NA> 1 pari…
#> # ℹ 35 more variables: v7 <int>, v8 <chr>, v9 <lgl>, v10 <lgl>, v11 <int>,
#> # v12 <int>, v13 <int>, v14 <int>, v15 <chr>, v16 <dttm>, v17 <chr>,
#> # v18 <chr>, v19 <chr>, v20 <int>, v21 <int>, v22 <int>, v23 <chr>,
#> # v24 <dbl>, v25 <dbl>, v26 <dttm>, v27 <dbl>, v28 <lgl>, v29 <dttm>,
#> # v30 <chr>, v31 <chr>, v32 <chr>, v33 <int>, v34 <int>, v35 <int>,
#> # v36 <chr>, v37 <dbl>, v38 <dbl>, v39 <dttm>, v40 <dbl>, v41 <lgl>Use simple = TRUE only for display. A simplified result
intentionally cannot be saved as a complete Study Results file.
After conversion, load the laboratory measurements with
read_saliva(), merge them with merge_saliva(),
and continue with the saliva-analysis vignette.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.