diff --git a/.Rprofile b/.Rprofile index c81932b..db760ca 100644 --- a/.Rprofile +++ b/.Rprofile @@ -12,3 +12,14 @@ if (interactive()) { } source("renv/activate.R") + +# Path to download Eunomia datasets +Sys.setenv(EUNOMIA_DATA_FOLDER = file.path("dev/test_db/eunomia")) +# Name of the synthetic dataset to use +Sys.setenv(TEST_DB_NAME = "GiBleed") +# OMOP CDM version +Sys.setenv(TEST_DB_OMOP_VERSION = "5.3") +# Schema name for data +Sys.setenv(TEST_DB_CDM_SCHEMA = "main") +# Schema name for results +Sys.setenv(TEST_DB_RESULTS_SCHEMA = "main") diff --git a/.renvignore b/.renvignore index 4a5e932..78dc387 100644 --- a/.renvignore +++ b/.renvignore @@ -1 +1,4 @@ -/dev/ +# Ignore golem dev scripts +/dev/01_start.R +/dev/02_dev.R +/dev/03_deploy.R diff --git a/DESCRIPTION b/DESCRIPTION index e6aeb7b..ef66bfb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -10,13 +10,19 @@ Imports: DT, ggplot2, golem (>= 0.4.1), - shiny (>= 1.9.1) + shiny (>= 1.9.1), + DBI, + duckdb, + glue Suggests: devtools, usethis, styler, testthat (>= 3.0.0), spelling, + here, + CDMConnector, + lubridate, lintr Encoding: UTF-8 LazyData: true diff --git a/NAMESPACE b/NAMESPACE index 03fe1db..939f17c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,6 +3,8 @@ export(run_app) import(bslib) import(shiny) +importFrom(DBI,dbConnect) +importFrom(duckdb,duckdb) importFrom(ggplot2,aes) importFrom(ggplot2,geom_bar) importFrom(ggplot2,geom_boxplot) @@ -10,6 +12,7 @@ importFrom(ggplot2,ggplot) importFrom(ggplot2,ggtitle) importFrom(ggplot2,xlab) importFrom(ggplot2,ylab) +importFrom(glue,glue) importFrom(golem,activate_js) importFrom(golem,add_resource_path) importFrom(golem,bundle_resources) diff --git a/R/fct_connect_to_test_db.R b/R/fct_connect_to_test_db.R new file mode 100644 index 0000000..ebc08f2 --- /dev/null +++ b/R/fct_connect_to_test_db.R @@ -0,0 +1,19 @@ +#' connect_to_test_db +#' +#' Connect to the test database +#' (using environment variables from .Rprofile) +#' +#' @return A DBI connection to the test database +#' +#' @importFrom DBI dbConnect +#' @importFrom duckdb duckdb +#' @importFrom glue glue +#' +#' @noRd +connect_to_test_db <- function() { + dir <- Sys.getenv("EUNOMIA_DATA_FOLDER") + name <- Sys.getenv("TEST_DB_NAME") + version <- Sys.getenv("TEST_DB_OMOP_VERSION") + # Connect to the duckdb test database + dbConnect(duckdb(dbdir = glue("{dir}/{name}_{version}_1.0.duckdb"))) +} diff --git a/README.md b/README.md index d0f3d4a..d9e82e4 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,14 @@ as it has good support for R package development and Shiny. install.packages("renv") renv::restore() ``` +3. Create the [duckdb](https://github.com/duckdb/duckdb) test database and run the analyses by running from an R console in the project directory (test dataset properties can be updated in the [`.Rprofile`](https://github.com/UCLH-Foundry/omop-data-catalogue/blob/main/.Rprofile) file): -3. To preview the app locally, run the following from an R console within the project directory: + ```r + source(here::here("dev/test_db/setup_test_db.R")) + source(here::here("dev/omop_analyses/analyse_omop_cdm.R")) + ``` + +4. To preview the app locally, run the following from an R console within the project directory: ```r golem::run_dev() diff --git a/dev/omop_analyses/analyse_omop_cdm.R b/dev/omop_analyses/analyse_omop_cdm.R new file mode 100644 index 0000000..f78435e --- /dev/null +++ b/dev/omop_analyses/analyse_omop_cdm.R @@ -0,0 +1,197 @@ + +library(tidyverse) + +dir <- Sys.getenv("EUNOMIA_DATA_FOLDER") +name <- Sys.getenv("TEST_DB_NAME") +version <- Sys.getenv("TEST_DB_OMOP_VERSION") + +# Connect to the duckdb test database +con <- DBI::dbConnect(duckdb::duckdb( + dbdir = glue::glue("{dir}/{name}_{version}_1.0.duckdb"))) + +# Function to execute one or more SQL queries and clear results +create_results_tables <- function(con, sql) { + # Execute sql query + result <- DBI::dbSendStatement(con, sql) + # Clear results + DBI::dbClearResult(result) +} + +# Function to produce the 'calypso_concepts' table +# from a list of concept ids +analyse_concepts <- function(cdm, concepts) { + # Extract columns from concept table + cdm$concept |> + filter(concept_id %in% concepts) |> + select( + concept_id, + concept_name, + vocabulary_id, + domain_id, + concept_class_id, + standard_concept, + concept_code + ) |> + collect() +} + +# Function to produce the 'calypso_monthly_counts' table +analyse_monthly_counts <- function(cdm) { + # Function to analyse a column from a specific table + # for each month + analyse_table <- function(table, concept, date) { + # Extract year and month from date column + table <- table |> + mutate( + concept_id = {{ concept }}, + date_year = lubridate::year({{ date }}), + date_month = lubridate::month({{ date }}) + ) + # Get total count for each month + total_count <- table |> + select(concept_id, date_year, date_month) |> + collect() |> + group_by(date_year, date_month, concept_id) |> + count(name = "total_count") + # Get number of unique patients per concept for each month + person_count <- table |> + select(concept_id, date_year, date_month, person_id) |> + collect() |> + group_by(date_year, date_month, concept_id) |> + reframe(person_count = n_distinct(person_id)) + # Get number of records per person for each month + table |> + select(concept_id, date_year, date_month) |> + distinct() |> + collect() |> + inner_join(total_count, join_by(date_year, date_month, concept_id)) |> + inner_join(person_count, join_by(date_year, date_month, concept_id)) |> + mutate(records_per_person = (total_count / person_count)) |> + select( + concept_id, + date_year, + date_month, + person_count, + records_per_person + ) + } + # Combine results for all tables + bind_rows( + cdm$condition_occurrence |> analyse_table(condition_concept_id, condition_start_date), + cdm$drug_exposure |> analyse_table(drug_concept_id, drug_exposure_start_date), + cdm$procedure_occurrence |> analyse_table(procedure_concept_id, procedure_date), + cdm$device_exposure |> analyse_table(device_concept_id, device_exposure_start_date), + cdm$measurement |> analyse_table(measurement_concept_id, measurement_date), + cdm$observation |> analyse_table(observation_concept_id, observation_date), + cdm$specimen |> analyse_table(specimen_concept_id, specimen_date) + ) +} + +# Function to produce the 'calypso_summary_stats' table +analyse_summary_stats <- function(cdm) { + # Function to analyse a numeric column + # by calculation the mean and the standard deviation + analyse_numeric_column <- function(table, concept, value) { + # Rename columns and remove empty values + table <- table |> + select(concept_id = {{ concept }}, value = {{ value }}) |> + filter(!is.na(value)) |> + collect() + # Calculate mean + df_mean <- table |> + group_by(concept_id) |> + reframe( + summary_attribute = "mean", + value_as_number = mean(value) + ) + # Calculate standard deviation + df_sd <- table |> + group_by(concept_id) |> + reframe( + summary_attribute = "sd", + value_as_number = sd(value) + ) + # Combine mean and standard deviation + bind_rows(df_mean, df_sd) + } + # Combine results for all columns + bind_rows( + cdm$measurement |> analyse_numeric_column(measurement_concept_id, value_as_number), + cdm$observation |> analyse_numeric_column(observation_concept_id, value_as_number) + ) +} + +# Function to write result to the results schema +write_results <- function(data, con, table) { + # Insert data into the specified table + # (in the results schema) + DBI::dbWriteTable( + conn = con, + name = DBI::Id( + schema = Sys.getenv("TEST_DB_RESULTS_SCHEMA"), + table = table + ), + value = data, + append = TRUE, + overwrite = FALSE + ) +} + +# Retrieve SQL query to create Calypso tables +# (using the results schema) +sql <- gsub( + "@resultsDatabaseSchema", + Sys.getenv("TEST_DB_RESULTS_SCHEMA"), + readr::read_file(here::here("dev/omop_analyses/calypso_tables.sql")) +) + +# Create the Calypso tables to the results schema +create_results_tables(con, sql) + +# Load the data in a CDMConnector object +cdm <- CDMConnector::cdm_from_con( + con = con, + cdm_schema = Sys.getenv("TEST_DB_CDM_SCHEMA"), + write_schema = Sys.getenv("TEST_DB_RESULTS_SCHEMA"), + cdm_name = name +) + +# Generate monthly counts and write it to the DB +monthly_counts <- analyse_monthly_counts(cdm) +monthly_counts |> + write_results(con, "calypso_monthly_counts") + +# Generate summary stats and write it to the DB +summary_stats <- analyse_summary_stats(cdm) +summary_stats |> + write_results(con, "calypso_summary_stats") + +# Get list of concept ids +ids <- bind_rows( + { monthly_counts |> select(concept_id) }, + { summary_stats |> select(concept_id) } +) |> distinct() +ids <- ids$concept_id + +# Retrieve concept properties from the list of ids +analyse_concepts(cdm, ids) |> + write_results(con, "calypso_concepts") + +# Clean up +DBI::dbDisconnect(con) +rm(create_results_tables) +rm(analyse_concepts) +rm(analyse_monthly_counts) +rm(analyse_summary_stats) +rm(write_results) +rm(monthly_counts) +rm(summary_stats) +rm(ids) +rm(cdm) +rm(con) +rm(sql) +rm(dir) +rm(name) +rm(version) + +detach("package:tidyverse", unload = TRUE) diff --git a/dev/omop_analyses/calypso_tables.sql b/dev/omop_analyses/calypso_tables.sql new file mode 100644 index 0000000..8a1a383 --- /dev/null +++ b/dev/omop_analyses/calypso_tables.sql @@ -0,0 +1,28 @@ +DROP TABLE IF EXISTS @resultsDatabaseSchema.calypso_concepts; +DROP TABLE IF EXISTS @resultsDatabaseSchema.calypso_monthly_counts; +DROP TABLE IF EXISTS @resultsDatabaseSchema.calypso_summary_stats; + +CREATE TABLE @resultsDatabaseSchema.calypso_concepts ( + concept_id BIGINT, + concept_name VARCHAR, + domain_id VARCHAR, + vocabulary_id VARCHAR, + concept_class_id VARCHAR, + standard_concept VARCHAR, + concept_code VARCHAR +); + +CREATE TABLE @resultsDatabaseSchema.calypso_monthly_counts ( + concept_id BIGINT, + date_year INTEGER, + date_month INTEGER, + person_count BIGINT, + records_per_person DOUBLE +); + +CREATE TABLE @resultsDatabaseSchema.calypso_summary_stats ( + concept_id BIGINT, + summary_attribute VARCHAR, + value_as_string VARCHAR, + value_as_number DOUBLE +); diff --git a/dev/test_db/eunomia/.gitignore b/dev/test_db/eunomia/.gitignore new file mode 100644 index 0000000..7499f89 --- /dev/null +++ b/dev/test_db/eunomia/.gitignore @@ -0,0 +1,5 @@ +# Eunomia data +*.zip + +# duckdb databases +*.duckdb diff --git a/dev/test_db/setup_test_db.R b/dev/test_db/setup_test_db.R new file mode 100644 index 0000000..a8b5e5b --- /dev/null +++ b/dev/test_db/setup_test_db.R @@ -0,0 +1,23 @@ + +# Create an duckdb database from Eunomia datasets +con <- DBI::dbConnect( + duckdb::duckdb( + dbdir = CDMConnector::eunomia_dir( + dataset_name = Sys.getenv("TEST_DB_NAME"), + cdm_version = Sys.getenv("TEST_DB_OMOP_VERSION"), + database_file = tempfile(fileext = ".duckdb") + ) + ) +) + +# Use 'cdm_from_con' to load the dataset and verify integrity +CDMConnector::cdm_from_con( + con = con, + cdm_schema = Sys.getenv("TEST_DB_CDM_SCHEMA"), + write_schema = Sys.getenv("TEST_DB_RESULTS_SCHEMA"), + cdm_name = Sys.getenv("TEST_DB_NAME") +) + +# Clean up +DBI::dbDisconnect(con) +rm(con) diff --git a/renv.lock b/renv.lock index 400f882..e5093aa 100644 --- a/renv.lock +++ b/renv.lock @@ -9,6 +9,48 @@ ] }, "Packages": { + "CDMConnector": { + "Package": "CDMConnector", + "Version": "1.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "DBI", + "R", + "checkmate", + "cli", + "dbplyr", + "dplyr", + "fs", + "generics", + "glue", + "jsonlite", + "lifecycle", + "methods", + "omopgenerics", + "purrr", + "readr", + "rlang", + "stringi", + "stringr", + "tidyr", + "tidyselect", + "waldo", + "withr" + ], + "Hash": "2bae94aed83da2007c938f3d2fa1a48f" + }, + "DBI": { + "Package": "DBI", + "Version": "1.2.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "065ae649b05f1ff66bb0c793107508f5" + }, "DT": { "Package": "DT", "Version": "0.33", @@ -58,6 +100,60 @@ ], "Hash": "1920b2f11133b12350024297d8a4ff4a" }, + "R.cache": { + "Package": "R.cache", + "Version": "0.16.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R.methodsS3", + "R.oo", + "R.utils", + "digest", + "utils" + ], + "Hash": "fe539ca3f8efb7410c3ae2cf5fe6c0f8" + }, + "R.methodsS3": { + "Package": "R.methodsS3", + "Version": "1.8.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "utils" + ], + "Hash": "278c286fd6e9e75d0c2e8f731ea445c8" + }, + "R.oo": { + "Package": "R.oo", + "Version": "1.26.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R.methodsS3", + "methods", + "utils" + ], + "Hash": "4fed809e53ddb5407b3da3d0f572e591" + }, + "R.utils": { + "Package": "R.utils", + "Version": "2.12.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R.methodsS3", + "R.oo", + "methods", + "tools", + "utils" + ], + "Hash": "3dc2829b790254bfba21e60965787651" + }, "R6": { "Package": "R6", "Version": "2.5.1", @@ -109,6 +205,16 @@ ], "Hash": "d7421bb5dfeb2676b9e4a5a60c2fcfd2" }, + "backports": { + "Package": "backports", + "Version": "1.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "e1e1b9d75c37401117b636b7ae50827a" + }, "base64enc": { "Package": "base64enc", "Version": "0.1-3", @@ -119,6 +225,42 @@ ], "Hash": "543776ae6848fde2f48ff3816d0628bc" }, + "bit": { + "Package": "bit", + "Version": "4.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "d242abec29412ce988848d0294b208fd" + }, + "bit64": { + "Package": "bit64", + "Version": "4.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bit", + "methods", + "stats", + "utils" + ], + "Hash": "9fe98599ca456d6552421db0d6772d8f" + }, + "blob": { + "Package": "blob", + "Version": "1.2.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "methods", + "rlang", + "vctrs" + ], + "Hash": "40415719b5a479b87949f3aa0aee737c" + }, "brew": { "Package": "brew", "Version": "1.0-10", @@ -136,6 +278,26 @@ ], "Hash": "c1ee497a6d999947c2c224ae46799b1a" }, + "broom": { + "Package": "broom", + "Version": "1.0.6", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "backports", + "dplyr", + "generics", + "glue", + "lifecycle", + "purrr", + "rlang", + "stringr", + "tibble", + "tidyr" + ], + "Hash": "a4652c36d1f8abfc3ddf4774f768c934" + }, "bslib": { "Package": "bslib", "Version": "0.8.0", @@ -182,6 +344,30 @@ ], "Hash": "d7e13f49c19103ece9e58ad2d83a7354" }, + "cellranger": { + "Package": "cellranger", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "rematch", + "tibble" + ], + "Hash": "f61dbaec772ccd2e17705c1e872e9e7c" + }, + "checkmate": { + "Package": "checkmate", + "Version": "2.3.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "backports", + "utils" + ], + "Hash": "0e14e01ce07e7c88fd25de6d4260d26b" + }, "cli": { "Package": "cli", "Version": "3.6.3", @@ -203,6 +389,16 @@ ], "Hash": "3f038e5ac7f41d4ac41ce658c85e3042" }, + "codetools": { + "Package": "codetools", + "Version": "0.2-20", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "61e097f35917d342622f21cdc79c256e" + }, "colorspace": { "Package": "colorspace", "Version": "2.1-1", @@ -234,6 +430,19 @@ ], "Hash": "8b7222e9d9eb5178eea545c0c4d33fc2" }, + "conflicted": { + "Package": "conflicted", + "Version": "1.2.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "memoise", + "rlang" + ], + "Hash": "bb097fccb22d156624fd07cd2894ddb6" + }, "cpp11": { "Package": "cpp11", "Version": "0.4.7", @@ -293,6 +502,59 @@ ], "Hash": "411ca2c03b1ce5f548345d2fc2685f7a" }, + "cyclocomp": { + "Package": "cyclocomp", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "callr", + "crayon", + "desc", + "remotes", + "withr" + ], + "Hash": "cdc4a473222b0112d4df0bcfbed12d44" + }, + "data.table": { + "Package": "data.table", + "Version": "1.15.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "8ee9ac56ef633d0c7cab8b2ca87d683e" + }, + "dbplyr": { + "Package": "dbplyr", + "Version": "2.5.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "DBI", + "R", + "R6", + "blob", + "cli", + "dplyr", + "glue", + "lifecycle", + "magrittr", + "methods", + "pillar", + "purrr", + "rlang", + "tibble", + "tidyr", + "tidyselect", + "utils", + "vctrs", + "withr" + ], + "Hash": "39b2e002522bfd258039ee4e889e0fd1" + }, "desc": { "Package": "desc", "Version": "1.4.3", @@ -386,6 +648,61 @@ ], "Hash": "45a6a596bf0108ee1ff16a040a2df897" }, + "dplyr": { + "Package": "dplyr", + "Version": "1.1.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "cli", + "generics", + "glue", + "lifecycle", + "magrittr", + "methods", + "pillar", + "rlang", + "tibble", + "tidyselect", + "utils", + "vctrs" + ], + "Hash": "fedd9d00c2944ff00a0e2696ccf048ec" + }, + "dtplyr": { + "Package": "dtplyr", + "Version": "1.3.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "data.table", + "dplyr", + "glue", + "lifecycle", + "rlang", + "tibble", + "tidyselect", + "vctrs" + ], + "Hash": "54ed3ea01b11e81a86544faaecfef8e2" + }, + "duckdb": { + "Package": "duckdb", + "Version": "1.0.0-2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "DBI", + "R", + "methods", + "utils" + ], + "Hash": "c68785a280aa69dbe449b3cf98fa3dd1" + }, "ellipsis": { "Package": "ellipsis", "Version": "0.3.2", @@ -446,6 +763,22 @@ ], "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d" }, + "forcats": { + "Package": "forcats", + "Version": "1.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "magrittr", + "rlang", + "tibble" + ], + "Hash": "1a0a9a3d5083d0d573c4214576f1e690" + }, "fs": { "Package": "fs", "Version": "1.6.4", @@ -457,6 +790,39 @@ ], "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a" }, + "gargle": { + "Package": "gargle", + "Version": "1.5.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "fs", + "glue", + "httr", + "jsonlite", + "lifecycle", + "openssl", + "rappdirs", + "rlang", + "stats", + "utils", + "withr" + ], + "Hash": "fc0b272e5847c58cd5da9b20eedbd026" + }, + "generics": { + "Package": "generics", + "Version": "0.1.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "methods" + ], + "Hash": "15e9634c0fcd294799e9b2e929ed1b86" + }, "gert": { "Package": "gert", "Version": "2.1.0", @@ -554,6 +920,59 @@ ], "Hash": "dc12172dc35c6c80e18b430dc546fc24" }, + "googledrive": { + "Package": "googledrive", + "Version": "2.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "gargle", + "glue", + "httr", + "jsonlite", + "lifecycle", + "magrittr", + "pillar", + "purrr", + "rlang", + "tibble", + "utils", + "uuid", + "vctrs", + "withr" + ], + "Hash": "e99641edef03e2a5e87f0a0b1fcc97f4" + }, + "googlesheets4": { + "Package": "googlesheets4", + "Version": "1.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cellranger", + "cli", + "curl", + "gargle", + "glue", + "googledrive", + "httr", + "ids", + "lifecycle", + "magrittr", + "methods", + "purrr", + "rematch2", + "rlang", + "tibble", + "utils", + "vctrs", + "withr" + ], + "Hash": "d6db1667059d027da730decdc214b959" + }, "gtable": { "Package": "gtable", "Version": "0.3.5", @@ -569,6 +988,27 @@ ], "Hash": "e18861963cbc65a27736e02b3cd3c4a0" }, + "haven": { + "Package": "haven", + "Version": "2.5.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "cpp11", + "forcats", + "hms", + "lifecycle", + "methods", + "readr", + "rlang", + "tibble", + "tidyselect", + "vctrs" + ], + "Hash": "9171f898db9d9c4c1b2c745adc2c1ef1" + }, "here": { "Package": "here", "Version": "1.0.1", @@ -588,7 +1028,21 @@ "R", "xfun" ], - "Hash": "d65ba49117ca223614f71b60d85b8ab7" + "Hash": "d65ba49117ca223614f71b60d85b8ab7" + }, + "hms": { + "Package": "hms", + "Version": "1.1.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "lifecycle", + "methods", + "pkgconfig", + "rlang", + "vctrs" + ], + "Hash": "b59377caa7ed00fa41808342002138f9" }, "htmltools": { "Package": "htmltools", @@ -636,6 +1090,21 @@ ], "Hash": "d55aa087c47a63ead0f6fc10f8fa1ee0" }, + "httr": { + "Package": "httr", + "Version": "1.4.7", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "curl", + "jsonlite", + "mime", + "openssl" + ], + "Hash": "ac107251d9d9fd72f0ca8049988f1d7f" + }, "httr2": { "Package": "httr2", "Version": "1.0.2", @@ -669,6 +1138,17 @@ ], "Hash": "e957e989ea17f937964f0d46b0f0bca0" }, + "ids": { + "Package": "ids", + "Version": "1.0.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "openssl", + "uuid" + ], + "Hash": "99df65cfef20e525ed38c3d2577f7190" + }, "ini": { "Package": "ini", "Version": "0.3.1", @@ -783,6 +1263,40 @@ ], "Hash": "b8552d117e1b808b09a832f589b79035" }, + "lintr": { + "Package": "lintr", + "Version": "3.1.2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "backports", + "codetools", + "cyclocomp", + "digest", + "glue", + "knitr", + "rex", + "stats", + "utils", + "xml2", + "xmlparsedata" + ], + "Hash": "08cff46381a242d44c0d8dd0aabd9f71" + }, + "lubridate": { + "Package": "lubridate", + "Version": "1.9.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "generics", + "methods", + "timechange" + ], + "Hash": "680ad542fbcf801442c83a6ac5a2126c" + }, "magrittr": { "Package": "magrittr", "Version": "2.0.3", @@ -843,6 +1357,24 @@ ], "Hash": "fec5f52652d60615fdb3957b3d74324a" }, + "modelr": { + "Package": "modelr", + "Version": "0.1.11", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "broom", + "magrittr", + "purrr", + "rlang", + "tibble", + "tidyr", + "tidyselect", + "vctrs" + ], + "Hash": "4f50122dc256b1b6996a4703fecea821" + }, "munsell": { "Package": "munsell", "Version": "0.5.1", @@ -868,6 +1400,25 @@ ], "Hash": "2769a88be217841b1f33ed469675c3cc" }, + "omopgenerics": { + "Package": "omopgenerics", + "Version": "0.2.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "dbplyr", + "dplyr", + "glue", + "methods", + "rlang", + "snakecase", + "stringr", + "tidyr" + ], + "Hash": "455369900c393d3eb843fcbd056e1a9c" + }, "openssl": { "Package": "openssl", "Version": "2.2.0", @@ -1017,6 +1568,20 @@ ], "Hash": "aa5a3864397ce6ae03458f98618395a1" }, + "progress": { + "Package": "progress", + "Version": "1.2.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "crayon", + "hms", + "prettyunits" + ], + "Hash": "f4625e061cb2865f111b47ff163a5ca6" + }, "promises": { "Package": "promises", "Version": "1.3.0", @@ -1102,6 +1667,51 @@ ], "Hash": "8f25ebe2ec38b1f2aef3b0d2ef76f6c4" }, + "readr": { + "Package": "readr", + "Version": "2.1.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "cli", + "clipr", + "cpp11", + "crayon", + "hms", + "lifecycle", + "methods", + "rlang", + "tibble", + "tzdb", + "utils", + "vroom" + ], + "Hash": "9de96463d2117f6ac49980577939dfb3" + }, + "readxl": { + "Package": "readxl", + "Version": "1.4.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cellranger", + "cpp11", + "progress", + "tibble", + "utils" + ], + "Hash": "8cf9c239b96df1bbb133b74aef77ad0a" + }, + "rematch": { + "Package": "rematch", + "Version": "2.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Hash": "cbff1b666c6fa6d21202f07e2318d4f1" + }, "rematch2": { "Package": "rematch2", "Version": "2.1.2", @@ -1136,6 +1746,38 @@ ], "Hash": "397b7b2a265bc5a7a06852524dabae20" }, + "reprex": { + "Package": "reprex", + "Version": "2.1.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "callr", + "cli", + "clipr", + "fs", + "glue", + "knitr", + "lifecycle", + "rlang", + "rmarkdown", + "rstudioapi", + "utils", + "withr" + ], + "Hash": "97b1d5361a24d9fb588db7afe3e5bcbf" + }, + "rex": { + "Package": "rex", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "lazyeval" + ], + "Hash": "ae34cd56890607370665bee5bd17812f" + }, "rlang": { "Package": "rlang", "Version": "1.1.4", @@ -1225,6 +1867,25 @@ ], "Hash": "a9881dfed103e83f9de151dc17002cd1" }, + "rvest": { + "Package": "rvest", + "Version": "1.0.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "httr", + "lifecycle", + "magrittr", + "rlang", + "selectr", + "tibble", + "xml2" + ], + "Hash": "0bcf0c6f274e90ea314b812a6d19a519" + }, "sass": { "Package": "sass", "Version": "0.4.9", @@ -1259,6 +1920,19 @@ ], "Hash": "c19df082ba346b0ffa6f833e92de34d1" }, + "selectr": { + "Package": "selectr", + "Version": "0.4-2", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R6", + "methods", + "stringr" + ], + "Hash": "3838071b66e0c566d55cc26bd6e27bf4" + }, "sessioninfo": { "Package": "sessioninfo", "Version": "1.2.2", @@ -1305,6 +1979,18 @@ ], "Hash": "6a293995a66e12c48d13aa1f957d09c7" }, + "snakecase": { + "Package": "snakecase", + "Version": "0.11.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "stringi", + "stringr" + ], + "Hash": "58767e44739b76965332e8a4fe3f91f1" + }, "sourcetools": { "Package": "sourcetools", "Version": "0.1.7-1", @@ -1358,6 +2044,25 @@ ], "Hash": "960e2ae9e09656611e0b8214ad543207" }, + "styler": { + "Package": "styler", + "Version": "1.10.3", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "R.cache", + "cli", + "magrittr", + "purrr", + "rlang", + "rprojroot", + "tools", + "vctrs", + "withr" + ], + "Hash": "93a2b1beac2437bdcc4724f8bf867e2c" + }, "sys": { "Package": "sys", "Version": "3.4.2", @@ -1438,6 +2143,96 @@ ], "Hash": "a84e2cc86d07289b3b6f5069df7a004c" }, + "tidyr": { + "Package": "tidyr", + "Version": "1.3.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "cpp11", + "dplyr", + "glue", + "lifecycle", + "magrittr", + "purrr", + "rlang", + "stringr", + "tibble", + "tidyselect", + "utils", + "vctrs" + ], + "Hash": "915fb7ce036c22a6a33b5a8adb712eb1" + }, + "tidyselect": { + "Package": "tidyselect", + "Version": "1.2.1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "rlang", + "vctrs", + "withr" + ], + "Hash": "829f27b9c4919c16b593794a6344d6c0" + }, + "tidyverse": { + "Package": "tidyverse", + "Version": "2.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "broom", + "cli", + "conflicted", + "dbplyr", + "dplyr", + "dtplyr", + "forcats", + "ggplot2", + "googledrive", + "googlesheets4", + "haven", + "hms", + "httr", + "jsonlite", + "lubridate", + "magrittr", + "modelr", + "pillar", + "purrr", + "ragg", + "readr", + "readxl", + "reprex", + "rlang", + "rstudioapi", + "rvest", + "stringr", + "tibble", + "tidyr", + "xml2" + ], + "Hash": "c328568cd14ea89a83bd4ca7f54ae07e" + }, + "timechange": { + "Package": "timechange", + "Version": "0.3.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cpp11" + ], + "Hash": "c5f3c201b931cd6474d17d8700ccb1c8" + }, "tinytex": { "Package": "tinytex", "Version": "0.52", @@ -1448,6 +2243,17 @@ ], "Hash": "cfbad971a71f0e27cec22e544a08bc3b" }, + "tzdb": { + "Package": "tzdb", + "Version": "0.4.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cpp11" + ], + "Hash": "f561504ec2897f4d46f0c7657e488ae1" + }, "urlchecker": { "Package": "urlchecker", "Version": "1.0.1", @@ -1503,6 +2309,16 @@ ], "Hash": "62b65c52671e6665f803ff02954446e9" }, + "uuid": { + "Package": "uuid", + "Version": "1.2-1", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "34e965e62a41fcafb1ca60e9b142085b" + }, "vctrs": { "Package": "vctrs", "Version": "0.6.5", @@ -1527,6 +2343,32 @@ ], "Hash": "c826c7c4241b6fc89ff55aaea3fa7491" }, + "vroom": { + "Package": "vroom", + "Version": "1.6.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "bit64", + "cli", + "cpp11", + "crayon", + "glue", + "hms", + "lifecycle", + "methods", + "progress", + "rlang", + "stats", + "tibble", + "tidyselect", + "tzdb", + "vctrs", + "withr" + ], + "Hash": "390f9315bc0025be03012054103d227c" + }, "waldo": { "Package": "waldo", "Version": "0.5.2", @@ -1589,6 +2431,16 @@ ], "Hash": "1d0336142f4cd25d8d23cd3ba7a8fb61" }, + "xmlparsedata": { + "Package": "xmlparsedata", + "Version": "1.0.5", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R" + ], + "Hash": "45e4bf3c46476896e821fc0a408fb4fc" + }, "xopen": { "Package": "xopen", "Version": "1.0.1",