diff --git a/.Rbuildignore b/.Rbuildignore index e67bba013..9db0d4473 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,3 +1,5 @@ +^renv$ +^renv\.lock$ extras man-roxygen license_header_stub.txt @@ -21,4 +23,7 @@ docs compare_versions _pkgdown.yml examplePhenotypeLibraryPackage -examplePackage \ No newline at end of file +examplePackage +.github +deploy.sh +compare_versions diff --git a/.github/workflows/R_CMD_check_Hades.yml b/.github/workflows/R_CMD_check_Hades.yml new file mode 100644 index 000000000..152753904 --- /dev/null +++ b/.github/workflows/R_CMD_check_Hades.yml @@ -0,0 +1,193 @@ +# For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag. +# https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions +on: + push: + branches: + - '**' + pull_request: + branches: + - '**' + +name: R-CMD-check + +jobs: + R-CMD-check: + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + + strategy: + fail-fast: false + matrix: + config: + - {os: windows-latest, r: 'release'} # Does not appear to have Java 32-bit, hence the --no-multiarch + - {os: macOS-latest, r: 'release'} + - {os: ubuntu-20.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"} + - {os: ubuntu-20.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"} + + env: + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + RSPM: ${{ matrix.config.rspm }} + CDM5_ORACLE_CDM_SCHEMA: ${{ secrets.CDM5_ORACLE_CDM_SCHEMA }} + CDM5_ORACLE_OHDSI_SCHEMA: ${{ secrets.CDM5_ORACLE_OHDSI_SCHEMA }} + CDM5_ORACLE_PASSWORD: ${{ secrets.CDM5_ORACLE_PASSWORD }} + CDM5_ORACLE_SERVER: ${{ secrets.CDM5_ORACLE_SERVER }} + CDM5_ORACLE_USER: ${{ secrets.CDM5_ORACLE_USER }} + CDM5_POSTGRESQL_CDM_SCHEMA: ${{ secrets.CDM5_POSTGRESQL_CDM_SCHEMA }} + CDM5_POSTGRESQL_OHDSI_SCHEMA: ${{ secrets.CDM5_POSTGRESQL_OHDSI_SCHEMA }} + CDM5_POSTGRESQL_PASSWORD: ${{ secrets.CDM5_POSTGRESQL_PASSWORD }} + CDM5_POSTGRESQL_SERVER: ${{ secrets.CDM5_POSTGRESQL_SERVER }} + CDM5_POSTGRESQL_USER: ${{ secrets.CDM5_POSTGRESQL_USER }} + CDM5_SQL_SERVER_CDM_SCHEMA: ${{ secrets.CDM5_SQL_SERVER_CDM_SCHEMA }} + CDM5_SQL_SERVER_OHDSI_SCHEMA: ${{ secrets.CDM5_SQL_SERVER_OHDSI_SCHEMA }} + CDM5_SQL_SERVER_PASSWORD: ${{ secrets.CDM5_SQL_SERVER_PASSWORD }} + CDM5_SQL_SERVER_SERVER: ${{ secrets.CDM5_SQL_SERVER_SERVER }} + CDM5_SQL_SERVER_USER: ${{ secrets.CDM5_SQL_SERVER_USER }} + CDM5_POSTGRESQL_COHORT_DIAGNOSTICS_SCHEMA: 'cohort_diagnostics' + + steps: + - uses: actions/checkout@v2 + + - uses: r-lib/actions/setup-r@v1 + with: + r-version: ${{ matrix.config.r }} + + - uses: r-lib/actions/setup-tinytex@v1 + + - uses: r-lib/actions/setup-pandoc@v1 + + - name: Query dependencies + run: | + install.packages('remotes') + saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) + writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") + shell: Rscript {0} + + - name: Cache R packages + if: runner.os != 'Windows' + uses: actions/cache@v2 + with: + path: ${{ env.R_LIBS_USER }} + key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- + + - name: Install system dependencies + if: runner.os == 'Linux' + run: | + while read -r cmd + do + eval sudo $cmd + done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))') + + - name: Install libssh + if: runner.os == 'Linux' + run: | + sudo apt-get install libssh-dev + - name: Install dependencies + run: | + remotes::install_deps(dependencies = TRUE, INSTALL_opts=c("--no-multiarch")) + remotes::install_cran("rcmdcheck") + shell: Rscript {0} + + - name: Install covr + if: runner.os == 'macOS' + run: | + remotes::install_cran("covr") + shell: Rscript {0} + + - name: Remove check folder if exists + if: runner.os == 'macOS' + run: unlink("check", recursive = TRUE) + shell: Rscript {0} + + - name: Check + env: + _R_CHECK_CRAN_INCOMING_REMOTE_: false + run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--no-multiarch"), error_on = "warning", check_dir = "check") + shell: Rscript {0} + + - name: Upload check results + if: failure() + uses: actions/upload-artifact@v2 + with: + name: ${{ runner.os }}-r${{ matrix.config.r }}-results + path: check + + - name: Upload source package + if: success() && runner.os == 'macOS' && github.event_name != 'pull_request' && github.ref == 'refs/heads/master' + uses: actions/upload-artifact@v2 + with: + name: package_tarball + path: check/*.tar.gz + + - name: Test coverage + if: runner.os == 'macOS' + run: covr::codecov() + shell: Rscript {0} + + Release: + needs: R-CMD-Check + + runs-on: macOS-latest + + env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} + + if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/master' }} + + steps: + + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Check if version has increased + run: | + echo "new_version="$(perl compare_versions --tag) >> $GITHUB_ENV + + - name: Display new version number + if: ${{ env.new_version != '' }} + run: | + echo "${{ env.new_version }}" + + - name: Create release + if: ${{ env.new_version != '' }} + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + with: + tag_name: ${{ env.new_version }} + release_name: Release ${{ env.new_version }} + body: | + See NEWS.md for release notes. + draft: false + prerelease: false + + - uses: r-lib/actions/setup-r@v1 + if: ${{ env.new_version != '' }} + + - name: Install drat + if: ${{ env.new_version != '' }} + run: | + install.packages('drat') + shell: Rscript {0} + + - name: Remove any tarballs that already exists + if: ${{ env.new_version != '' }} + run: | + rm -f *.tar.gz + + - name: Download package tarball + if: ${{ env.new_version != '' }} + uses: actions/download-artifact@v2 + with: + name: package_tarball + + - name: Push to drat + if: ${{ env.new_version != '' }} + run: | + bash deploy.sh + - name: Push to BroadSea + if: ${{ env.new_version != '' }} + run: | + curl --data "build=true" -X POST https://registry.hub.docker.com/u/ohdsi/broadsea-methodslibrary/trigger/f0b51cec-4027-4781-9383-4b38b42dd4f5/ \ No newline at end of file diff --git a/.github/workflows/nightly_cleanup_Hades.yml b/.github/workflows/nightly_cleanup_Hades.yml new file mode 100644 index 000000000..f1ecd1acf --- /dev/null +++ b/.github/workflows/nightly_cleanup_Hades.yml @@ -0,0 +1,18 @@ +name: 'nightly artifacts cleanup' +on: + schedule: + - cron: '0 1 * * *' # every night at 1 am UTC + +jobs: + remove-old-artifacts: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Remove old artifacts + uses: c-hive/gha-remove-artifacts@v1 + with: + age: '7 days' + # Optional inputs + # skip-tags: true + skip-recent: 1 \ No newline at end of file diff --git a/.gitignore b/.gitignore index f51de251e..baeb0effe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,12 @@ .Rhistory .RData .Ruserdata -*.RData -inst/shiny/DiagnosticsExplorer/data/phenotypeDescription.csv -inst/shiny/DiagnosticsExplorer/data/cohortDescription.csv *.zip errorReportSql.txt errorReportR.txt *.tex .DS_Store +*.history +.RDataTmp +*.log +*log.txt diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index bd01e4cfd..000000000 --- a/.travis.yml +++ /dev/null @@ -1,30 +0,0 @@ -language: R -cache: packages - -branches: - except: - - /^*-v[0-9]/ - -before_install: - - sudo $(which R) CMD javareconf - -r_packages: - - covr - - drat - - devtools - -before_script: - - export PKG_NAME=$(Rscript -e 'cat(paste0(devtools::as.package(".")$package))') - - export PKG_TARBALL=$(Rscript -e 'pkg <- devtools::as.package("."); cat(paste0(pkg$package,"_",pkg$version,".tar.gz"))') - -notifications: - recipients: - - gowthamrao@gmail.com - - schuemie@ohdsi.org - email: - on_success: change - on_failure: change - -after_success: - - Rscript -e 'covr::codecov()' - - test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && perl compare_versions --tag && bash deploy.sh && curl --data "build=true" -X POST https://registry.hub.docker.com/u/ohdsi/broadsea-methodslibrary/trigger/f0b51cec-4027-4781-9383-4b38b42dd4f5/ diff --git a/CohortDiagnostics.Rproj b/CohortDiagnostics.Rproj index eaa6b8186..5a4617f30 100644 --- a/CohortDiagnostics.Rproj +++ b/CohortDiagnostics.Rproj @@ -13,6 +13,5 @@ RnwWeave: Sweave LaTeX: pdfLaTeX BuildType: Package -PackageUseDevtools: Yes PackageInstallArgs: --no-multiarch --with-keep.source PackageRoxygenize: rd,collate,namespace diff --git a/DESCRIPTION b/DESCRIPTION index 0c8b615d0..9e360b754 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,57 +1,64 @@ Package: CohortDiagnostics Type: Package Title: Diagnostics for OHDSI Cohorts -Version: 2.0.0 -Date: 2020-10-07 +Version: 2.1.0 +Date: 2021-05-24 Authors@R: c( - person("Gowtham", "Rao", email = "gowthamrao@gmail.com", role = c("aut", "cre")), + person("Gowtham", "Rao", email = "rao@ohdsi.org", role = c("aut", "cre")), person("Martijn", "Schuemie", email = "schuemie@ohdsi.org", role = c("aut")), person("Patrick", "Ryan", role = c("aut")), person("James", "Weaver", role = c("aut")), + person("Jamie", "Gilbert", role = c("aut")), person("Observational Health Data Science and Informatics", role = c("cph")) ) -Maintainer: Gowtham Rao +Maintainer: Gowtham Rao Description: Diagnostics for cohorts that use the OMOP Common Data Model and the OHDSI tools. Depends: - DatabaseConnector (>= 3.0.0), - FeatureExtraction (>= 3.1.0), - R (>= 3.5.0) + DatabaseConnector (>= 4.0.0), + FeatureExtraction (>= 3.1.1), + R (>= 4.0.0) Imports: Andromeda, checkmate, + CirceR, + clock, digest, dplyr (>= 1.0.0), - ggplot2, - ggiraph, + methods, ParallelLogger (>= 2.0.0), + pool, readr (>= 1.4.0), - rlang, RJSONIO, - ROhdsiWebApi (>= 1.1.2), - SqlRender (>= 1.6.7), + rlang, + ROhdsiWebApi (>= 1.2.0), + SqlRender (>= 1.7.0), stringr, - tidyr (>= 1.0.0), - methods + tidyr (>= 1.0.0) Suggests: - shiny, - shinydashboard, - shinyWidgets, DT, - plotly, + Eunomia, + ggiraph, + ggplot2, htmltools, - RColorBrewer, - scales, knitr, + lubridate, + plotly, + purrr, + RColorBrewer, rmarkdown, - Eunomia, - testthat, RSQLite (>= 2.2.1), + scales, + shiny, + shinydashboard, + shinyWidgets, + testthat, + withr, zip Remotes: ohdsi/Eunomia, ohdsi/FeatureExtraction, ohdsi/ROhdsiWebApi, - ohdsi/DatabaseConnector, + ohdsi/CirceR License: Apache License VignetteBuilder: knitr URL: https://ohdsi.github.io/CohortDiagnostics, https://github.com/OHDSI/CohortDiagnostics diff --git a/NAMESPACE b/NAMESPACE index 31a3632aa..14afcf2f7 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,11 +1,8 @@ # Generated by roxygen2: do not edit by hand -export(checkInputFileEncoding) -export(createCohortTable) export(createResultsDataModel) export(getCohortCounts) export(getResultsDataModelSpecifications) -export(instantiateCohort) export(instantiateCohortSet) export(launchCohortExplorer) export(launchDiagnosticsExplorer) @@ -22,5 +19,7 @@ importFrom(rlang,.data) importFrom(stats,aggregate) importFrom(utils,install.packages) importFrom(utils,menu) +importFrom(utils,setTxtProgressBar) +importFrom(utils,txtProgressBar) importFrom(utils,unzip) importFrom(utils,write.csv) diff --git a/NEWS.md b/NEWS.md index 749604565..72307f860 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,36 @@ +CohortDiagnostics 2.1.0 +======================= + +Changes: + +1. Diagnostics explorer Shiny app enhancements: +- Improved tool tip +- Various improvements to plots for consistent color, axis labels and labels +- Visit context table addition +- Diagnostic explorer is now a distinct shiny application from phenotype library. PhenotypeExplorer is a stand alone shiny app in package PhenotypeLibrarian. +- Lot of UX changes. Reactivity deferred on drop down menus. +- Changes to improve app stability. +2. Index event breakdown now has subject count +3. Index event breakdown calculates _source_concept_id from source fields in CDM tables. +4. Vocabulary database schema is now supported. +5. Metadata (vocabulary version information from data source) is now collected. +6. OracleTempSchema use deprecated in favor of tempEmulationSchema. +7. Run against external concept count has been removed, as concept counts data is not available. Function 'runCohortDiagnosticsUsingExternalCounts' is removed. +8. Removed code related to referentConceptId = phenotypeId/1000 as it does not always hold true. +9. Create cohort table function is now private. Please use instantiate cohort. +10. checkInputFileEncoding is not exported as a public function (as not the scope of CohortDiagnostics). +11. Updated results data model to include new tables (resolved_concepts). +12. Cohort Diagnostics results data model now compliant with standard characterization output. +13. Support for cohort_censor_stats table in webapi 2.8.1 #387 +14. Add time series diagnostics computation. Output is not in Diagnostics explorer in this version. +15. Any improvements to help with usability and stability. Informative messages to help with debugbing as needed. +16. phenotypeDescription is no longer supported as input for cohort diagnostics. +Bug fixes: + +1. databaseName and databaseDescription should be non NULL +2. Fixed computation of standard deviation and standard difference of mean for binary covariates. + + CohortDiagnostics 2.0.0 ======================= @@ -56,6 +89,7 @@ Bug fixes: 2. Removed ohdsi/SqlRender from Remotes https://github.com/OHDSI/CohortDiagnostics/issues/189 3. Fixed Digit precision for RJSONIO::toJson and fromJSON https://github.com/OHDSI/CohortDiagnostics/issues/161 This is an important fix. If digit precision is not explicitly specified in RJSONIO, then scientific notation is used. This issue seems to only happen when an integer id (conceptId, conceptSetId, cohortId etc) >= 10,000,000 (which is rare). Please use this update if you have id's > 10,000,000. + CohortDiagnostics 1.2.2 ======================= New features: @@ -152,7 +186,7 @@ Bugfixes: 2. Fixed error in index event breakdown when entry event contained multiple criteria for the same domain. -3. Fixed error related to oracleTempSchema argument (needed on Oracle and BigQuery). +3. Fixed error related to tempEmulationSchema argument (needed on Oracle and BigQuery). 4. Fixed use of deprecated function, causing warnings and causing older versions of ParallelLogger to error. @@ -208,4 +242,4 @@ Bugfixes: CohortDiagnostics 0.0.1 ======================= -Initial version \ No newline at end of file +Initial version diff --git a/R/CohortCharacterizationDiagnostics.R b/R/CohortCharacterizationDiagnostics.R index d2193d623..f90af5de3 100644 --- a/R/CohortCharacterizationDiagnostics.R +++ b/R/CohortCharacterizationDiagnostics.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,7 +17,7 @@ getCohortCharacteristics <- function(connectionDetails = NULL, connection = NULL, cdmDatabaseSchema, - oracleTempSchema = NULL, + tempEmulationSchema = NULL, cohortDatabaseSchema = cdmDatabaseSchema, cohortTable = "cohort", cohortIds, @@ -33,85 +33,143 @@ getCohortCharacteristics <- function(connectionDetails = NULL, for (start in seq(1, length(cohortIds), by = batchSize)) { end <- min(start + batchSize - 1, length(cohortIds)) if (length(cohortIds) > batchSize) { - ParallelLogger::logInfo(sprintf("Batch characterization. Processing cohorts %s through %s", - start, - end)) + ParallelLogger::logInfo(sprintf( + "Batch characterization. Processing cohorts %s through %s", + start, + end + )) } - featureExtractionOutput <- FeatureExtraction::getDbCovariateData(connection = connection, - oracleTempSchema = oracleTempSchema, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cdmVersion = cdmVersion, - cohortTable = cohortTable, - cohortId = cohortIds[start:end], - covariateSettings = covariateSettings, - aggregated = TRUE) + featureExtractionOutput <- + FeatureExtraction::getDbCovariateData( + connection = connection, + oracleTempSchema = tempEmulationSchema, + cdmDatabaseSchema = cdmDatabaseSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cdmVersion = cdmVersion, + cohortTable = cohortTable, + cohortId = cohortIds[start:end], + covariateSettings = covariateSettings, + aggregated = TRUE + ) - populationSize <- attr(x = featureExtractionOutput, which = "metaData")$populationSize - populationSize <- dplyr::tibble(cohortId = names(populationSize), - populationSize = populationSize) + populationSize <- + attr(x = featureExtractionOutput, which = "metaData")$populationSize + populationSize <- + dplyr::tibble( + cohortId = names(populationSize) %>% as.numeric(), + populationSize = populationSize + ) if (!"analysisRef" %in% names(results)) { results$analysisRef <- featureExtractionOutput$analysisRef } if (!"covariateRef" %in% names(results)) { - results$covariateRef <- featureExtractionOutput$covariateRef + results$covariateRef <- featureExtractionOutput$covariateRef } else { covariateIds <- results$covariateRef %>% - dplyr::select(.data$covariateId) - Andromeda::appendToTable(results$covariateRef, featureExtractionOutput$covariateRef %>% - dplyr::anti_join(covariateIds, by = "covariateId", copy = TRUE)) + dplyr::select(.data$covariateId) + Andromeda::appendToTable( + results$covariateRef, + featureExtractionOutput$covariateRef %>% + dplyr::anti_join(covariateIds, by = "covariateId", copy = TRUE) + ) } - if ("timeRef" %in% names(featureExtractionOutput) && !"timeRef" %in% names(results)) { + if ("timeRef" %in% names(featureExtractionOutput) && + !"timeRef" %in% names(results)) { results$timeRef <- featureExtractionOutput$timeRef } - if ("covariates" %in% names(featureExtractionOutput) && + if ("covariates" %in% names(featureExtractionOutput) && dplyr::pull(dplyr::count(featureExtractionOutput$covariates)) > 0) { + covariates <- featureExtractionOutput$covariates %>% + dplyr::rename(cohortId = .data$cohortDefinitionId) %>% + dplyr::left_join(populationSize, by = "cohortId", copy = TRUE) %>% + dplyr::mutate(p = .data$sumValue / .data$populationSize) - covariates <- featureExtractionOutput$covariates %>% - dplyr::rename(cohortId = .data$cohortDefinitionId) %>% - dplyr::left_join(populationSize, by = "cohortId", copy = TRUE) %>% - dplyr::mutate(sd = sqrt(((populationSize * .data$sumValue) + .data$sumValue)/(populationSize^2))) %>% - dplyr::rename(mean = .data$averageValue) %>% - dplyr::select(-.data$sumValue, -.data$populationSize) + if (nrow(covariates %>% + dplyr::filter(.data$p > 1) %>% + dplyr::collect()) > 0) { + stop( + paste0( + "During characterization, population size (denominator) was found to be smaller than features Value (numerator).", + "- this may have happened because of an error in Feature generation process. Please contact the package developer." + ) + ) + } + + covariates <- covariates %>% + dplyr::mutate(sd = sqrt(.data$p * (1 - .data$p))) %>% + dplyr::select(-.data$p) %>% + dplyr::rename(mean = .data$averageValue) %>% + dplyr::select(-.data$populationSize) if (FeatureExtraction::isTemporalCovariateData(featureExtractionOutput)) { - covariates <- covariates %>% - dplyr::select(.data$cohortId, .data$timeId, .data$covariateId, .data$mean, .data$sd) + covariates <- covariates %>% + dplyr::select(.data$cohortId, + .data$timeId, + .data$covariateId, + .data$sumValue, + .data$mean, + .data$sd) } else { - covariates <- covariates %>% - dplyr::select(.data$cohortId, .data$covariateId, .data$mean, .data$sd) + covariates <- covariates %>% + dplyr::select(.data$cohortId, + .data$covariateId, + .data$sumValue, + .data$mean, + .data$sd) } if ("covariates" %in% names(results)) { - Andromeda::appendToTable(results$covariates, covariates) + Andromeda::appendToTable(results$covariates, covariates) } else { results$covariates <- covariates } } - if ("covariatesContinuous" %in% names(featureExtractionOutput) && + if ("covariatesContinuous" %in% names(featureExtractionOutput) && dplyr::pull(dplyr::count(featureExtractionOutput$covariatesContinuous)) > 0) { - covariates <- featureExtractionOutput$covariatesContinuous %>% - dplyr::rename(mean = .data$averageValue, - sd = .data$standardDeviation, - cohortId = .data$cohortDefinitionId) + covariates <- featureExtractionOutput$covariatesContinuous %>% + dplyr::rename( + mean = .data$averageValue, + sd = .data$standardDeviation, + cohortId = .data$cohortDefinitionId + ) + covariatesContinuous <- covariates if (FeatureExtraction::isTemporalCovariateData(featureExtractionOutput)) { - covariates <- covariates %>% - dplyr::select(.data$cohortId, .data$timeId, .data$covariateId, .data$mean, .data$sd) + covariates <- covariates %>% + dplyr::mutate(sumValue = -1) %>% + dplyr::select(.data$cohortId, + .data$timeId, + .data$covariateId, + .data$sum, + .data$mean, + .data$sd) } else { - covariates <- covariates %>% - dplyr::select(.data$cohortId, .data$covariateId, .data$mean, .data$sd) + covariates <- covariates %>% + dplyr::mutate(sumValue = -1) %>% + dplyr::select(.data$cohortId, + .data$covariateId, + .data$sumValue, + .data$mean, + .data$sd) } if ("covariates" %in% names(results)) { - Andromeda::appendToTable(results$covariates, covariates) + Andromeda::appendToTable(results$covariates, covariates) } else { results$covariates <- covariates } + if ("covariatesContinuous" %in% names(results)) { + Andromeda::appendToTable(results$covariatesContinuous, covariatesContinuous) + } else { + results$covariatesContinuous <- covariatesContinuous + } } } delta <- Sys.time() - startTime - ParallelLogger::logInfo("Cohort characterization took ", signif(delta, 3), " ", attr(delta, "units")) + ParallelLogger::logInfo("Cohort characterization took ", + signif(delta, 3), + " ", + attr(delta, "units")) return(results) } diff --git a/R/CohortComparisonDiagnostics.R b/R/CohortComparisonDiagnostics.R index fb7e1809d..e687b437e 100644 --- a/R/CohortComparisonDiagnostics.R +++ b/R/CohortComparisonDiagnostics.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,42 +27,66 @@ computeCohortOverlap <- function(connectionDetails = NULL, on.exit(DatabaseConnector::disconnect(connection)) } - if (!checkIfCohortInstantiated(connection = connection, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortId = targetCohortId)) { - warning("- Target cohort with ID ", - targetCohortId, - " appears to be empty. Was it instantiated? Skipping overlap computation.") + if (!checkIfCohortInstantiated( + connection = connection, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cohortId = targetCohortId + )) { + warning( + "- Target cohort with ID ", + targetCohortId, + " appears to be empty. Was it instantiated? Skipping overlap computation." + ) delta <- Sys.time() - start - ParallelLogger::logInfo(paste("Computing overlap took", signif(delta, 3), attr(delta, "units"))) + ParallelLogger::logInfo(paste( + "Computing overlap took", + signif(delta, 3), + attr(delta, "units") + )) return(tidyr::tibble()) } - if (!checkIfCohortInstantiated(connection = connection, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortId = comparatorCohortId)) { - warning("- Comparator cohort with ID ", - comparatorCohortId, - " appears to be empty. Was it instantiated? Skipping overlap computation.") + if (!checkIfCohortInstantiated( + connection = connection, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cohortId = comparatorCohortId + )) { + warning( + "- Comparator cohort with ID ", + comparatorCohortId, + " appears to be empty. Was it instantiated? Skipping overlap computation." + ) delta <- Sys.time() - start - ParallelLogger::logInfo(paste("Computing overlap took", signif(delta, 3), attr(delta, "units"))) + ParallelLogger::logInfo(paste( + "Computing overlap took", + signif(delta, 3), + attr(delta, "units") + )) return(tidyr::tibble()) } - sql <- SqlRender::loadRenderTranslateSql("CohortOverlap.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - cohort_database_schema = cohortDatabaseSchema, - cohort_table = cohortTable, - target_cohort_id = targetCohortId, - comparator_cohort_id = comparatorCohortId) - overlap <- DatabaseConnector::querySql(connection = connection, - sql = sql, - snakeCaseToCamelCase = TRUE) %>% + sql <- SqlRender::loadRenderTranslateSql( + "CohortOverlap.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + cohort_database_schema = cohortDatabaseSchema, + cohort_table = cohortTable, + target_cohort_id = targetCohortId, + comparator_cohort_id = comparatorCohortId + ) + overlap <- DatabaseConnector::querySql( + connection = connection, + sql = sql, + snakeCaseToCamelCase = TRUE + ) %>% tidyr::tibble() delta <- Sys.time() - start - ParallelLogger::logInfo(paste("Computing overlap took", signif(delta, 3), attr(delta, "units"))) + ParallelLogger::logInfo(paste( + "Computing overlap took", + signif(delta, 3), + attr(delta, "units") + )) return(overlap) } diff --git a/R/CohortConstruction.R b/R/CohortConstruction.R index 4475cc5fb..a6016a248 100644 --- a/R/CohortConstruction.R +++ b/R/CohortConstruction.R @@ -1,131 +1,183 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -checkCohortReference <- function(cohortReference, errorMessage = NULL) { - if (is.null(errorMessage) | !class(errorMessage) == 'AssertColection') { - errorMessage <- checkmate::makeAssertCollection() +checkCohortReference <- + function(cohortReference, errorMessage = NULL) { + if (is.null(errorMessage) | + !class(errorMessage) == 'AssertColection') { + errorMessage <- checkmate::makeAssertCollection() + } + checkmate::assertDataFrame( + x = cohortReference, + types = c("integer", "character", "numeric"), + min.rows = 1, + min.cols = 4, + null.ok = FALSE, + col.names = "named", + add = errorMessage + ) + if ("referentConceptId" %in% names(cohortReference)) { + checkmate::assertIntegerish( + x = cohortReference$referentConceptId, + lower = 0, + any.missing = FALSE, + unique = FALSE, + null.ok = FALSE, + add = errorMessage + ) + } + checkmate::assertNames( + x = names(cohortReference), + subset.of = c( + "referentConceptId", + "cohortId", + "webApiCohortId", + "cohortName", + "logicDescription", + "clinicalRationale" + ), + add = errorMessage + ) + invisible(errorMessage) } - checkmate::assertDataFrame(x = cohortReference, - types = c("integer", "character","numeric"), - min.rows = 1, - min.cols = 4, - null.ok = FALSE, - col.names = "named", - add = errorMessage) - if ("referentConceptId" %in% names(cohortReference)) { - checkmate::assertIntegerish(x = cohortReference$referentConceptId, - lower = 0, - any.missing = FALSE, - unique = FALSE, - null.ok = FALSE, - add = errorMessage) - } - checkmate::assertNames(x = names(cohortReference),subset.of = c("referentConceptId","cohortId", - "webApiCohortId","cohortName", - "logicDescription","clinicalRationale" ), - add = errorMessage) - invisible(errorMessage) -} makeBackwardsCompatible <- function(cohorts) { if (!"name" %in% colnames(cohorts)) { - cohorts <- cohorts %>% - mutate(name = .data$cohortId) + if ('cohortId' %in% colnames(cohorts)) { + cohorts <- cohorts %>% + dplyr::mutate(name = as.character(.data$cohortId)) + } else if ('id' %in% colnames(cohorts)) { + cohorts <- cohorts %>% + dplyr::mutate(name = as.character(.data$id)) %>% + dplyr::mutate(cohortId = .data$id) + } } - if (!"webApiCohortId" %in% colnames(cohorts) && "atlasId" %in% colnames(cohorts)) { + if (!"webApiCohortId" %in% colnames(cohorts) && + "atlasId" %in% colnames(cohorts)) { cohorts <- cohorts %>% - rename(webApiCohortId = .data$atlasId) + dplyr::mutate(webApiCohortId = .data$atlasId) } - if (!"cohortName" %in% colnames(cohorts) && "atlasName" %in% colnames(cohorts)) { + if (!"cohortName" %in% colnames(cohorts) && + "atlasName" %in% colnames(cohorts)) { cohorts <- cohorts %>% - rename(cohortName = .data$atlasName) + dplyr::mutate(cohortName = .data$atlasName) } return(cohorts) } -getCohortsJsonAndSqlFromPackage <- function(packageName = packageName, - cohortToCreateFile = cohortToCreateFile, - cohortIds = NULL, - errorMessage = NULL) { - ParallelLogger::logDebug("Executing on cohorts specified in package - ", packageName) - - if (is.null(errorMessage) | !class(errorMessage) == 'AssertColection') { - errorMessage <- checkmate::makeAssertCollection() - } - checkmate::assertCharacter(x = packageName, min.len = 1, max.len = 1, add = errorMessage) - pathToCsv <- system.file(cohortToCreateFile, package = packageName) - checkmate::assertFileExists(x = system.file(cohortToCreateFile, package = packageName), - access = "r", - extension = "csv", - add = errorMessage) - - checkInputFileEncoding(pathToCsv) - - cohorts <- readr::read_csv(pathToCsv, - col_types = readr::cols(), - guess_max = min(1e7)) - - cohorts <- makeBackwardsCompatible(cohorts) - if (!is.null(cohortIds)) { - cohorts <- cohorts %>% - dplyr::filter(.data$cohortId %in% cohortIds) +getCohortsJsonAndSqlFromPackage <- + function(packageName = packageName, + cohortToCreateFile = cohortToCreateFile, + cohortIds = NULL, + errorMessage = NULL) { + ParallelLogger::logDebug("Executing on cohorts specified in package - ", packageName) + + if (is.null(errorMessage) | + !class(errorMessage) == 'AssertColection') { + errorMessage <- checkmate::makeAssertCollection() + } + checkmate::assertCharacter( + x = packageName, + min.len = 1, + max.len = 1, + add = errorMessage + ) + pathToCsv <- + system.file(cohortToCreateFile, package = packageName) + checkmate::assertFileExists( + x = system.file(cohortToCreateFile, package = packageName), + access = "r", + extension = "csv", + add = errorMessage + ) + + checkInputFileEncoding(pathToCsv) + + cohorts <- readr::read_csv(pathToCsv, + col_types = readr::cols(), + guess_max = min(1e7)) + + cohorts <- makeBackwardsCompatible(cohorts) + if (!is.null(cohortIds)) { + cohorts <- cohorts %>% + dplyr::filter(.data$cohortId %in% cohortIds) + } + + checkCohortReference(cohortReference = cohorts, errorMessage = errorMessage) + checkmate::reportAssertions(collection = errorMessage) + + getSql <- function(name) { + pathToSql <- + system.file("sql", "sql_server", paste0(name, ".sql"), package = packageName) + checkmate::assertFile( + x = pathToSql, + access = "r", + extension = ".sql", + add = errorMessage + ) + sql <- readChar(pathToSql, file.info(pathToSql)$size) + return(sql) + } + cohorts$sql <- sapply(cohorts$name, getSql) + getJson <- function(name) { + pathToJson <- + system.file("cohorts", paste0(name, ".json"), package = packageName) + checkmate::assertFile( + x = pathToJson, + access = "r", + extension = ".sql", + add = errorMessage + ) + json <- readChar(pathToJson, file.info(pathToJson)$size) + return(json) + } + cohorts$json <- sapply(cohorts$name, getJson) + return(selectColumnAccordingToResultsModel(cohorts)) } - - checkCohortReference(cohortReference = cohorts, errorMessage = errorMessage) - checkmate::reportAssertions(collection = errorMessage) - - getSql <- function(name) { - pathToSql <- system.file("sql", "sql_server", paste0(name, ".sql"), package = packageName) - checkmate::assertFile(x = pathToSql, access = "r", extension = ".sql", add = errorMessage) - sql <- readChar(pathToSql, file.info(pathToSql)$size) - return(sql) - } - cohorts$sql <- sapply(cohorts$name, getSql) - getJson <- function(name) { - pathToJson <- system.file("cohorts", paste0(name, ".json"), package = packageName) - checkmate::assertFile(x = pathToJson, access = "r", extension = ".sql", add = errorMessage) - json <- readChar(pathToJson, file.info(pathToJson)$size) - return(json) - } - cohorts$json <- sapply(cohorts$name, getJson) - return(selectColumnAccordingToResultsModel(cohorts)) -} getCohortsJsonAndSqlFromWebApi <- function(baseUrl = baseUrl, cohortSetReference = cohortSetReference, cohortIds = NULL, - errorMessage = NULL) { - ParallelLogger::logDebug("Running Cohort Diagnostics on cohort specified in WebApi - ", baseUrl) + errorMessage = NULL, + generateStats = TRUE) { + ParallelLogger::logDebug("Running Cohort Diagnostics on cohort specified in WebApi - ", + baseUrl) - if (is.null(errorMessage) | !class(errorMessage) == 'AssertColection') { + if (is.null(errorMessage) | + !class(errorMessage) == 'AssertColection') { errorMessage <- checkmate::makeAssertCollection() } - checkmate::assertCharacter(x = baseUrl, min.chars = 1, add = errorMessage) + checkmate::assertCharacter(x = baseUrl, + min.chars = 1, + add = errorMessage) webApiVersion <- ROhdsiWebApi::getWebApiVersion(baseUrl) ParallelLogger::logInfo("WebApi of version ", webApiVersion, " found at ", baseUrl) - checkmate::assertCharacter(x = webApiVersion, min.chars = 1, add = errorMessage) + checkmate::assertCharacter(x = webApiVersion, + min.chars = 1, + add = errorMessage) checkmate::reportAssertions(collection = errorMessage) if (!is.null(cohortIds)) { - cohortSetReference <- cohortSetReference %>% + cohortSetReference <- cohortSetReference %>% dplyr::filter(.data$cohortId %in% cohortIds) } if ("name" %in% names(cohortSetReference)) { - cohortSetReference <- dplyr::rename(cohortSetReference, cohortName = "name") + cohortSetReference <- + dplyr::rename(cohortSetReference, cohortName = "name") } cohortSetReference <- makeBackwardsCompatible(cohortSetReference) cohortSetReference$json <- "" @@ -133,13 +185,19 @@ getCohortsJsonAndSqlFromWebApi <- function(baseUrl = baseUrl, ParallelLogger::logInfo("Retrieving cohort definitions from WebAPI") for (i in 1:nrow(cohortSetReference)) { - ParallelLogger::logInfo("- Retrieving definitions for cohort ", cohortSetReference$cohortName[i]) - cohortDefinition <- ROhdsiWebApi::getCohortDefinition(cohortId = cohortSetReference$webApiCohortId[i], - baseUrl = baseUrl) - cohortSetReference$json[i] <- RJSONIO::toJSON(x = cohortDefinition$expression, digits = 23) - cohortSetReference$sql[i] <- ROhdsiWebApi::getCohortSql(cohortDefinition = cohortDefinition, - baseUrl = baseUrl, - generateStats = TRUE) + ParallelLogger::logInfo("- Retrieving definitions for cohort ", + cohortSetReference$cohortName[i]) + cohortDefinition <- + ROhdsiWebApi::getCohortDefinition(cohortId = cohortSetReference$webApiCohortId[i], + baseUrl = baseUrl) + cohortSetReference$json[i] <- + RJSONIO::toJSON(x = cohortDefinition$expression, digits = 23) + cohortSetReference$sql[i] <- + ROhdsiWebApi::getCohortSql( + cohortDefinition = cohortDefinition, + baseUrl = baseUrl, + generateStats = generateStats + ) } return(selectColumnAccordingToResultsModel(cohortSetReference)) } @@ -153,8 +211,14 @@ selectColumnAccordingToResultsModel <- function(data) { if ("logicDescription" %in% colnames(data)) { columsToInclude <- c(columsToInclude, "logicDescription") } - - columsToInclude <- c(columsToInclude, "json" ,"sql", "webApiCohortId") + if ("referentConceptId" %in% colnames(data)) { + columsToInclude <- c(columsToInclude, "referentConceptId") + } + if ("cohortType" %in% colnames(data)) { + columsToInclude <- c(columsToInclude, "cohortType") + } + columsToInclude <- + c(columsToInclude, "json" , "sql", "webApiCohortId") return(data[, columsToInclude]) } @@ -162,247 +226,77 @@ getCohortsJsonAndSql <- function(packageName = NULL, cohortToCreateFile = "settings/CohortsToCreate.csv", baseUrl = NULL, cohortSetReference = NULL, - cohortIds = NULL) { - + cohortIds = NULL, + generateStats = TRUE) { if (!is.null(packageName)) { - cohorts <- getCohortsJsonAndSqlFromPackage(packageName = packageName, - cohortToCreateFile = cohortToCreateFile, - cohortIds = cohortIds) + cohorts <- + getCohortsJsonAndSqlFromPackage( + packageName = packageName, + cohortToCreateFile = cohortToCreateFile, + cohortIds = cohortIds + ) if (!is.null(baseUrl)) { baseUrl <- NULL - ParallelLogger::logInfo("Ignoring parameter baseUrl because packageName is provided. Overiding user parameter baseUrl - setting to NULL") + ParallelLogger::logInfo( + "Ignoring parameter baseUrl because packageName is provided. Overiding user parameter baseUrl - setting to NULL" + ) } if (!is.null(cohortSetReference)) { cohortSetReference <- NULL - ParallelLogger::logInfo("Ignoring parameter cohortSetReference because packageName is provided. Overiding user parameter cohortSetReference - setting to NULL") + ParallelLogger::logInfo( + "Ignoring parameter cohortSetReference because packageName is provided. Overiding user parameter cohortSetReference - setting to NULL" + ) } } else { - cohorts <- getCohortsJsonAndSqlFromWebApi(baseUrl = baseUrl, - cohortSetReference = cohortSetReference, - cohortIds = cohortIds) + cohorts <- getCohortsJsonAndSqlFromWebApi( + baseUrl = baseUrl, + cohortSetReference = cohortSetReference, + cohortIds = cohortIds, + generateStats = generateStats + ) } ParallelLogger::logInfo("Number of cohorts ", nrow(cohorts)) if (nrow(cohorts) == 0) { warning("No cohorts founds") } if (nrow(cohorts) != length(cohorts$cohortId %>% unique())) { - warning("Please check input cohort specification. Is there duplication of cohortId? Returning empty cohort table.") - return(cohorts[0,]) + warning( + "Please check input cohort specification. Is there duplication of cohortId? Returning empty cohort table." + ) + return(cohorts[0, ]) } return(cohorts) } -#' Create cohort table(s) -#' -#' @description -#' This function creates an empty cohort table. Optionally, additional empty tables are created to -#' store statistics on the various inclusion criteria. -#' -#' @template Connection -#' -#' @template CohortTable -#' -#' @param createInclusionStatsTables Create the four additional tables for storing inclusion rule -#' statistics? -#' @param resultsDatabaseSchema Schema name where the statistics tables reside. Note that for -#' SQL Server, this should include both the database and schema -#' name, for example 'scratch.dbo'. -#' @param cohortInclusionTable Name of the inclusion table, one of the tables for storing -#' inclusion rule statistics. -#' @param cohortInclusionResultTable Name of the inclusion result table, one of the tables for -#' storing inclusion rule statistics. -#' @param cohortInclusionStatsTable Name of the inclusion stats table, one of the tables for storing -#' inclusion rule statistics. -#' @param cohortSummaryStatsTable Name of the summary stats table, one of the tables for storing -#' inclusion rule statistics. -#' -#' @export createCohortTable <- function(connectionDetails = NULL, connection = NULL, cohortDatabaseSchema, - cohortTable = "cohort", - createInclusionStatsTables = FALSE, - resultsDatabaseSchema = cohortDatabaseSchema, - cohortInclusionTable = paste0(cohortTable, "_inclusion"), - cohortInclusionResultTable = paste0(cohortTable, "_inclusion_result"), - cohortInclusionStatsTable = paste0(cohortTable, "_inclusion_stats"), - cohortSummaryStatsTable = paste0(cohortTable, "_summary_stats")) { + cohortTable = "cohort") { start <- Sys.time() ParallelLogger::logInfo("Creating cohort table") if (is.null(connection)) { connection <- DatabaseConnector::connect(connectionDetails) on.exit(DatabaseConnector::disconnect(connection)) } - sql <- SqlRender::loadRenderTranslateSql("CreateCohortTable.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - cohort_database_schema = cohortDatabaseSchema, - cohort_table = cohortTable) - DatabaseConnector::executeSql(connection, sql, progressBar = FALSE, reportOverallTime = FALSE) + sql <- SqlRender::loadRenderTranslateSql( + "CreateCohortTable.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + cohort_database_schema = cohortDatabaseSchema, + cohort_table = cohortTable + ) + DatabaseConnector::executeSql(connection, + sql, + progressBar = FALSE, + reportOverallTime = FALSE) ParallelLogger::logDebug("Created table ", cohortDatabaseSchema, ".", cohortTable) - if (createInclusionStatsTables) { - ParallelLogger::logInfo("Creating inclusion rule statistics tables") - sql <- SqlRender::loadRenderTranslateSql("CreateInclusionStatsTables.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - cohort_database_schema = resultsDatabaseSchema, - cohort_inclusion_table = cohortInclusionTable, - cohort_inclusion_result_table = cohortInclusionResultTable, - cohort_inclusion_stats_table = cohortInclusionStatsTable, - cohort_summary_stats_table = cohortSummaryStatsTable) - DatabaseConnector::executeSql(connection, sql, progressBar = FALSE, reportOverallTime = FALSE) - ParallelLogger::logDebug("Created table ", cohortDatabaseSchema, ".", cohortInclusionTable) - ParallelLogger::logDebug("Created table ", - cohortDatabaseSchema, - ".", - cohortInclusionResultTable) - ParallelLogger::logDebug("Created table ", - cohortDatabaseSchema, - ".", - cohortInclusionStatsTable) - ParallelLogger::logDebug("Created table ", cohortDatabaseSchema, ".", cohortSummaryStatsTable) - } delta <- Sys.time() - start - writeLines(paste("Creating cohort table took", signif(delta, 3), attr(delta, "units"))) -} - - -#' Instantiate a cohort -#' -#' @description -#' This function instantiates the cohort in the cohort table. Optionally, the inclusion rule -#' statistics are computed and stored in the inclusion rule statistics tables described in -#' \code{\link{createCohortTable}}). -#' -#' @template Connection -#' -#' @template CohortTable -#' -#' @template CohortDef -#' -#' @template OracleTempSchema -#' -#' @template CdmDatabaseSchema -#' -#' @param cohortId The cohort ID used to reference the cohort in the cohort table. -#' @param generateInclusionStats Compute and store inclusion rule statistics? -#' @param resultsDatabaseSchema Schema name where the statistics tables reside. Note that for -#' SQL Server, this should include both the database and schema -#' name, for example 'scratch.dbo'. -#' @param cohortInclusionTable Name of the inclusion table, one of the tables for storing -#' inclusion rule statistics. -#' @param cohortInclusionResultTable Name of the inclusion result table, one of the tables for -#' storing inclusion rule statistics. -#' @param cohortInclusionStatsTable Name of the inclusion stats table, one of the tables for storing -#' inclusion rule statistics. -#' @param cohortSummaryStatsTable Name of the summary stats table, one of the tables for storing -#' inclusion rule statistics. -#' -#' @export -instantiateCohort <- function(connectionDetails = NULL, - connection = NULL, - cdmDatabaseSchema, - oracleTempSchema = NULL, - cohortDatabaseSchema = cdmDatabaseSchema, - cohortTable = "cohort", - baseUrl = NULL, - cohortJson = NULL, - cohortSql = NULL, - cohortId = NULL, - generateInclusionStats = FALSE, - resultsDatabaseSchema = cohortDatabaseSchema, - cohortInclusionTable = paste0(cohortTable, "_inclusion"), - cohortInclusionResultTable = paste0(cohortTable, "_inclusion_result"), - cohortInclusionStatsTable = paste0(cohortTable, "_inclusion_stats"), - cohortSummaryStatsTable = paste0(cohortTable, "_summary_stats")) { - if (is.null(baseUrl) && is.null(cohortJson)) { - stop("Must provide either baseUrl and cohortId, or cohortJson and cohortSql") - } - if (!is.null(cohortJson) && !is.character(cohortJson)) { - stop("cohortJson should be character (a JSON string).") - } - start <- Sys.time() - if (is.null(cohortJson)) { - ParallelLogger::logInfo("Retrieving cohort definition from WebAPI") - cohortDefinition <- ROhdsiWebApi::getCohortDefinition(cohortId = cohortId, - baseUrl = baseUrl) - cohortDefinition <- cohortDefinition$expression - cohortSql <- ROhdsiWebApi::getCohortSql(cohortDefinition = cohortDefinition, - baseUrl = baseUrl, - generateStats = generateInclusionStats) - } else { - cohortDefinition <- RJSONIO::fromJSON(content = cohortJson, digits = 23) - } - if (generateInclusionStats) { - inclusionRules <- tidyr::tibble() - if (!is.null(cohortDefinition$InclusionRules)) { - nrOfRules <- length(cohortDefinition$InclusionRules) - if (nrOfRules > 0) { - for (i in 1:nrOfRules) { - inclusionRules <- dplyr::bind_rows(inclusionRules, tidyr::tibble(cohortId = cohortId, - ruleSequence = i - 1, - name = cohortDefinition$InclusionRules[[i]]$name)) %>% - dplyr::mutate(name = stringr::str_replace_na(string = .data$name, replacement = '')) - } - } - } - } - - if (is.null(connection)) { - connection <- DatabaseConnector::connect(connectionDetails) - on.exit(DatabaseConnector::disconnect(connection)) - } - - ParallelLogger::logInfo("Instantiation cohort with cohort_definition_id = ", cohortId) - sql <- cohortSql - .warnMismatchSqlInclusionStats(sql, generateInclusionStats = generateInclusionStats) - if (generateInclusionStats) { - sql <- SqlRender::render(sql, - cdm_database_schema = cdmDatabaseSchema, - vocabulary_database_schema = cdmDatabaseSchema, - target_database_schema = cohortDatabaseSchema, - target_cohort_table = cohortTable, - target_cohort_id = cohortId, - results_database_schema.cohort_inclusion = paste(resultsDatabaseSchema, - cohortInclusionTable, - sep = "."), - results_database_schema.cohort_inclusion_result = paste(resultsDatabaseSchema, - cohortInclusionResultTable, - sep = "."), - results_database_schema.cohort_inclusion_stats = paste(resultsDatabaseSchema, - cohortInclusionStatsTable, - sep = "."), - results_database_schema.cohort_summary_stats = paste(resultsDatabaseSchema, - cohortSummaryStatsTable, - sep = ".")) - } else { - sql <- SqlRender::render(sql, - cdm_database_schema = cdmDatabaseSchema, - vocabulary_database_schema = cdmDatabaseSchema, - target_database_schema = cohortDatabaseSchema, - target_cohort_table = cohortTable, - target_cohort_id = cohortId) - } - sql <- SqlRender::translate(sql, - targetDialect = connection@dbms, - oracleTempSchema = oracleTempSchema) - DatabaseConnector::executeSql(connection, sql) - - if (generateInclusionStats && nrow(inclusionRules) > 0) { - DatabaseConnector::insertTable(connection = connection, - tableName = paste(resultsDatabaseSchema, - cohortInclusionTable, - sep = "."), - data = inclusionRules, - dropTableIfExists = FALSE, - createTable = FALSE, - tempTable = FALSE, - camelCaseToSnakeCase = TRUE) - } - delta <- Sys.time() - start - writeLines(paste("Instantiating cohort took", signif(delta, 3), attr(delta, "units"))) - + writeLines(paste( + "Creating cohort table took", + signif(delta, 3), + attr(delta, "units") + )) } getInclusionStatisticsFromFiles <- function(cohortIds = NULL, @@ -418,34 +312,45 @@ getInclusionStatisticsFromFiles <- function(cohortIds = NULL, simplify = TRUE) { start <- Sys.time() + if (!file.exists(cohortInclusionFile)) { + return(NULL) + } + fetchStats <- function(file) { ParallelLogger::logDebug("- Fetching data from ", file) - stats <- readr::read_csv(file, + stats <- readr::read_csv(file, col_types = readr::cols(), guess_max = min(1e7)) if (!is.null(cohortIds)) { - stats <- stats %>% + stats <- stats %>% dplyr::filter(.data$cohortDefinitionId %in% cohortIds) } return(stats) } - inclusion <- fetchStats(cohortInclusionFile) %>% + inclusion <- fetchStats(cohortInclusionFile) %>% tidyr::replace_na(replace = list(description = '')) summaryStats <- fetchStats(cohortSummaryStatsFile) inclusionStats <- fetchStats(cohortInclusionStatsFile) inclusionResults <- fetchStats(cohortInclusionResultFile) result <- dplyr::tibble() for (cohortId in unique(inclusion$cohortDefinitionId)) { - cohortResult <- processInclusionStats(inclusion = filter(inclusion, .data$cohortDefinitionId == cohortId), - inclusionResults = filter(inclusionResults, .data$cohortDefinitionId == cohortId), - inclusionStats = filter(inclusionStats, .data$cohortDefinitionId == cohortId), - summaryStats = filter(summaryStats, .data$cohortDefinitionId == cohortId), - simplify = simplify) + cohortResult <- + processInclusionStats( + inclusion = filter(inclusion, .data$cohortDefinitionId == cohortId), + inclusionResults = filter(inclusionResults, .data$cohortDefinitionId == cohortId), + inclusionStats = filter(inclusionStats, .data$cohortDefinitionId == cohortId), + summaryStats = filter(summaryStats, .data$cohortDefinitionId == cohortId), + simplify = simplify + ) cohortResult$cohortDefinitionId <- cohortId result <- dplyr::bind_rows(result, cohortResult) } delta <- Sys.time() - start - writeLines(paste("Fetching inclusion statistics took", signif(delta, 3), attr(delta, "units"))) + writeLines(paste( + "Fetching inclusion statistics took", + signif(delta, 3), + attr(delta, "units") + )) return(result) } @@ -462,34 +367,47 @@ processInclusionStats <- function(inclusion, result <- inclusion %>% dplyr::select(.data$ruleSequence, .data$name) %>% dplyr::distinct() %>% - dplyr::inner_join(inclusionStats %>% - dplyr::filter(.data$modeId == 0) %>% - dplyr::select(.data$ruleSequence, .data$personCount, .data$gainCount, .data$personTotal), - by = "ruleSequence") %>% + dplyr::inner_join( + inclusionStats %>% + dplyr::filter(.data$modeId == 0) %>% + dplyr::select( + .data$ruleSequence, + .data$personCount, + .data$gainCount, + .data$personTotal + ), + by = "ruleSequence" + ) %>% dplyr::mutate(remain = 0) - inclusionResults <- inclusionResults %>% + inclusionResults <- inclusionResults %>% dplyr::filter(.data$modeId == 0) mask <- 0 for (ruleId in 0:(nrow(result) - 1)) { - mask <- bitwOr(mask, 2^ruleId) - idx <- bitwAnd(inclusionResults$inclusionRuleMask, mask) == mask - result$remain[result$ruleSequence == ruleId] <- sum(inclusionResults$personCount[idx]) + mask <- bitwOr(mask, 2 ^ ruleId) + idx <- + bitwAnd(inclusionResults$inclusionRuleMask, mask) == mask + result$remain[result$ruleSequence == ruleId] <- + sum(inclusionResults$personCount[idx]) } - colnames(result) <- c("ruleSequenceId", - "ruleName", - "meetSubjects", - "gainSubjects", - "totalSubjects", - "remainSubjects") + colnames(result) <- c( + "ruleSequenceId", + "ruleName", + "meetSubjects", + "gainSubjects", + "totalSubjects", + "remainSubjects" + ) } else { if (nrow(inclusion) == 0) { return(list()) } - result <- list(inclusion = inclusion, - inclusionResults = inclusionResults, - inclusionStats = inclusionStats, - summaryStats = summaryStats) + result <- list( + inclusion = inclusion, + inclusionResults = inclusionResults, + inclusionStats = inclusionStats, + summaryStats = summaryStats + ) } return(result) } @@ -504,12 +422,16 @@ processInclusionStats <- function(inclusion, #' #' @template CohortTable #' +#' @template TempEmulationSchema +#' #' @template OracleTempSchema #' #' @template CdmDatabaseSchema -#' +#' +#' @template VocabularyDatabaseSchema +#' #' @template CohortSetSpecs -#' +#' #' @template CohortSetReference #' #' @param cohortIds Optionally, provide a subset of cohort IDs to restrict the @@ -523,12 +445,14 @@ processInclusionStats <- function(inclusion, #' @param incrementalFolder If \code{incremental = TRUE}, specify a folder where records are kept #' of which definition has been executed. #' @return -#' A data frame with cohort counts +#' A data frame with cohort counts #' #' @export instantiateCohortSet <- function(connectionDetails = NULL, connection = NULL, cdmDatabaseSchema, + vocabularyDatabaseSchema = cdmDatabaseSchema, + tempEmulationSchema = NULL, oracleTempSchema = NULL, cohortDatabaseSchema = cdmDatabaseSchema, cohortTable = "cohort", @@ -539,9 +463,19 @@ instantiateCohortSet <- function(connectionDetails = NULL, cohortSetReference = NULL, generateInclusionStats = FALSE, inclusionStatisticsFolder = NULL, - createCohortTable = FALSE, + createCohortTable = TRUE, incremental = FALSE, incrementalFolder = NULL) { + if (!is.null(cohortSetReference)) { + ParallelLogger::logInfo("Found cohortSetReference. Cohort Diagnostics is running in WebApi mode.") + cohortToCreateFile <- NULL + } + + if (!is.null(oracleTempSchema) && is.null(tempEmulationSchema)) { + tempEmulationSchema <- oracleTempSchema + warning('OracleTempSchema has been deprecated by DatabaseConnector') + } + if (generateInclusionStats) { if (is.null(inclusionStatisticsFolder)) { stop("Must specify inclusionStatisticsFolder when generateInclusionStats = TRUE") @@ -567,155 +501,226 @@ instantiateCohortSet <- function(connectionDetails = NULL, if (createCohortTable) { needToCreate <- TRUE if (incremental) { - tables <- DatabaseConnector::getTableNames(connection, cohortDatabaseSchema) + tables <- + DatabaseConnector::getTableNames(connection, cohortDatabaseSchema) if (toupper(cohortTable) %in% toupper(tables)) { ParallelLogger::logInfo("Cohort table already exists and in incremental mode, so not recreating table.") needToCreate <- FALSE } } if (needToCreate) { - createCohortTable(connection = connection, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - createInclusionStatsTables = FALSE) + createCohortTable( + connection = connection, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable + ) } } - cohorts <- getCohortsJsonAndSql(packageName = packageName, - cohortToCreateFile = cohortToCreateFile, - baseUrl = baseUrl, - cohortSetReference = cohortSetReference, - cohortIds = cohortIds) + cohorts <- getCohortsJsonAndSql( + packageName = packageName, + cohortToCreateFile = cohortToCreateFile, + baseUrl = baseUrl, + cohortSetReference = cohortSetReference, + cohortIds = cohortIds, + generateStats = generateInclusionStats + ) if (incremental) { cohorts$checksum <- computeChecksum(cohorts$sql) - recordKeepingFile <- file.path(incrementalFolder, "InstantiatedCohorts.csv") + recordKeepingFile <- + file.path(incrementalFolder, "InstantiatedCohorts.csv") } if (generateInclusionStats) { - createTempInclusionStatsTables(connection, oracleTempSchema, cohorts) + createTempInclusionStatsTables(connection, tempEmulationSchema, cohorts) } - instantiatedCohortIds <- c() + instantiatedCohortIds <- c() for (i in 1:nrow(cohorts)) { - if (!incremental || isTaskRequired(cohortId = cohorts$cohortId[i], - checksum = cohorts$checksum[i], - recordKeepingFile = recordKeepingFile)) { - ParallelLogger::logInfo("Instantiation cohort ", cohorts$cohortName[i], " (Cohort id: ", cohorts$cohortId[i], ")") + if (!incremental || isTaskRequired( + cohortId = cohorts$cohortId[i], + checksum = cohorts$checksum[i], + recordKeepingFile = recordKeepingFile + )) { + ParallelLogger::logInfo( + "Instantiation cohort ", + cohorts$cohortName[i], + " (Cohort id: ", + cohorts$cohortId[i], + ")" + ) sql <- cohorts$sql[i] .warnMismatchSqlInclusionStats(sql, generateInclusionStats = generateInclusionStats) - if (generateInclusionStats) { + sql <- SqlRender::render( + sql, + cdm_database_schema = cdmDatabaseSchema, + target_database_schema = cohortDatabaseSchema, + target_cohort_table = cohortTable, + target_cohort_id = cohorts$cohortId[i] + ) + if (stringr::str_detect(string = sql, + pattern = 'vocabulary_database_schema')) { sql <- SqlRender::render(sql, - cdm_database_schema = cdmDatabaseSchema, - vocabulary_database_schema = cdmDatabaseSchema, - target_database_schema = cohortDatabaseSchema, - target_cohort_table = cohortTable, - target_cohort_id = cohorts$cohortId[i], - results_database_schema.cohort_inclusion = "#cohort_inclusion", - results_database_schema.cohort_inclusion_result = "#cohort_inc_result", - results_database_schema.cohort_inclusion_stats = "#cohort_inc_stats", - results_database_schema.cohort_summary_stats = "#cohort_summary_stats") + vocabulary_database_schema = vocabularyDatabaseSchema) } else { - sql <- SqlRender::render(sql, - cdm_database_schema = cdmDatabaseSchema, - vocabulary_database_schema = cdmDatabaseSchema, - target_database_schema = cohortDatabaseSchema, - target_cohort_table = cohortTable, - target_cohort_id = cohorts$cohortId[i]) + ParallelLogger::logDebug('Cohort id ', cohorts$cohortId[i], " SQL does not have vocabularyDatabaseSchema.") + } + if (stringr::str_detect(string = sql, + pattern = 'results_database_schema')) { + ParallelLogger::logDebug('Cohort id ', cohorts$cohortId[i], " SQL has inclusion rule statistics tables.") + } + if (generateInclusionStats) { + if (stringr::str_detect(string = sql, + pattern = 'cohort_inclusion')) { + sql <- SqlRender::render( + sql, + results_database_schema.cohort_inclusion = "#cohort_inclusion", + results_database_schema.cohort_inclusion_result = "#cohort_inc_result", + results_database_schema.cohort_inclusion_stats = "#cohort_inc_stats", + results_database_schema.cohort_summary_stats = "#cohort_summary_stats" + ) + } else { + ParallelLogger::logDebug('Cohort id ', cohorts$cohortId[i], " SQL does not have inclusion rule statistics tables.") + } + # added for compatibility for 2.8.1 + # https://github.com/OHDSI/CohortDiagnostics/issues/387 + # this table was introduced in v2.8.1, and does not exist in prior version of webapi + if (stringr::str_detect(string = sql, + pattern = 'cohort_censor_stats')) { + sql <- SqlRender::render(sql = sql, + results_database_schema.cohort_censor_stats = "#cohort_censor_stats" + ) + } + } else { + ParallelLogger::logDebug("Skipping inclusion rules for cohort id ", + cohorts$cohortId[i], + " because this diagnostics is set to FALSE.") } sql <- SqlRender::translate(sql, targetDialect = connection@dbms, - oracleTempSchema = oracleTempSchema) + tempEmulationSchema = tempEmulationSchema) DatabaseConnector::executeSql(connection, sql) - instantiatedCohortIds <- c(instantiatedCohortIds, cohorts$cohortId[i]) + instantiatedCohortIds <- + c(instantiatedCohortIds, cohorts$cohortId[i]) } } if (generateInclusionStats) { - saveAndDropTempInclusionStatsTables(connection = connection, - oracleTempSchema = oracleTempSchema, - inclusionStatisticsFolder = inclusionStatisticsFolder, - incremental = incremental, - cohortIds = instantiatedCohortIds) + saveAndDropTempInclusionStatsTables( + connection = connection, + tempEmulationSchema = tempEmulationSchema, + inclusionStatisticsFolder = inclusionStatisticsFolder, + incremental = incremental, + cohortIds = instantiatedCohortIds + ) } if (incremental) { - recordTasksDone(cohortId = cohorts$cohortId, checksum = cohorts$checksum, recordKeepingFile = recordKeepingFile) + recordTasksDone( + cohortId = cohorts$cohortId, + checksum = cohorts$checksum, + recordKeepingFile = recordKeepingFile + ) } delta <- Sys.time() - start - writeLines(paste("Instantiating cohort set took", signif(delta, 3), attr(delta, "units"))) + writeLines(paste( + "Instantiating cohort set took", + signif(delta, 3), + attr(delta, "units") + )) } -createTempInclusionStatsTables <- function(connection, oracleTempSchema, cohorts) { - ParallelLogger::logInfo("Creating temporary inclusion statistics tables") - sql <- SqlRender::loadRenderTranslateSql("inclusionStatsTables.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - oracleTempSchema = oracleTempSchema) - DatabaseConnector::executeSql(connection, sql) - - inclusionRules <- tidyr::tibble() - for (i in 1:nrow(cohorts)) { - cohortDefinition <- RJSONIO::fromJSON(content = cohorts$json[i], digits = 23) - if (!is.null(cohortDefinition$InclusionRules)) { - nrOfRules <- length(cohortDefinition$InclusionRules) - if (nrOfRules > 0) { - for (j in 1:nrOfRules) { - inclusionRules <- dplyr::bind_rows(inclusionRules, - tidyr::tibble(cohortId = cohorts$cohortId[i], - ruleSequence = j - 1, - ruleName = cohortDefinition$InclusionRules[[j]]$name)) %>% - dplyr::distinct() +createTempInclusionStatsTables <- + function(connection, tempEmulationSchema, cohorts) { + ParallelLogger::logInfo("Creating temporary inclusion statistics tables") + sql <- + SqlRender::loadRenderTranslateSql( + "inclusionStatsTables.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + tempEmulationSchema = tempEmulationSchema + ) + DatabaseConnector::executeSql(connection, sql) + + inclusionRules <- tidyr::tibble() + for (i in 1:nrow(cohorts)) { + cohortDefinition <- + RJSONIO::fromJSON(content = cohorts$json[i], digits = 23) + if (!is.null(cohortDefinition$InclusionRules)) { + nrOfRules <- length(cohortDefinition$InclusionRules) + if (nrOfRules > 0) { + for (j in 1:nrOfRules) { + ruleName <- cohortDefinition$InclusionRules[[j]]$name + if (length(ruleName) == 0) { + ruleName <- paste0("Unamed rule (Sequence ", j - 1, ")") + } + inclusionRules <- dplyr::bind_rows( + inclusionRules, + tidyr::tibble( + cohortId = cohorts$cohortId[i], + ruleSequence = j - 1, + ruleName = !!ruleName + ) + ) %>% + dplyr::distinct() + } } } } - } - - if (nrow(inclusionRules) > 0) { - inclusionRules <- inclusionRules %>% - dplyr::inner_join(cohorts %>% dplyr::select(.data$cohortId, .data$cohortName), by = "cohortId") %>% - dplyr::rename(name = .data$ruleName, - cohortDefinitionId = .data$cohortId) %>% - dplyr::select(.data$cohortDefinitionId, .data$ruleSequence, .data$name) - inclusionRules <- data.frame(inclusionRules) # temporary solution till DatabaseConnector supports tibble - - DatabaseConnector::insertTable(connection = connection, - tableName = "#cohort_inclusion", - data = inclusionRules, - dropTableIfExists = TRUE, - createTable = TRUE, - tempTable = TRUE, - oracleTempSchema = oracleTempSchema, - camelCaseToSnakeCase = TRUE) - } else { - inclusionRules <- data.frame(cohortDefinitionId = as.double(), - ruleSequence = as.integer(), - name = as.character()) - DatabaseConnector::insertTable(connection = connection, - tableName = "#cohort_inclusion", - data = inclusionRules, - dropTableIfExists = TRUE, - createTable = TRUE, - tempTable = TRUE, - oracleTempSchema = oracleTempSchema, - camelCaseToSnakeCase = TRUE) + if (nrow(inclusionRules) > 0) { + inclusionRules <- inclusionRules %>% + dplyr::inner_join(cohorts %>% dplyr::select(.data$cohortId, .data$cohortName), + by = "cohortId") %>% + dplyr::rename(name = .data$ruleName, + cohortDefinitionId = .data$cohortId) %>% + dplyr::select(.data$cohortDefinitionId, .data$ruleSequence, .data$name) + + DatabaseConnector::insertTable( + connection = connection, + tableName = "#cohort_inclusion", + data = inclusionRules, + dropTableIfExists = TRUE, + createTable = TRUE, + tempTable = TRUE, + tempEmulationSchema = tempEmulationSchema, + camelCaseToSnakeCase = TRUE + ) + } else { + inclusionRules <- dplyr::tibble( + cohortDefinitionId = as.double(), + ruleSequence = as.integer(), + name = as.character() + ) + DatabaseConnector::insertTable( + connection = connection, + tableName = "#cohort_inclusion", + data = inclusionRules, + dropTableIfExists = TRUE, + createTable = TRUE, + tempTable = TRUE, + tempEmulationSchema = tempEmulationSchema, + camelCaseToSnakeCase = TRUE + ) + } } -} -saveAndDropTempInclusionStatsTables <- function(connection, - oracleTempSchema, - inclusionStatisticsFolder, +saveAndDropTempInclusionStatsTables <- function(connection, + tempEmulationSchema, + inclusionStatisticsFolder, incremental, cohortIds) { fetchStats <- function(table, fileName) { ParallelLogger::logDebug("- Fetching data from ", table) sql <- "SELECT * FROM @table" - data <- DatabaseConnector::renderTranslateQuerySql(sql = sql, - connection = connection, - oracleTempSchema = oracleTempSchema, - snakeCaseToCamelCase = TRUE, - table = table) %>% + data <- DatabaseConnector::renderTranslateQuerySql( + sql = sql, + connection = connection, + tempEmulationSchema = tempEmulationSchema, + snakeCaseToCamelCase = TRUE, + table = table + ) %>% tidyr::tibble() fullFileName <- file.path(inclusionStatisticsFolder, fileName) if (incremental) { @@ -729,40 +734,48 @@ saveAndDropTempInclusionStatsTables <- function(connection, fetchStats("#cohort_inc_stats", "cohortIncStats.csv") fetchStats("#cohort_summary_stats", "cohortSummaryStats.csv") - sql <- "TRUNCATE TABLE #cohort_inclusion; + sql <- "TRUNCATE TABLE #cohort_inclusion; DROP TABLE #cohort_inclusion; - - TRUNCATE TABLE #cohort_inc_result; + + TRUNCATE TABLE #cohort_inc_result; DROP TABLE #cohort_inc_result; - - TRUNCATE TABLE #cohort_inc_stats; + + TRUNCATE TABLE #cohort_inc_stats; DROP TABLE #cohort_inc_stats; - - TRUNCATE TABLE #cohort_summary_stats; + + TRUNCATE TABLE #cohort_summary_stats; DROP TABLE #cohort_summary_stats;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - progressBar = FALSE, - reportOverallTime = FALSE, - oracleTempSchema = oracleTempSchema) + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + progressBar = FALSE, + reportOverallTime = FALSE, + tempEmulationSchema = tempEmulationSchema + ) } -.warnMismatchSqlInclusionStats <- function(sql, generateInclusionStats) { - if (any(stringr::str_detect(string = sql, pattern = "_inclusion_result"), - stringr::str_detect(string = sql, pattern = "_inclusion_stats"), - stringr::str_detect(string = sql, pattern = "_summary_stats") - ) - ) { - if (isFALSE(generateInclusionStats)) { - warning("The SQL template used to instantiate cohort was designed to output cohort inclusion statistics. - But, generateInclusionStats is set to False while instantiating cohort. - This may cause error and terminate cohort diagnositcs.") - } - } else { - if (isTRUE(generateInclusionStats)) { - warning("The SQL template used to instantiate cohort was designed to NOT output cohort inclusion statistics. - But, generateInclusionStats is set to TRUE while instantiating cohort. - This may cause error and terminate cohort diagnositcs.") +.warnMismatchSqlInclusionStats <- + function(sql, generateInclusionStats) { + if (any( + stringr::str_detect(string = sql, pattern = "_inclusion_result"), + stringr::str_detect(string = sql, pattern = "_inclusion_stats"), + stringr::str_detect(string = sql, pattern = "_summary_stats"), + stringr::str_detect(string = sql, pattern = "_censor_stats") + )) { + if (isFALSE(generateInclusionStats)) { + warning( + "The SQL template used to instantiate cohort was designed to output cohort inclusion statistics. + But, generateInclusionStats is set to False while instantiating cohort. + This may cause error and terminate cohort diagnositcs." + ) + } + } else { + if (isTRUE(generateInclusionStats)) { + warning( + "The SQL template used to instantiate cohort was designed to NOT output cohort inclusion statistics. + But, generateInclusionStats is set to TRUE while instantiating cohort. + This may cause error and terminate cohort diagnositcs." + ) + } } } -} diff --git a/R/CohortDiagnostics.R b/R/CohortDiagnostics.R index 57f8e050d..918df762f 100644 --- a/R/CohortDiagnostics.R +++ b/R/CohortDiagnostics.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,7 +20,7 @@ #' @import DatabaseConnector #' @importFrom grDevices rgb #' @importFrom stats aggregate -#' @importFrom utils write.csv install.packages menu unzip +#' @importFrom utils write.csv install.packages menu unzip setTxtProgressBar txtProgressBar #' @import dplyr #' @importFrom rlang .data #' @importFrom methods is diff --git a/R/CohortLevelDiagnostics.R b/R/CohortLevelDiagnostics.R index bf41dc9f3..d5ac44048 100644 --- a/R/CohortLevelDiagnostics.R +++ b/R/CohortLevelDiagnostics.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -42,29 +42,49 @@ getCohortCounts <- function(connectionDetails = NULL, on.exit(DatabaseConnector::disconnect(connection)) } - sql <- SqlRender::loadRenderTranslateSql(sqlFilename = "CohortCounts.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - cohort_database_schema = cohortDatabaseSchema, - cohort_table = cohortTable, - cohort_ids = cohortIds) - counts <- DatabaseConnector::querySql(connection, sql, snakeCaseToCamelCase = TRUE) %>% - tidyr::tibble() - delta <- Sys.time() - start - ParallelLogger::logInfo(paste("Counting cohorts took", - signif(delta, 3), - attr(delta, "units"))) - return(counts) - + sql <- + SqlRender::loadRenderTranslateSql( + sqlFilename = "CohortCounts.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + cohort_database_schema = cohortDatabaseSchema, + cohort_table = cohortTable, + cohort_ids = cohortIds + ) + tablesInServer <- + tolower(DatabaseConnector::dbListTables(conn = connection, schema = cohortDatabaseSchema)) + if (tolower(cohortTable) %in% tablesInServer) { + counts <- + DatabaseConnector::querySql(connection, sql, snakeCaseToCamelCase = TRUE) %>% + tidyr::tibble() + delta <- Sys.time() - start + ParallelLogger::logInfo(paste( + "Counting cohorts took", + signif(delta, 3), + attr(delta, "units") + )) + return(counts) + } else { + warning('Cohort table was not found. Was it created?') + return(NULL) + } } -checkIfCohortInstantiated <- function(connection, cohortDatabaseSchema, cohortTable, cohortId) { - sql <- "SELECT COUNT(*) COUNT FROM @cohort_database_schema.@cohort_table WHERE cohort_definition_id = @cohort_id;" - count <- DatabaseConnector::renderTranslateQuerySql(connection = connection, - sql, - cohort_database_schema = cohortDatabaseSchema, - cohort_table = cohortTable, - cohort_id = cohortId) - count <- count %>% dplyr::pull(1) - return(count > 0) -} +checkIfCohortInstantiated <- + function(connection, + cohortDatabaseSchema, + cohortTable, + cohortId) { + sql <- + "SELECT COUNT(*) COUNT FROM @cohort_database_schema.@cohort_table WHERE cohort_definition_id = @cohort_id;" + count <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql, + cohort_database_schema = cohortDatabaseSchema, + cohort_table = cohortTable, + cohort_id = cohortId + ) + count <- count %>% dplyr::pull(1) + return(count > 0) + } diff --git a/R/ConceptIds.R b/R/ConceptIds.R index 63db7b8c2..aaca84222 100644 --- a/R/ConceptIds.R +++ b/R/ConceptIds.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,16 +16,18 @@ exportConceptInformation <- function(connection = NULL, cdmDatabaseSchema, - oracleTempSchema, + tempEmulationSchema, conceptIdTable, - vocabularyTableNames = c("concept", - "conceptAncestor", - "conceptClass", - "conceptRelationship", - "conceptSynonym", - "domain", - "relationship", - "vocabulary"), + vocabularyTableNames = c( + "concept", + "conceptAncestor", + "conceptClass", + "conceptRelationship", + "conceptSynonym", + "domain", + "relationship", + "vocabulary" + ), incremental, exportFolder) { start <- Sys.time() @@ -33,78 +35,101 @@ exportConceptInformation <- function(connection = NULL, warning('No connection provided') } - vocabularyTableNames <- tolower(SqlRender::camelCaseToSnakeCase(vocabularyTableNames)) - tablesInCdmDatabaseSchema <- tolower(DatabaseConnector::getTableNames(connection, cdmDatabaseSchema)) - vocabularyTablesInCdmDatabaseSchema <- tablesInCdmDatabaseSchema[tablesInCdmDatabaseSchema %in% vocabularyTableNames] + vocabularyTableNames <- + tolower(SqlRender::camelCaseToSnakeCase(vocabularyTableNames)) + tablesInCdmDatabaseSchema <- + tolower(DatabaseConnector::getTableNames(connection, cdmDatabaseSchema)) + vocabularyTablesInCdmDatabaseSchema <- + tablesInCdmDatabaseSchema[tablesInCdmDatabaseSchema %in% vocabularyTableNames] if (length(vocabularyTablesInCdmDatabaseSchema) == 0) { stop("Vocabulary tables not found in ", cdmDatabaseSchema) } sql <- "SELECT DISTINCT concept_id FROM @unique_concept_id_table;" - uniqueConceptIds <- DatabaseConnector::renderTranslateQuerySql(connection = connection, - sql = sql, - unique_concept_id_table = conceptIdTable, - snakeCaseToCamelCase = TRUE, - oracleTempSchema = oracleTempSchema)[, 1] + uniqueConceptIds <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = sql, + unique_concept_id_table = conceptIdTable, + snakeCaseToCamelCase = TRUE, + tempEmulationSchema = tempEmulationSchema + )[, 1] if (length(uniqueConceptIds) == 0) { - warning("No concept IDs found to retrieve information for") + warning("No concept IDs in cohorts. No concept information exported.") return(NULL) } for (vocabularyTable in vocabularyTablesInCdmDatabaseSchema) { - ParallelLogger::logInfo("- Retrieving concept information from vocabulary table '", vocabularyTable, "'") + ParallelLogger::logInfo("- Retrieving concept information from vocabulary table '", + vocabularyTable, + "'") if (vocabularyTable %in% c("concept", "concept_synonym")) { sql <- "SELECT a.* FROM @cdm_database_schema.@table a INNER JOIN (SELECT distinct concept_id FROM @unique_concept_id_table) b ON a.concept_id = b.concept_id;" } else if (vocabularyTable %in% c("concept_ancestor")) { sql <- "SELECT a.* FROM @cdm_database_schema.@table a - INNER JOIN (SELECT distinct concept_id FROM @unique_concept_id_table) b1 + LEFT JOIN (SELECT distinct concept_id FROM @unique_concept_id_table) b1 ON a.ancestor_concept_id = b1.concept_id - INNER JOIN (SELECT distinct concept_id FROM @unique_concept_id_table) b2 - ON a.descendant_concept_id = b2.concept_id;" + LEFT JOIN (SELECT distinct concept_id FROM @unique_concept_id_table) b2 + ON a.descendant_concept_id = b2.concept_id + WHERE b1.concept_id IS NOT NULL or b2.concept_id IS NOT NULL;" } else if (vocabularyTable %in% c("concept_relationship")) { sql <- "SELECT a.* FROM @cdm_database_schema.@table a INNER JOIN (SELECT distinct concept_id FROM @unique_concept_id_table) b1 ON a.concept_id_1 = b1.concept_id INNER JOIN (SELECT distinct concept_id FROM @unique_concept_id_table) b2 - ON a.concept_id_2 = b2.concept_id;" - } + ON a.concept_id_2 = b2.concept_id + WHERE b1.concept_id IS NOT NULL or b2.concept_id IS NOT NULL;" + } if (vocabularyTable %in% c("concept", "concept_synonym", "concept_ancestor", "concept_relationship")) { - data <- DatabaseConnector::renderTranslateQuerySql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - cdm_database_schema = cdmDatabaseSchema, - unique_concept_id_table = conceptIdTable, - table = vocabularyTable, - snakeCaseToCamelCase = TRUE) + data <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + cdm_database_schema = cdmDatabaseSchema, + unique_concept_id_table = conceptIdTable, + table = vocabularyTable, + snakeCaseToCamelCase = TRUE + ) if (nrow(data) > 0) { - writeToCsv(data = data, - fileName = file.path(exportFolder, paste(vocabularyTable, "csv", sep = ".")), - incremental = incremental, - conceptId = uniqueConceptIds) + writeToCsv( + data = data, + fileName = file.path(exportFolder, paste(vocabularyTable, "csv", sep = ".")), + incremental = incremental, + conceptId = uniqueConceptIds + ) } } else if (vocabularyTable %in% c("domain", "relationship", "vocabulary", "conceptClass")) { sql <- "SELECT * FROM @cdm_database_schema.@table;" - data <- DatabaseConnector::renderTranslateQuerySql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - cdm_database_schema = cdmDatabaseSchema, - table = vocabularyTable, - snakeCaseToCamelCase = TRUE) + data <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + cdm_database_schema = cdmDatabaseSchema, + table = vocabularyTable, + snakeCaseToCamelCase = TRUE + ) if (nrow(data) > 0) { - writeToCsv(data = data, - fileName = file.path(exportFolder, paste(vocabularyTable, "csv", sep = ".")), - incremental = FALSE) + writeToCsv( + data = data, + fileName = file.path(exportFolder, paste(vocabularyTable, "csv", sep = ".")), + incremental = FALSE + ) } } } delta <- Sys.time() - start - ParallelLogger::logInfo("Retrieving concept information took ", signif(delta, 3), " ", attr(delta, "units")) + ParallelLogger::logInfo("Retrieving concept information took ", + signif(delta, 3), + " ", + attr(delta, "units")) } diff --git a/R/ConceptSets.R b/R/ConceptSets.R index f258dc007..68bc44219 100644 --- a/R/ConceptSets.R +++ b/R/ConceptSets.R @@ -1,4 +1,4 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics # @@ -67,7 +67,8 @@ extractConceptSetsSqlFromCohortSql <- function(cohortSql) { extractConceptSetsJsonFromCohortJson <- function(cohortJson) { - cohortDefinition <- RJSONIO::fromJSON(content = cohortJson, digits = 23) + cohortDefinition <- + RJSONIO::fromJSON(content = cohortJson, digits = 23) if ("expression" %in% names(cohortDefinition)) { expression <- cohortDefinition$expression } else { @@ -96,34 +97,44 @@ combineConceptSetsFromCohorts <- function(cohorts) { checkmate::assertDataFrame(x = cohorts, min.cols = 4, add = errorMessage) - checkmate::assertNames(x = colnames(cohorts), - must.include = c('cohortId', 'sql', 'json', 'cohortName')) + checkmate::assertNames( + x = colnames(cohorts), + must.include = c('cohortId', 'sql', 'json', 'cohortName') + ) checkmate::reportAssertions(errorMessage) - checkmate::assertDataFrame(x = cohorts %>% dplyr::select(.data$cohortId, - .data$sql, - .data$json, - .data$cohortName), - any.missing = FALSE, - min.cols = 4, - add = errorMessage) + checkmate::assertDataFrame( + x = cohorts %>% dplyr::select(.data$cohortId, + .data$sql, + .data$json, + .data$cohortName), + any.missing = FALSE, + min.cols = 4, + add = errorMessage + ) checkmate::reportAssertions(errorMessage) conceptSets <- list() conceptSetCounter <- 0 for (i in (1:nrow(cohorts))) { - cohort <- cohorts[i,] - sql <- extractConceptSetsSqlFromCohortSql(cohortSql = cohort$sql) - json <- extractConceptSetsJsonFromCohortJson(cohortJson = cohort$json) + cohort <- cohorts[i, ] + sql <- + extractConceptSetsSqlFromCohortSql(cohortSql = cohort$sql) + json <- + extractConceptSetsJsonFromCohortJson(cohortJson = cohort$json) if (nrow(sql) == 0 || nrow(json) == 0) { - ParallelLogger::logInfo("Cohort Definition expression does not have a concept set expression. ", - "Skipping Cohort: ", - cohort$cohortName ) + ParallelLogger::logInfo( + "Cohort Definition expression does not have a concept set expression. ", + "Skipping Cohort: ", + cohort$cohortName + ) } else { if (!length(sql$conceptSetId %>% unique()) == length(json$conceptSetId %>% unique())) { - stop("Mismatch in concept set IDs between SQL and JSON for cohort ", - cohort$cohortFullName) + stop( + "Mismatch in concept set IDs between SQL and JSON for cohort ", + cohort$cohortFullName + ) } if (length(sql) > 0 && length(json) > 0) { conceptSetCounter <- conceptSetCounter + 1 @@ -133,6 +144,9 @@ combineConceptSetsFromCohorts <- function(cohorts) { } } } + if (length(conceptSets) == 0) { + return(NULL) + } conceptSets <- dplyr::bind_rows(conceptSets) %>% dplyr::arrange(.data$cohortId, .data$conceptSetId) @@ -142,33 +156,58 @@ combineConceptSetsFromCohorts <- function(cohorts) { dplyr::mutate(uniqueConceptSetId = dplyr::row_number()) conceptSets <- conceptSets %>% - dplyr::inner_join(uniqueConceptSets, by = "conceptSetExpression") %>% - dplyr::distinct() %>% - dplyr::relocate(.data$uniqueConceptSetId, .data$cohortId, .data$conceptSetId) %>% - dplyr::arrange(.data$uniqueConceptSetId, .data$cohortId, .data$conceptSetId) - + dplyr::inner_join(uniqueConceptSets, by = "conceptSetExpression") %>% + dplyr::distinct() %>% + dplyr::relocate(.data$uniqueConceptSetId, + .data$cohortId, + .data$conceptSetId) %>% + dplyr::arrange(.data$uniqueConceptSetId, + .data$cohortId, + .data$conceptSetId) return(conceptSets) } -mergeTempTables <- function(connection, tableName, tempTables, oracleTempSchema) { - valueString <- paste(tempTables, collapse = "\n\n UNION ALL\n\n SELECT *\n FROM ") - sql <- sprintf("SELECT *\nINTO %s\nFROM (\n SELECT *\n FROM %s\n) tmp;", tableName, valueString) - sql <- SqlRender::translate(sql, targetDialect = connection@dbms, oracleTempSchema = oracleTempSchema) - DatabaseConnector::executeSql(connection, sql, progressBar = FALSE, reportOverallTime = FALSE) - - # Drop temp tables: - for (tempTable in tempTables) { - sql <- sprintf("TRUNCATE TABLE %s;\nDROP TABLE %s;", tempTable, tempTable) - sql <- SqlRender::translate(sql, targetDialect = connection@dbms, oracleTempSchema = oracleTempSchema) - DatabaseConnector::executeSql(connection, sql, progressBar = FALSE, reportOverallTime = FALSE) +mergeTempTables <- + function(connection, + tableName, + tempTables, + tempEmulationSchema) { + valueString <- + paste(tempTables, collapse = "\n\n UNION ALL\n\n SELECT *\n FROM ") + sql <- + sprintf("SELECT *\nINTO %s\nFROM (\n SELECT *\n FROM %s\n) tmp;", + tableName, + valueString) + sql <- + SqlRender::translate(sql, + targetDialect = connection@dbms, + tempEmulationSchema = tempEmulationSchema) + DatabaseConnector::executeSql(connection, + sql, + progressBar = FALSE, + reportOverallTime = FALSE) + + # Drop temp tables: + for (tempTable in tempTables) { + sql <- + sprintf("TRUNCATE TABLE %s;\nDROP TABLE %s;", tempTable, tempTable) + sql <- + SqlRender::translate(sql, + targetDialect = connection@dbms, + tempEmulationSchema = tempEmulationSchema) + DatabaseConnector::executeSql(connection, + sql, + progressBar = FALSE, + reportOverallTime = FALSE) + } } -} instantiateUniqueConceptSets <- function(uniqueConceptSets, connection, cdmDatabaseSchema, - oracleTempSchema, + vocabularyDatabaseSchema = cdmDatabaseSchema, + tempEmulationSchema, conceptSetsTable = '#inst_concept_sets') { ParallelLogger::logInfo("Instantiating concept sets") sql <- sapply(split(uniqueConceptSets, 1:nrow(uniqueConceptSets)), @@ -184,26 +223,36 @@ instantiateUniqueConceptSets <- function(uniqueConceptSets, tempTables <- c() pb <- utils::txtProgressBar(style = 3) for (start in seq(1, length(sql), by = batchSize)) { - utils::setTxtProgressBar(pb, start/length(sql)) - tempTable <- paste("#", paste(sample(letters, 20, replace = TRUE), collapse = ""), sep = "") + utils::setTxtProgressBar(pb, start / length(sql)) + tempTable <- + paste("#", paste(sample(letters, 20, replace = TRUE), collapse = ""), sep = "") tempTables <- c(tempTables, tempTable) end <- min(start + batchSize - 1, length(sql)) sqlSubset <- sql[start:end] sqlSubset <- paste(sqlSubset, collapse = "\n\n UNION ALL\n\n") - sqlSubset <- sprintf("SELECT *\nINTO %s\nFROM (\n %s\n) tmp;", tempTable, sqlSubset) - sqlSubset <- SqlRender::render(sqlSubset, vocabulary_database_schema = cdmDatabaseSchema) + sqlSubset <- + sprintf("SELECT *\nINTO %s\nFROM (\n %s\n) tmp;", + tempTable, + sqlSubset) + sqlSubset <- + SqlRender::render(sqlSubset, vocabulary_database_schema = vocabularyDatabaseSchema) sqlSubset <- SqlRender::translate(sqlSubset, targetDialect = connection@dbms, - oracleTempSchema = oracleTempSchema) - DatabaseConnector::executeSql(connection, sqlSubset, progressBar = FALSE, reportOverallTime = FALSE) + tempEmulationSchema = tempEmulationSchema) + DatabaseConnector::executeSql(connection, + sqlSubset, + progressBar = FALSE, + reportOverallTime = FALSE) } utils::setTxtProgressBar(pb, 1) close(pb) - mergeTempTables(connection = connection, - tableName = conceptSetsTable, - tempTables = tempTables, - oracleTempSchema = oracleTempSchema) + mergeTempTables( + connection = connection, + tableName = conceptSetsTable, + tempTables = tempTables, + tempEmulationSchema = tempEmulationSchema + ) } getCodeSetId <- function(criterion) { @@ -222,15 +271,16 @@ getCodeSetIds <- function(criterionList) { if (is.null(codeSetIds)) { return(NULL) } else { - return(dplyr::tibble(domain = names(criterionList), codeSetIds = codeSetIds) + return(dplyr::tibble(domain = names(criterionList), codeSetIds = codeSetIds) %>% filter(!is.na(codeSetIds))) } } runConceptSetDiagnostics <- function(connection, - oracleTempSchema, + tempEmulationSchema, cdmDatabaseSchema, + vocabularyDatabaseSchema = cdmDatabaseSchema, databaseId, cohorts, runIncludedSourceConcepts, @@ -252,25 +302,31 @@ runConceptSetDiagnostics <- function(connection, subset <- dplyr::tibble() if (runIncludedSourceConcepts) { - subsetIncluded <- subsetToRequiredCohorts(cohorts = cohorts, - task = "runIncludedSourceConcepts", - incremental = incremental, - recordKeepingFile = recordKeepingFile) + subsetIncluded <- subsetToRequiredCohorts( + cohorts = cohorts, + task = "runIncludedSourceConcepts", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) subset <- dplyr::bind_rows(subset, subsetIncluded) } if (runBreakdownIndexEvents) { - subsetBreakdown <- subsetToRequiredCohorts(cohorts = cohorts, - task = "runBreakdownIndexEvents", - incremental = incremental, - recordKeepingFile = recordKeepingFile) + subsetBreakdown <- subsetToRequiredCohorts( + cohorts = cohorts, + task = "runBreakdownIndexEvents", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) subset <- dplyr::bind_rows(subset, subsetBreakdown) } if (runOrphanConcepts) { - subsetOrphans <- subsetToRequiredCohorts(cohorts = cohorts, - task = "runOrphanConcepts", - incremental = incremental, - recordKeepingFile = recordKeepingFile) + subsetOrphans <- subsetToRequiredCohorts( + cohorts = cohorts, + task = "runOrphanConcepts", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) subset <- dplyr::bind_rows(subset, subsetOrphans) } subset <- dplyr::distinct(subset) @@ -281,24 +337,37 @@ runConceptSetDiagnostics <- function(connection, conceptSets <- combineConceptSetsFromCohorts(subset) + if (is.null(conceptSets)) { + ParallelLogger::logInfo( + "Cohorts being diagnosed does not have concept ids. Skipping concept set diagnostics." + ) + return(NULL) + } + # Save concept set metadata --------------------------------------- - writeToCsv(data = conceptSets %>% - dplyr::select(-.data$uniqueConceptSetId), - fileName = file.path(exportFolder, "concept_sets.csv"), - incremental = incremental, - cohortId = conceptSets$cohortId) + writeToCsv( + data = conceptSets %>% + dplyr::select(-.data$uniqueConceptSetId), + fileName = file.path(exportFolder, "concept_sets.csv"), + incremental = incremental, + cohortId = conceptSets$cohortId + ) - uniqueConceptSets <- conceptSets[!duplicated(conceptSets$uniqueConceptSetId),] %>% + uniqueConceptSets <- + conceptSets[!duplicated(conceptSets$uniqueConceptSetId), ] %>% dplyr::select(-.data$cohortId, -.data$conceptSetId) - instantiateUniqueConceptSets(uniqueConceptSets = uniqueConceptSets, - connection = connection, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - conceptSetsTable = "#inst_concept_sets") + instantiateUniqueConceptSets( + uniqueConceptSets = uniqueConceptSets, + connection = connection, + cdmDatabaseSchema = cdmDatabaseSchema, + vocabularyDatabaseSchema = vocabularyDatabaseSchema, + tempEmulationSchema = tempEmulationSchema, + conceptSetsTable = "#inst_concept_sets" + ) # Export concept IDs per concept set ------------------------------------------ - # Disabling for now, since we don't have a diagnostic for it. + # Disabling for now, since we don't have a diagnostic for it. # If we do enable this, it should be a separate option (e.g. runConceptSetExpansion), # and it should be tracked for incremental mode. # sql <- "SELECT DISTINCT codeset_id AS unique_concept_set_id, @@ -307,48 +376,52 @@ runConceptSetDiagnostics <- function(connection, # conceptSetConceptIds <- DatabaseConnector::renderTranslateQuerySql(connection = connection, # sql = sql, # concept_sets_table = "#inst_concept_sets", - # snakeCaseToCamelCase = TRUE) %>% + # snakeCaseToCamelCase = TRUE) %>% # tidyr::tibble() - # + # # conceptSetConceptIds <- conceptSetConceptIds %>% # dplyr::inner_join(conceptSets, by = "uniqueConceptSetId") %>% # dplyr::select(.data$cohortId, .data$conceptSetId, .data$conceptId) - # - # writeToCsv(data = conceptSetConceptIds, - # fileName = file.path(exportFolder, "concept_sets_concept_id.csv"), + # + # writeToCsv(data = conceptSetConceptIds, + # fileName = file.path(exportFolder, "concept_sets_concept_id.csv"), # incremental = incremental, # cohortId = conceptSetConceptIds$cohortId) - # - # + # + # # if (!is.null(conceptIdTable)) { # sql <- "INSERT INTO @concept_id_table (concept_id) # SELECT DISTINCT concept_id # FROM @concept_sets_table;" # DatabaseConnector::renderTranslateExecuteSql(connection = connection, # sql = sql, - # oracleTempSchema = oracleTempSchema, + # tempEmulationSchema = tempEmulationSchema, # concept_id_table = conceptIdTable, # concept_sets_table = "#inst_concept_sets", # progressBar = FALSE, # reportOverallTime = FALSE) # } - if ((runIncludedSourceConcepts && nrow(subsetIncluded) > 0) || + if ((runIncludedSourceConcepts && nrow(subsetIncluded) > 0) || (runOrphanConcepts && nrow(subsetOrphans) > 0)) { - createConceptCountsTable(connection = connection, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - conceptCountsDatabaseSchema = conceptCountsDatabaseSchema, - conceptCountsTable = conceptCountsTable, - conceptCountsTableIsTemp = conceptCountsTableIsTemp) + createConceptCountsTable( + connection = connection, + cdmDatabaseSchema = cdmDatabaseSchema, + tempEmulationSchema = tempEmulationSchema, + conceptCountsDatabaseSchema = conceptCountsDatabaseSchema, + conceptCountsTable = conceptCountsTable, + conceptCountsTableIsTemp = conceptCountsTableIsTemp + ) } if (runIncludedSourceConcepts) { # Included concepts ------------------------------------------------------------------ ParallelLogger::logInfo("Fetching included source concepts") #TODO: Disregard empty cohorts in tally: if (incremental && (nrow(cohorts) - nrow(subsetIncluded)) > 0) { - ParallelLogger::logInfo(sprintf("Skipping %s cohorts in incremental mode.", - nrow(cohorts) - nrow(subsetIncluded))) + ParallelLogger::logInfo(sprintf( + "Skipping %s cohorts in incremental mode.", + nrow(cohorts) - nrow(subsetIncluded) + )) } if (nrow(subsetIncluded) > 0) { start <- Sys.time() @@ -361,22 +434,22 @@ runConceptSetDiagnostics <- function(connection, # "CohortSourceConceptsFromCcTable.sql", # packageName = "CohortDiagnostics", # dbms = connection@dbms, - # oracleTempSchema = oracleTempSchema, + # tempEmulationSchema = tempEmulationSchema, # cdm_database_schema = cdmDatabaseSchema, # concept_counts_database_schema = conceptCountsDatabaseSchema, # concept_counts_table = conceptCountsTable, # concept_counts_table_is_temp = conceptCountsTableIsTemp # ) - # + # # sourceCounts <- # DatabaseConnector::querySql(connection, sql, snakeCaseToCamelCase = TRUE) - # + # # sql <- # SqlRender::loadRenderTranslateSql( # "CohortStandardConceptsFromCcTable.sql", # packageName = "CohortDiagnostics", # dbms = connection@dbms, - # oracleTempSchema = oracleTempSchema, + # tempEmulationSchema = tempEmulationSchema, # cdm_database_schema = cdmDatabaseSchema, # concept_counts_database_schema = conceptCountsDatabaseSchema, # concept_counts_table = conceptCountsTable, @@ -384,7 +457,7 @@ runConceptSetDiagnostics <- function(connection, # ) # standardCounts <- # DatabaseConnector::querySql(connection, sql, snakeCaseToCamelCase = TRUE) - # + # # # To avoid double counting, subtract standard concept counts included in source counts. # # Note: this can create negative counts, because a source concept can be double counted itself # # if it maps to more than one standard concept, but it will show correctly in the viewer app, @@ -408,80 +481,104 @@ runConceptSetDiagnostics <- function(connection, # standardCounts$conceptSubjects - standardCounts$dupSubjects # standardCounts$dupCount <- NULL # standardCounts$dupSubjects <- NULL - # + # # counts <- dplyr::bind_rows(sourceCounts, standardCounts) } else { - sql <- SqlRender::loadRenderTranslateSql( "CohortSourceCodes.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - oracleTempSchema = oracleTempSchema, - cdm_database_schema = cdmDatabaseSchema, - instantiated_concept_sets = "#inst_concept_sets", - include_source_concept_table = "#inc_src_concepts", - by_month = FALSE ) + sql <- SqlRender::loadRenderTranslateSql( + "CohortSourceCodes.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + tempEmulationSchema = tempEmulationSchema, + cdm_database_schema = cdmDatabaseSchema, + instantiated_concept_sets = "#inst_concept_sets", + include_source_concept_table = "#inc_src_concepts", + by_month = FALSE + ) DatabaseConnector::executeSql(connection = connection, sql = sql) - counts <- DatabaseConnector::renderTranslateQuerySql(connection = connection, - sql = "SELECT * FROM @include_source_concept_table;", - include_source_concept_table = "#inc_src_concepts", - oracleTempSchema = oracleTempSchema, - snakeCaseToCamelCase = TRUE) %>% + counts <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = "SELECT * FROM @include_source_concept_table;", + include_source_concept_table = "#inc_src_concepts", + tempEmulationSchema = tempEmulationSchema, + snakeCaseToCamelCase = TRUE + ) %>% tidyr::tibble() - counts <- counts %>% - dplyr::rename(uniqueConceptSetId = .data$conceptSetId) %>% - dplyr::inner_join(conceptSets %>% dplyr::select(.data$uniqueConceptSetId, - .data$cohortId, - .data$conceptSetId), - by = "uniqueConceptSetId") %>% - dplyr::select(-.data$uniqueConceptSetId) %>% - dplyr::mutate(databaseId = !!databaseId) %>% - dplyr::relocate(.data$databaseId, - .data$cohortId, - .data$conceptSetId, - .data$conceptId) %>% + counts <- counts %>% + dplyr::rename(uniqueConceptSetId = .data$conceptSetId) %>% + dplyr::inner_join( + conceptSets %>% dplyr::select( + .data$uniqueConceptSetId, + .data$cohortId, + .data$conceptSetId + ), + by = "uniqueConceptSetId" + ) %>% + dplyr::select(-.data$uniqueConceptSetId) %>% + dplyr::mutate(databaseId = !!databaseId) %>% + dplyr::relocate(.data$databaseId, + .data$cohortId, + .data$conceptSetId, + .data$conceptId) %>% dplyr::distinct() if (nrow(counts) > 0) { counts$databaseId <- databaseId - counts <- enforceMinCellValue(counts, "conceptSubjects", minCellCount) - counts <- enforceMinCellValue(counts, "conceptCount", minCellCount) + counts <- + enforceMinCellValue(counts, "conceptSubjects", minCellCount) + counts <- + enforceMinCellValue(counts, "conceptCount", minCellCount) } - writeToCsv(counts, - file.path(exportFolder, "included_source_concept.csv"), - incremental = incremental, - cohortId = subsetIncluded$cohortId) - recordTasksDone(cohortId = subsetIncluded$cohortId, - task = "runIncludedSourceConcepts", - checksum = subsetIncluded$checksum, - recordKeepingFile = recordKeepingFile, - incremental = incremental) + writeToCsv( + counts, + file.path(exportFolder, "included_source_concept.csv"), + incremental = incremental, + cohortId = subsetIncluded$cohortId + ) + recordTasksDone( + cohortId = subsetIncluded$cohortId, + task = "runIncludedSourceConcepts", + checksum = subsetIncluded$checksum, + recordKeepingFile = recordKeepingFile, + incremental = incremental + ) if (!is.null(conceptIdTable)) { sql <- "INSERT INTO @concept_id_table (concept_id) SELECT DISTINCT concept_id FROM @include_source_concept_table; - + INSERT INTO @concept_id_table (concept_id) SELECT DISTINCT source_concept_id FROM @include_source_concept_table;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - concept_id_table = conceptIdTable, - include_source_concept_table = "#inc_src_concepts", - progressBar = FALSE, - reportOverallTime = FALSE) + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + concept_id_table = conceptIdTable, + include_source_concept_table = "#inc_src_concepts", + progressBar = FALSE, + reportOverallTime = FALSE + ) } - sql <- "TRUNCATE TABLE @include_source_concept_table;\nDROP TABLE @include_source_concept_table;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - include_source_concept_table = "#inc_src_concepts", - progressBar = FALSE, - reportOverallTime = FALSE) + sql <- + "TRUNCATE TABLE @include_source_concept_table;\nDROP TABLE @include_source_concept_table;" + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + include_source_concept_table = "#inc_src_concepts", + progressBar = FALSE, + reportOverallTime = FALSE + ) delta <- Sys.time() - start - ParallelLogger::logInfo(paste("Finding source codes took", signif(delta, 3), attr(delta, "units"))) + ParallelLogger::logInfo(paste( + "Finding source codes took", + signif(delta, 3), + attr(delta, "units") + )) } } } @@ -489,114 +586,176 @@ runConceptSetDiagnostics <- function(connection, if (runBreakdownIndexEvents) { # Index event breakdown -------------------------------------------------------------------------- ParallelLogger::logInfo("Breaking down index events") - if (incremental && (nrow(cohorts) - nrow(subsetBreakdown)) > 0) { - ParallelLogger::logInfo(sprintf("Skipping %s cohorts in incremental mode.", - nrow(cohorts) - nrow(subsetBreakdown))) + if (incremental && + (nrow(cohorts) - nrow(subsetBreakdown)) > 0) { + ParallelLogger::logInfo(sprintf( + "Skipping %s cohorts in incremental mode.", + nrow(cohorts) - nrow(subsetBreakdown) + )) } if (nrow(subsetBreakdown) > 0) { start <- Sys.time() - domains <- readr::read_csv(system.file("csv", "domains.csv", package = "CohortDiagnostics"), - col_types = readr::cols(), - guess_max = min(1e7)) + domains <- + readr::read_csv( + system.file("csv", "domains.csv", package = "CohortDiagnostics"), + col_types = readr::cols(), + guess_max = min(1e7) + ) runBreakdownIndexEvents <- function(cohort) { - ParallelLogger::logInfo("- Breaking down index events for cohort '", cohort$cohortName, "'") + ParallelLogger::logInfo("- Breaking down index events for cohort '", + cohort$cohortName, + "'") - cohortDefinition <- RJSONIO::fromJSON(cohort$json) - primaryCodesetIds <- lapply(cohortDefinition$PrimaryCriteria$CriteriaList, getCodeSetIds) %>% - dplyr::bind_rows() + cohortDefinition <- + RJSONIO::fromJSON(cohort$json, digits = 23) + primaryCodesetIds <- + lapply(cohortDefinition$PrimaryCriteria$CriteriaList, + getCodeSetIds) %>% + dplyr::bind_rows() + if (nrow(primaryCodesetIds) == 0) { + warning("No primary event criteria concept sets found for cohort id: ", + cohort$cohortId) + return(tidyr::tibble()) + } + primaryCodesetIds <- primaryCodesetIds %>% dplyr::filter(.data$domain %in% + c(domains$domain %>% unique())) if (nrow(primaryCodesetIds) == 0) { - warning("No primary event criteria concept sets found for cohort id: ", cohort$cohortId) + warning("Primary event criteria concept sets found for cohort id: ", + cohort$cohortId, " but,", "\nnone of the concept sets belong to the supported domains.", + "\nThe supported domains are:\n", paste(domains$domain, + collapse = ", ")) return(tidyr::tibble()) } primaryCodesetIds <- conceptSets %>% - dplyr::filter(.data$cohortId == cohort$cohortId) %>% + dplyr::filter(.data$cohortId %in% cohort$cohortId) %>% dplyr::select(codeSetIds = .data$conceptSetId, .data$uniqueConceptSetId) %>% dplyr::inner_join(primaryCodesetIds, by = "codeSetIds") pasteIds <- function(row) { - return(dplyr::tibble(domain = row$domain[1], - uniqueConceptSetId = paste(row$uniqueConceptSetId, collapse = ", "))) + return(dplyr::tibble( + domain = row$domain[1], + uniqueConceptSetId = paste(row$uniqueConceptSetId, collapse = ", ") + )) } - primaryCodesetIds <- lapply(split(primaryCodesetIds, primaryCodesetIds$domain), pasteIds) + primaryCodesetIds <- + lapply(split(primaryCodesetIds, primaryCodesetIds$domain), + pasteIds) primaryCodesetIds <- dplyr::bind_rows(primaryCodesetIds) getCounts <- function(row) { - domain <- domains[domains$domain == row$domain, ] - sql <- SqlRender::loadRenderTranslateSql("CohortEntryBreakdown.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - oracleTempSchema = oracleTempSchema, - cdm_database_schema = cdmDatabaseSchema, - cohort_database_schema = cohortDatabaseSchema, - cohort_table = cohortTable, - cohort_id = cohort$cohortId, - domain_table = domain$domainTable, - domain_start_date = domain$domainStartDate, - domain_concept_id = domain$domainConceptId, - primary_codeset_ids = row$uniqueConceptSetId, - concept_set_table = "#inst_concept_sets", - store = TRUE, - store_table = "#breakdown") - DatabaseConnector::executeSql(connection = connection, - sql = sql, - progressBar = FALSE, - reportOverallTime = FALSE) + domain <- domains[domains$domain == row$domain,] + sql <- + SqlRender::loadRenderTranslateSql( + "CohortEntryBreakdown.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + tempEmulationSchema = tempEmulationSchema, + cdm_database_schema = cdmDatabaseSchema, + vocabulary_database_schema = vocabularyDatabaseSchema, + cohort_database_schema = cohortDatabaseSchema, + cohort_table = cohortTable, + cohort_id = cohort$cohortId, + domain_table = domain$domainTable, + domain_start_date = domain$domainStartDate, + domain_concept_id = domain$domainConceptId, + domain_source_concept_id = domain$domainSourceConceptId, + use_source_concept_id = !is.null(domain$domainSourceConceptId), + primary_codeset_ids = row$uniqueConceptSetId, + concept_set_table = "#inst_concept_sets", + store = TRUE, + store_table = "#breakdown" + ) + + DatabaseConnector::executeSql( + connection = connection, + sql = sql, + progressBar = FALSE, + reportOverallTime = FALSE + ) sql <- "SELECT * FROM @store_table;" - counts <- DatabaseConnector::renderTranslateQuerySql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - store_table = "#breakdown", - snakeCaseToCamelCase = TRUE) %>% + counts <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + store_table = "#breakdown", + snakeCaseToCamelCase = TRUE + ) %>% tidyr::tibble() if (!is.null(conceptIdTable)) { sql <- "INSERT INTO @concept_id_table (concept_id) SELECT DISTINCT concept_id FROM @store_table;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - concept_id_table = conceptIdTable, - store_table = "#breakdown", - progressBar = FALSE, - reportOverallTime = FALSE) + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + concept_id_table = conceptIdTable, + store_table = "#breakdown", + progressBar = FALSE, + reportOverallTime = FALSE + ) } - sql <- "TRUNCATE TABLE @store_table;\nDROP TABLE @store_table;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - store_table = "#breakdown", - progressBar = FALSE, - reportOverallTime = FALSE) + sql <- + "TRUNCATE TABLE @store_table;\nDROP TABLE @store_table;" + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + store_table = "#breakdown", + progressBar = FALSE, + reportOverallTime = FALSE + ) return(counts) } - counts <- lapply(split(primaryCodesetIds, 1:nrow(primaryCodesetIds)), getCounts) %>% - dplyr::bind_rows() %>% + counts <- + lapply(split(primaryCodesetIds, 1:nrow(primaryCodesetIds)), getCounts) %>% + dplyr::bind_rows() %>% dplyr::arrange(.data$conceptCount) if (nrow(counts) > 0) { counts$cohortId <- cohort$cohortId + } else { + ParallelLogger::logInfo("Index event breakdown results were not returned for: ", + cohort$cohortId) + return(dplyr::tibble()) } return(counts) } - data <- lapply(split(subsetBreakdown, subsetBreakdown$cohortId), runBreakdownIndexEvents) + data <- + lapply(split(subsetBreakdown, subsetBreakdown$cohortId), + runBreakdownIndexEvents) data <- dplyr::bind_rows(data) if (nrow(data) > 0) { data <- data %>% dplyr::mutate(databaseId = !!databaseId) - data <- enforceMinCellValue(data, "conceptCount", minCellCount) + data <- + enforceMinCellValue(data, "conceptCount", minCellCount) + if ('subjectCount' %in% colnames(data)) { + data <- + enforceMinCellValue(data, "subjectCount", minCellCount) + } } - writeToCsv(data = data, - fileName = file.path(exportFolder, "index_event_breakdown.csv"), - incremental = incremental, - cohortId = subset$cohortId) - recordTasksDone(cohortId = subset$cohortId, - task = "runBreakdownIndexEvents", - checksum = subset$checksum, - recordKeepingFile = recordKeepingFile, - incremental = incremental) + writeToCsv( + data = data, + fileName = file.path(exportFolder, "index_event_breakdown.csv"), + incremental = incremental, + cohortId = subset$cohortId + ) + recordTasksDone( + cohortId = subset$cohortId, + task = "runBreakdownIndexEvents", + checksum = subset$checksum, + recordKeepingFile = recordKeepingFile, + incremental = incremental + ) delta <- Sys.time() - start - ParallelLogger::logInfo(paste("Breaking down index event took", signif(delta, 3), attr(delta, "units"))) + ParallelLogger::logInfo(paste( + "Breaking down index event took", + signif(delta, 3), + attr(delta, "units") + )) } } @@ -604,8 +763,10 @@ runConceptSetDiagnostics <- function(connection, # Orphan concepts --------------------------------------------------------- ParallelLogger::logInfo("Finding orphan concepts") if (incremental && (nrow(cohorts) - nrow(subsetOrphans)) > 0) { - ParallelLogger::logInfo(sprintf("Skipping %s cohorts in incremental mode.", - nrow(cohorts) - nrow(subsetOrphans))) + ParallelLogger::logInfo(sprintf( + "Skipping %s cohorts in incremental mode.", + nrow(cohorts) - nrow(subsetOrphans) + )) } if (nrow(subsetOrphans > 0)) { start <- Sys.time() @@ -618,97 +779,166 @@ runConceptSetDiagnostics <- function(connection, # [OPTIMIZATION idea] can we modify the sql to do this for all uniqueConceptSetId in one query using group by? data <- list() for (i in (1:nrow(uniqueConceptSets))) { - conceptSet <- uniqueConceptSets[i,] - ParallelLogger::logInfo("- Finding orphan concepts for concept set '", conceptSet$conceptSetName, "'") - data[[i]] <- .findOrphanConcepts(connection = connection, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - useCodesetTable = TRUE, - codesetId = conceptSet$uniqueConceptSetId, - conceptCountsDatabaseSchema = conceptCountsDatabaseSchema, - conceptCountsTable = conceptCountsTable, - conceptCountsTableIsTemp = conceptCountsTableIsTemp, - instantiatedCodeSets = "#inst_concept_sets", - orphanConceptTable = "#orphan_concepts") + conceptSet <- uniqueConceptSets[i, ] + ParallelLogger::logInfo("- Finding orphan concepts for concept set '", + conceptSet$conceptSetName, + "'") + data[[i]] <- .findOrphanConcepts( + connection = connection, + cdmDatabaseSchema = cdmDatabaseSchema, + tempEmulationSchema = tempEmulationSchema, + useCodesetTable = TRUE, + codesetId = conceptSet$uniqueConceptSetId, + conceptCountsDatabaseSchema = conceptCountsDatabaseSchema, + conceptCountsTable = conceptCountsTable, + conceptCountsTableIsTemp = conceptCountsTableIsTemp, + instantiatedCodeSets = "#inst_concept_sets", + orphanConceptTable = "#orphan_concepts" + ) if (!is.null(conceptIdTable)) { sql <- "INSERT INTO @concept_id_table (concept_id) SELECT DISTINCT concept_id FROM @orphan_concept_table;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - concept_id_table = conceptIdTable, - orphan_concept_table = "#orphan_concepts", - progressBar = FALSE, - reportOverallTime = FALSE) + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + concept_id_table = conceptIdTable, + orphan_concept_table = "#orphan_concepts", + progressBar = FALSE, + reportOverallTime = FALSE + ) } - sql <- "TRUNCATE TABLE @orphan_concept_table;\nDROP TABLE @orphan_concept_table;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - orphan_concept_table = "#orphan_concepts", - progressBar = FALSE, - reportOverallTime = FALSE) + sql <- + "TRUNCATE TABLE @orphan_concept_table;\nDROP TABLE @orphan_concept_table;" + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + orphan_concept_table = "#orphan_concepts", + progressBar = FALSE, + reportOverallTime = FALSE + ) } - data <- dplyr::bind_rows(data) %>% - dplyr::distinct() %>% - dplyr::rename(uniqueConceptSetId = .data$codesetId) %>% - dplyr::inner_join(conceptSets %>% - dplyr::select(.data$uniqueConceptSetId, - .data$cohortId, - .data$conceptSetId), - by = "uniqueConceptSetId") %>% - dplyr::select(-.data$uniqueConceptSetId) %>% - dplyr::mutate(databaseId = !!databaseId) %>% + data <- dplyr::bind_rows(data) %>% + dplyr::distinct() %>% + dplyr::rename(uniqueConceptSetId = .data$codesetId) %>% + dplyr::inner_join( + conceptSets %>% + dplyr::select( + .data$uniqueConceptSetId, + .data$cohortId, + .data$conceptSetId + ), + by = "uniqueConceptSetId" + ) %>% + dplyr::select(-.data$uniqueConceptSetId) %>% + dplyr::mutate(databaseId = !!databaseId) %>% dplyr::relocate(.data$cohortId, .data$conceptSetId, .data$databaseId) if (nrow(data) > 0) { data <- enforceMinCellValue(data, "conceptCount", minCellCount) - data <- enforceMinCellValue(data, "conceptSubjects", minCellCount) + data <- + enforceMinCellValue(data, "conceptSubjects", minCellCount) } - writeToCsv(data, + writeToCsv( + data, file.path(exportFolder, "orphan_concept.csv"), incremental = incremental, - cohortId = subsetOrphans$cohortId) + cohortId = subsetOrphans$cohortId + ) - recordTasksDone(cohortId = subsetOrphans$cohortId, + recordTasksDone( + cohortId = subsetOrphans$cohortId, task = "runOrphanConcepts", checksum = subsetOrphans$checksum, recordKeepingFile = recordKeepingFile, - incremental = incremental) + incremental = incremental + ) delta <- Sys.time() - start - ParallelLogger::logInfo("Finding orphan concepts took ", signif(delta, 3), " ", attr(delta, "units")) + ParallelLogger::logInfo("Finding orphan concepts took ", + signif(delta, 3), + " ", + attr(delta, "units")) } } + + # put all instantiated concepts into #concept_ids table + # this is extracted with vocabulary tables + # this will have more codes than included source concepts + # included source concepts is limited to resolved concept ids in source data + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = "INSERT INTO #concept_ids (concept_id) + SELECT DISTINCT concept_id + FROM #inst_concept_sets;", + tempEmulationSchema = tempEmulationSchema, + progressBar = FALSE, + reportOverallTime = FALSE + ) + + resolvedConceptIds <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = "SELECT * + FROM #inst_concept_sets;", + tempEmulationSchema = tempEmulationSchema, + snakeCaseToCamelCase = TRUE + ) %>% + dplyr::tibble() %>% + dplyr::rename(uniqueConceptSetId = .data$codesetId) %>% + dplyr::inner_join(conceptSets, + by = "uniqueConceptSetId") %>% + dplyr::select(.data$cohortId, + .data$conceptSetId, + .data$conceptId) %>% + dplyr::mutate(databaseId = !!databaseId) %>% + dplyr::distinct() + + writeToCsv( + resolvedConceptIds, + file.path(exportFolder, "resolved_concepts.csv"), + incremental = TRUE + ) + ParallelLogger::logTrace("Dropping temp concept set table") - sql <- "TRUNCATE TABLE #inst_concept_sets; DROP TABLE #inst_concept_sets;" - DatabaseConnector::renderTranslateExecuteSql(connection, - sql, - oracleTempSchema = oracleTempSchema, - progressBar = FALSE, - reportOverallTime = FALSE) + sql <- + "TRUNCATE TABLE #inst_concept_sets; DROP TABLE #inst_concept_sets;" + DatabaseConnector::renderTranslateExecuteSql( + connection, + sql, + tempEmulationSchema = tempEmulationSchema, + progressBar = FALSE, + reportOverallTime = FALSE + ) - if ((runIncludedSourceConcepts && nrow(subsetIncluded) > 0) || + if ((runIncludedSourceConcepts && nrow(subsetIncluded) > 0) || (runOrphanConcepts && nrow(subsetOrphans) > 0)) { ParallelLogger::logTrace("Dropping temp concept count table") if (conceptCountsTableIsTemp) { countTable <- conceptCountsTable } else { - countTable <- paste(conceptCountsDatabaseSchema, conceptCountsTable, sep = ".") + countTable <- + paste(conceptCountsDatabaseSchema, conceptCountsTable, sep = ".") } sql <- "TRUNCATE TABLE @count_table; DROP TABLE @count_table;" - DatabaseConnector::renderTranslateExecuteSql(connection, - sql, - oracleTempSchema = oracleTempSchema, - count_table = countTable, - progressBar = FALSE, - reportOverallTime = FALSE) + DatabaseConnector::renderTranslateExecuteSql( + connection, + sql, + tempEmulationSchema = tempEmulationSchema, + count_table = countTable, + progressBar = FALSE, + reportOverallTime = FALSE + ) } delta <- Sys.time() - startConceptSetDiagnostics - ParallelLogger::logInfo("Running concept set diagnostics took ", signif(delta, 3), " ", attr(delta, "units")) + ParallelLogger::logInfo("Running concept set diagnostics took ", + signif(delta, 3), + " ", + attr(delta, "units")) } diff --git a/R/ExportCharacterization.R b/R/ExportCharacterization.R new file mode 100644 index 000000000..2b25f81bc --- /dev/null +++ b/R/ExportCharacterization.R @@ -0,0 +1,114 @@ +# Copyright 2021 Observational Health Data Sciences and Informatics +# +# This file is part of CohortDiagnostics +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +exportCharacterization <- function(characteristics, + databaseId, + incremental, + covariateValueFileName, + covariateValueContFileName, + covariateRefFileName, + analysisRefFileName, + timeRefFileName = NULL, + counts, + cutOff = 0.0001, + minCellCount) { + minCellCount <- minCellCount # to avoid warning on OhdsiRTools::checkUsagePackage("CohortDiagnostics") + if (!"covariates" %in% names(characteristics)) { + warning("No characterization output for submitted cohorts") + } else if (dplyr::pull(dplyr::count(characteristics$covariateRef)) > 0) { + characteristics$filteredCovariates <- + characteristics$covariates %>% + dplyr::filter(mean >= cutOff) %>% + dplyr::mutate(databaseId = !!databaseId) %>% + dplyr::left_join(counts, + by = c("cohortId", "databaseId"), + copy = TRUE) %>% + dplyr::mutate( + mean = dplyr::case_when( + .data$mean != 0 & + .data$mean < !!minCellCount / .data$cohortEntries ~ -!!minCellCount / .data$cohortEntries, + TRUE ~ .data$mean + ) + ) %>% + dplyr::mutate(sd = dplyr::case_when(.data$mean >= 0 ~ sd)) %>% + dplyr::mutate(mean = round(.data$mean, digits = 4), + sd = round(.data$sd, digits = 4)) %>% + dplyr::select(-.data$cohortEntries, -.data$cohortSubjects) + + if (dplyr::pull(dplyr::count(characteristics$filteredCovariates)) > 0) { + covariateRef <- dplyr::collect(characteristics$covariateRef) + writeToCsv( + data = covariateRef, + fileName = covariateRefFileName, + incremental = incremental, + covariateId = covariateRef$covariateId + ) + analysisRef <- dplyr::collect(characteristics$analysisRef) + writeToCsv( + data = analysisRef, + fileName = analysisRefFileName, + incremental = incremental, + analysisId = analysisRef$analysisId + ) + if (!is.null(timeRefFileName)) { + timeRef <- dplyr::collect(characteristics$timeRef) + writeToCsv( + data = timeRef, + fileName = timeRefFileName, + incremental = incremental, + analysisId = timeRef$timeId + ) + } + writeCovariateDataAndromedaToCsv( + data = characteristics$filteredCovariates, + fileName = covariateValueFileName, + incremental = incremental + ) + } + } + + if (!"covariatesContinuous" %in% names(characteristics)) { + ParallelLogger::logInfo("No continuous characterization output for submitted cohorts") + } else if (dplyr::pull(dplyr::count(characteristics$covariateRef)) > 0) { + characteristics$filteredCovariatesContinous <- + characteristics$covariatesContinuous %>% + # dplyr::filter(mean >= cutOff) %>% + dplyr::mutate(databaseId = !!databaseId) %>% + dplyr::left_join(counts, + by = c("cohortId", "databaseId"), + copy = TRUE) %>% + dplyr::mutate( + mean = dplyr::case_when( + .data$mean != 0 & + .data$mean < !!minCellCount / .data$cohortEntries ~ -!!minCellCount / .data$cohortEntries, + TRUE ~ .data$mean + ) + ) %>% + dplyr::mutate(sd = dplyr::case_when(.data$mean >= 0 ~ sd)) %>% + # dplyr::mutate(mean = round(.data$mean, digits = 4), + # sd = round(.data$sd, digits = 4)) %>% + dplyr::select(-.data$cohortEntries, -.data$cohortSubjects) + + if (dplyr::pull(dplyr::count(characteristics$filteredCovariatesContinous)) > 0) { + writeCovariateDataAndromedaToCsv( + data = characteristics$filteredCovariatesContinous, + fileName = covariateValueContFileName, + incremental = incremental + ) + } + } +} diff --git a/R/IncidenceRates.R b/R/IncidenceRates.R index ed918acaf..2ecedd435 100644 --- a/R/IncidenceRates.R +++ b/R/IncidenceRates.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,8 +19,9 @@ getIncidenceRate <- function(connectionDetails = NULL, cohortDatabaseSchema, cohortTable, cdmDatabaseSchema, + vocabularyDatabaseSchema = cdmDatabaseSchema, cdmVersion = 5, - oracleTempSchema = oracleTempSchema, + tempEmulationSchema = tempEmulationSchema, firstOccurrenceOnly = TRUE, washoutPeriod = 365, cohortId) { @@ -34,103 +35,161 @@ getIncidenceRate <- function(connectionDetails = NULL, on.exit(DatabaseConnector::disconnect(connection)) } - if (!checkIfCohortInstantiated(connection = connection, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortId = cohortId)) { - warning("Cohort with ID ", cohortId, " appears to be empty. Was it instantiated? Skipping incidence rate computation.") + if (!checkIfCohortInstantiated( + connection = connection, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cohortId = cohortId + )) { + warning( + "Cohort with ID ", + cohortId, + " appears to be empty. Was it instantiated? Skipping incidence rate computation." + ) delta <- Sys.time() - start - ParallelLogger::logInfo(paste("Computing incidence rates took", - signif(delta, 3), - attr(delta, "units"))) + ParallelLogger::logInfo(paste( + "Computing incidence rates took", + signif(delta, 3), + attr(delta, "units") + )) return(tidyr::tibble()) } ParallelLogger::logInfo("Calculating incidence rate per year by age and gender") - sql <- SqlRender::loadRenderTranslateSql(sqlFilename = "GetCalendarYearRange.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - cdm_database_schema = cdmDatabaseSchema) - yearRange <- DatabaseConnector::querySql(connection, sql, snakeCaseToCamelCase = TRUE) - # Temporarily using data.frame instead of tibble, until DatabaseConnector is fixed (see https://github.com/OHDSI/DatabaseConnector/issues/127) - calendarYears <- data.frame(calendarYear = seq(yearRange$startYear, yearRange$endYear, by = 1)) - DatabaseConnector::insertTable(connection = connection, - tableName = "#calendar_years", - data = calendarYears, - dropTableIfExists = TRUE, - createTable = TRUE, - tempTable = TRUE, - oracleTempSchema = oracleTempSchema, - camelCaseToSnakeCase = TRUE) + sql <- + SqlRender::loadRenderTranslateSql( + sqlFilename = "GetCalendarYearRange.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + cdm_database_schema = cdmDatabaseSchema + ) + yearRange <- + DatabaseConnector::querySql(connection, sql, snakeCaseToCamelCase = TRUE) + + calendarYears <- + dplyr::tibble(calendarYear = seq(yearRange$startYear, yearRange$endYear, by = 1)) + DatabaseConnector::insertTable( + connection = connection, + tableName = "#calendar_years", + data = calendarYears, + dropTableIfExists = TRUE, + createTable = TRUE, + tempTable = TRUE, + tempEmulationSchema = tempEmulationSchema, + camelCaseToSnakeCase = TRUE + ) - sql <- SqlRender::loadRenderTranslateSql(sqlFilename = "ComputeIncidenceRates.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - oracleTempSchema = oracleTempSchema, - cohort_database_schema = cohortDatabaseSchema, - cohort_table = cohortTable, - cdm_database_schema = cdmDatabaseSchema, - first_occurrence_only = firstOccurrenceOnly, - washout_period = washoutPeriod, - cohort_id = cohortId) + sql <- + SqlRender::loadRenderTranslateSql( + sqlFilename = "ComputeIncidenceRates.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + tempEmulationSchema = tempEmulationSchema, + cohort_database_schema = cohortDatabaseSchema, + cohort_table = cohortTable, + cdm_database_schema = cdmDatabaseSchema, + vocabulary_database_schema = vocabularyDatabaseSchema, + first_occurrence_only = firstOccurrenceOnly, + washout_period = washoutPeriod, + cohort_id = cohortId + ) DatabaseConnector::executeSql(connection, sql) sql <- "SELECT * FROM #rates_summary;" - ratesSummary <- DatabaseConnector::renderTranslateQuerySql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - snakeCaseToCamelCase = TRUE) %>% + ratesSummary <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + snakeCaseToCamelCase = TRUE + ) %>% tidyr::tibble() sql <- "TRUNCATE TABLE #rates_summary; DROP TABLE #rates_summary;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - progressBar = FALSE, - reportOverallTime = FALSE, - oracleTempSchema = oracleTempSchema) + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + progressBar = FALSE, + reportOverallTime = FALSE, + tempEmulationSchema = tempEmulationSchema + ) irYearAgeGender <- recode(ratesSummary) - irOverall <- tidyr::tibble(cohortCount = sum(irYearAgeGender$cohortCount), - personYears = sum(irYearAgeGender$personYears)) - irGender <- aggregateIr(irYearAgeGender, list(gender = irYearAgeGender$gender)) - irAge <- aggregateIr(irYearAgeGender, list(ageGroup = irYearAgeGender$ageGroup)) - irAgeGender <- aggregateIr(irYearAgeGender, list(ageGroup = irYearAgeGender$ageGroup, - gender = irYearAgeGender$gender)) - irYear <- aggregateIr(irYearAgeGender, list(calendarYear = irYearAgeGender$calendarYear)) - irYearAge <- aggregateIr(irYearAgeGender, list(calendarYear = irYearAgeGender$calendarYear, - ageGroup = irYearAgeGender$ageGroup)) - irYearGender <- aggregateIr(irYearAgeGender, list(calendarYear = irYearAgeGender$calendarYear, - gender = irYearAgeGender$gender)) - result <- dplyr::bind_rows(irOverall, - irGender, - irAge, - irAgeGender, - irYear, - irYearAge, - irYearGender, - irYearAgeGender) - result$incidenceRate <- 1000 * result$cohortCount/result$personYears + irOverall <- + tidyr::tibble( + cohortCount = sum(irYearAgeGender$cohortCount), + personYears = sum(irYearAgeGender$personYears) + ) + irGender <- + aggregateIr(irYearAgeGender, list(gender = irYearAgeGender$gender)) + irAge <- + aggregateIr(irYearAgeGender, list(ageGroup = irYearAgeGender$ageGroup)) + irAgeGender <- + aggregateIr( + irYearAgeGender, + list(ageGroup = irYearAgeGender$ageGroup, + gender = irYearAgeGender$gender) + ) + irYear <- + aggregateIr(irYearAgeGender, + list(calendarYear = irYearAgeGender$calendarYear)) + irYearAge <- + aggregateIr( + irYearAgeGender, + list( + calendarYear = irYearAgeGender$calendarYear, + ageGroup = irYearAgeGender$ageGroup + ) + ) + irYearGender <- + aggregateIr( + irYearAgeGender, + list( + calendarYear = irYearAgeGender$calendarYear, + gender = irYearAgeGender$gender + ) + ) + result <- dplyr::bind_rows( + irOverall, + irGender, + irAge, + irAgeGender, + irYear, + irYearAge, + irYearGender, + irYearAgeGender + ) + result$incidenceRate <- + 1000 * result$cohortCount / result$personYears result$incidenceRate[is.nan(result$incidenceRate)] <- 0 delta <- Sys.time() - start - ParallelLogger::logInfo(paste("Computing incidence rates took", - signif(delta, 3), - attr(delta, "units"))) + ParallelLogger::logInfo(paste( + "Computing incidence rates took", + signif(delta, 3), + attr(delta, "units") + )) return(result) } recode <- function(ratesSummary) { - ratesSummary$ageGroup <- paste(10 * ratesSummary$ageGroup, 10 * ratesSummary$ageGroup + 9, sep = "-") + ratesSummary$ageGroup <- + paste(10 * ratesSummary$ageGroup, 10 * ratesSummary$ageGroup + 9, sep = "-") ratesSummary$gender <- tolower(ratesSummary$gender) - substr(ratesSummary$gender, 1, 1) <- toupper(substr(ratesSummary$gender, 1, 1) ) + substr(ratesSummary$gender, 1, 1) <- + toupper(substr(ratesSummary$gender, 1, 1)) return(tidyr::tibble(ratesSummary)) } aggregateIr <- function(ratesSummary, aggregateList) { if (nrow(ratesSummary) > 0) { - return(aggregate(cbind(cohortCount = ratesSummary$cohortCount, - personYears = ratesSummary$personYears), - by = aggregateList, - FUN = sum)) + return(aggregate( + cbind( + cohortCount = ratesSummary$cohortCount, + personYears = ratesSummary$personYears + ), + by = aggregateList, + FUN = sum + )) } else { return(tidyr::tibble()) } diff --git a/R/Incremental.R b/R/Incremental.R index f7f64623b..20859fd42 100644 --- a/R/Incremental.R +++ b/R/Incremental.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,41 +15,53 @@ # limitations under the License. computeChecksum <- function(column) { - return(sapply(as.character(column), digest::digest, algo = "md5", serialize = FALSE)) + return(sapply( + as.character(column), + digest::digest, + algo = "md5", + serialize = FALSE + )) } -isTaskRequired <- function(..., checksum, recordKeepingFile, verbose = TRUE) { - if (file.exists(recordKeepingFile)) { - recordKeeping <- readr::read_csv(recordKeepingFile, - col_types = readr::cols(), - guess_max = min(1e7)) - task <- recordKeeping[getKeyIndex(list(...), recordKeeping), ] - if (nrow(task) == 0) { - return(TRUE) - } - if (nrow(task) > 1) { - stop("Duplicate key ", as.character(list(...)), " found in recordkeeping table") - } - if (task$checksum == checksum) { - if (verbose) { - key <- list(...) - key <- paste(sprintf("%s = '%s'", names(key), key), collapse = ", ") - ParallelLogger::logInfo("Skipping ", key, " because unchanged from earlier run") +isTaskRequired <- + function(..., + checksum, + recordKeepingFile, + verbose = TRUE) { + if (file.exists(recordKeepingFile)) { + recordKeeping <- readr::read_csv(recordKeepingFile, + col_types = readr::cols(), + guess_max = min(1e7)) + task <- recordKeeping[getKeyIndex(list(...), recordKeeping),] + if (nrow(task) == 0) { + return(TRUE) + } + if (nrow(task) > 1) { + stop("Duplicate key ", + as.character(list(...)), + " found in recordkeeping table") + } + if (task$checksum == checksum) { + if (verbose) { + key <- list(...) + key <- + paste(sprintf("%s = '%s'", names(key), key), collapse = ", ") + ParallelLogger::logInfo("Skipping ", key, " because unchanged from earlier run") + } + return(FALSE) + } else { + return(TRUE) } - return(FALSE) } else { return(TRUE) } - } else { - return(TRUE) } -} getRequiredTasks <- function(..., checksum, recordKeepingFile) { tasks <- list(...) if (file.exists(recordKeepingFile) && length(tasks[[1]]) > 0) { - recordKeeping <- readr::read_csv(recordKeepingFile, - col_types = readr::cols(), + recordKeeping <- readr::read_csv(recordKeepingFile, + col_types = readr::cols(), guess_max = min(1e7)) tasks$checksum <- checksum tasks <- dplyr::as_tibble(tasks) @@ -62,14 +74,16 @@ getRequiredTasks <- function(..., checksum, recordKeepingFile) { if (length(idx) > 0) { # text <- paste(sprintf("%s = %s", names(tasks), tasks[idx,]), collapse = ", ") # ParallelLogger::logInfo("Skipping ", text, " because unchanged from earlier run") - tasks <- tasks[-idx, ] + tasks <- tasks[-idx,] } } return(tasks) } getKeyIndex <- function(key, recordKeeping) { - if (nrow(recordKeeping) == 0 || length(key[[1]]) == 0 || !all(names(key) %in% names(recordKeeping))) { + if (nrow(recordKeeping) == 0 || + length(key[[1]]) == 0 || + !all(names(key) %in% names(recordKeeping))) { return(c()) } else { key <- dplyr::as_tibble(key) %>% dplyr::distinct() @@ -79,39 +93,43 @@ getKeyIndex <- function(key, recordKeeping) { } } -recordTasksDone <- function(..., checksum, recordKeepingFile, incremental = TRUE) { - if (!incremental) { - return() - } - if (length(list(...)[[1]]) == 0) { - return() - } - if (file.exists(recordKeepingFile)) { - recordKeeping <- readr::read_csv(recordKeepingFile, - col_types = readr::cols(), - guess_max = min(1e7)) - recordKeeping$timeStamp <- as.character(recordKeeping$timeStamp) - if ('cohortId' %in% colnames(recordKeeping)) { - recordKeeping <- recordKeeping %>% - dplyr::mutate(cohortId = as.double(.data$cohortId)) +recordTasksDone <- + function(..., + checksum, + recordKeepingFile, + incremental = TRUE) { + if (!incremental) { + return() } - if ('comparatorId' %in% colnames(recordKeeping)) { - recordKeeping <- recordKeeping %>% - dplyr::mutate(comparatorId = as.double(.data$comparatorId)) + if (length(list(...)[[1]]) == 0) { + return() } - idx <- getKeyIndex(list(...), recordKeeping) - if (length(idx) > 0) { - recordKeeping <- recordKeeping[-idx, ] + if (file.exists(recordKeepingFile)) { + recordKeeping <- readr::read_csv(recordKeepingFile, + col_types = readr::cols(), + guess_max = min(1e7)) + recordKeeping$timeStamp <- as.character(recordKeeping$timeStamp) + if ('cohortId' %in% colnames(recordKeeping)) { + recordKeeping <- recordKeeping %>% + dplyr::mutate(cohortId = as.double(.data$cohortId)) + } + if ('comparatorId' %in% colnames(recordKeeping)) { + recordKeeping <- recordKeeping %>% + dplyr::mutate(comparatorId = as.double(.data$comparatorId)) + } + idx <- getKeyIndex(list(...), recordKeeping) + if (length(idx) > 0) { + recordKeeping <- recordKeeping[-idx,] + } + } else { + recordKeeping <- dplyr::tibble() } - } else { - recordKeeping <- dplyr::tibble() + newRow <- dplyr::as_tibble(list(...)) + newRow$checksum <- checksum + newRow$timeStamp <- as.character(Sys.time()) + recordKeeping <- dplyr::bind_rows(recordKeeping, newRow) + readr::write_csv(recordKeeping, recordKeepingFile) } - newRow <- dplyr::as_tibble(list(...)) - newRow$checksum <- checksum - newRow$timeStamp <- as.character(Sys.time()) - recordKeeping <- dplyr::bind_rows(recordKeeping, newRow) - readr::write_csv(recordKeeping, recordKeepingFile) -} writeToCsv <- function(data, fileName, incremental = FALSE, ...) { colnames(data) <- SqlRender::camelCaseToSnakeCase(colnames(data)) @@ -124,65 +142,74 @@ writeToCsv <- function(data, fileName, incremental = FALSE, ...) { ParallelLogger::logDebug("appending records to ", fileName) } else { if (file.exists(fileName)) { - ParallelLogger::logDebug("Overwriting and replacing previous ",fileName, " with new.") + ParallelLogger::logDebug("Overwriting and replacing previous ", + fileName, + " with new.") } else { - ParallelLogger::logDebug("creating ",fileName) + ParallelLogger::logDebug("creating ", fileName) } - readr::write_excel_csv(x = data, - file = fileName, - na = "", - append = FALSE, - delim = ",") + readr::write_excel_csv( + x = data, + file = fileName, + na = "", + append = FALSE, + delim = "," + ) } } -writeCovariateDataAndromedaToCsv <- function(data, fileName, incremental = FALSE) { - if (incremental && file.exists(fileName)) { - ParallelLogger::logDebug("Appending records to ", fileName) - batchSize <- 1e5 - - cohortIds <- data %>% - distinct(.data$cohortId) %>% - pull() - - tempName <- paste0(fileName, "2") - - processChunk <- function(chunk, pos) { - chunk <- chunk %>% - filter(!.data$cohort_id %in% cohortIds) - readr::write_csv(chunk, tempName, append = (pos != 1)) - } - - readr::read_csv_chunked(file = fileName, - callback = processChunk, - chunk_size = batchSize, - col_types = readr::cols(), - guess_max = batchSize) - - addChunk <- function(chunk) { - colnames(chunk) <- SqlRender::camelCaseToSnakeCase(colnames(chunk)) - readr::write_csv(chunk, tempName, append = TRUE) - } - Andromeda::batchApply(data, addChunk) - unlink(fileName) - file.rename(tempName, fileName) - } else { - if (file.exists(fileName)) { - ParallelLogger::logDebug("Overwriting and replacing previous ",fileName, " with new.") +writeCovariateDataAndromedaToCsv <- + function(data, fileName, incremental = FALSE) { + if (incremental && file.exists(fileName)) { + ParallelLogger::logDebug("Appending records to ", fileName) + batchSize <- 1e5 + + cohortIds <- data %>% + distinct(.data$cohortId) %>% + pull() + + tempName <- paste0(fileName, "2") + + processChunk <- function(chunk, pos) { + chunk <- chunk %>% + filter(!.data$cohort_id %in% cohortIds) + readr::write_csv(chunk, tempName, append = (pos != 1)) + } + + readr::read_csv_chunked( + file = fileName, + callback = processChunk, + chunk_size = batchSize, + col_types = readr::cols(), + guess_max = batchSize + ) + + addChunk <- function(chunk) { + colnames(chunk) <- SqlRender::camelCaseToSnakeCase(colnames(chunk)) + readr::write_csv(chunk, tempName, append = TRUE) + } + Andromeda::batchApply(data, addChunk) unlink(fileName) + file.rename(tempName, fileName) } else { - ParallelLogger::logDebug("Creating ",fileName) - } - writeToFile <- function(batch) { - first <- !file.exists(fileName) - if (first) { - colnames(batch) <- SqlRender::camelCaseToSnakeCase(colnames(batch)) + if (file.exists(fileName)) { + ParallelLogger::logDebug("Overwriting and replacing previous ", + fileName, + " with new.") + unlink(fileName) + } else { + ParallelLogger::logDebug("Creating ", fileName) } - readr::write_csv(batch, fileName, append = !first) + writeToFile <- function(batch) { + first <- !file.exists(fileName) + if (first) { + colnames(batch) <- SqlRender::camelCaseToSnakeCase(colnames(batch)) + } + readr::write_csv(batch, fileName, append = !first) + } + Andromeda::batchApply(data, writeToFile) } - Andromeda::batchApply(data, writeToFile) } -} saveIncremental <- function(data, fileName, ...) { if (!length(list(...)) == 0) { @@ -191,7 +218,7 @@ saveIncremental <- function(data, fileName, ...) { } } if (file.exists(fileName)) { - previousData <- readr::read_csv(fileName, + previousData <- readr::read_csv(fileName, col_types = readr::cols(), guess_max = min(1e7)) if ((nrow(previousData)) > 0) { @@ -201,42 +228,60 @@ saveIncremental <- function(data, fileName, ...) { idx <- NULL } if (length(idx) > 0) { - previousData <- previousData[-idx, ] + previousData <- previousData[-idx,] } if (nrow(previousData) > 0) { - data <- dplyr::bind_rows(previousData, data) %>% - dplyr::distinct() %>% + data <- dplyr::bind_rows(previousData, data) %>% + dplyr::distinct() %>% tidyr::tibble() } else { data <- data %>% tidyr::tibble() } } - } + } readr::write_csv(data, fileName) } -subsetToRequiredCohorts <- function(cohorts, task, incremental, recordKeepingFile) { - if (incremental) { - tasks <- getRequiredTasks(cohortId = cohorts$cohortId, - task = task, - checksum = cohorts$checksum, - recordKeepingFile = recordKeepingFile) - return(cohorts[cohorts$cohortId %in% tasks$cohortId, ]) - } else { - return(cohorts) +subsetToRequiredCohorts <- + function(cohorts, + task, + incremental, + recordKeepingFile) { + if (incremental) { + tasks <- getRequiredTasks( + cohortId = cohorts$cohortId, + task = task, + checksum = cohorts$checksum, + recordKeepingFile = recordKeepingFile + ) + return(cohorts[cohorts$cohortId %in% tasks$cohortId,]) + } else { + return(cohorts) + } } -} -subsetToRequiredCombis <- function(combis, task, incremental, recordKeepingFile) { - if (incremental) { - tasks <- getRequiredTasks(cohortId = combis$targetCohortId, - comparatorId = combis$comparatorCohortId, - task = task, - checksum = combis$checksum, - recordKeepingFile = recordKeepingFile) - return(merge(combis, dplyr::tibble(targetCohortId = tasks$cohortId, comparatorCohortId = tasks$comparatorId))) - } else { - return(combis) +subsetToRequiredCombis <- + function(combis, + task, + incremental, + recordKeepingFile) { + if (incremental) { + tasks <- getRequiredTasks( + cohortId = combis$targetCohortId, + comparatorId = combis$comparatorCohortId, + task = task, + checksum = combis$checksum, + recordKeepingFile = recordKeepingFile + ) + return(merge( + combis, + dplyr::tibble( + targetCohortId = tasks$cohortId, + comparatorCohortId = tasks$comparatorId + ) + )) + } else { + return(combis) + } } -} diff --git a/R/MetaDataDiagnostics.R b/R/MetaDataDiagnostics.R index 8af8fd956..1df06bbac 100644 --- a/R/MetaDataDiagnostics.R +++ b/R/MetaDataDiagnostics.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,7 +17,8 @@ .findOrphanConcepts <- function(connectionDetails = NULL, connection = NULL, cdmDatabaseSchema, - oracleTempSchema = NULL, + vocabularyDatabaseSchema = cdmDatabaseSchema, + tempEmulationSchema = NULL, conceptIds = c(), useCodesetTable = FALSE, codesetId = 1, @@ -30,64 +31,74 @@ connection <- DatabaseConnector::connect(connectionDetails) on.exit(DatabaseConnector::disconnect(connection)) } - sql <- SqlRender::loadRenderTranslateSql("OrphanCodes.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - oracleTempSchema = oracleTempSchema, - cdm_database_schema = cdmDatabaseSchema, - work_database_schema = conceptCountsDatabaseSchema, - concept_counts_table = conceptCountsTable, - concept_counts_table_is_temp = conceptCountsTableIsTemp, - concept_ids = conceptIds, - use_codesets_table = useCodesetTable, - orphan_concept_table = orphanConceptTable, - instantiated_code_sets = instantiatedCodeSets, - codeset_id = codesetId) + sql <- SqlRender::loadRenderTranslateSql( + "OrphanCodes.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + tempEmulationSchema = tempEmulationSchema, + vocabulary_database_schema = vocabularyDatabaseSchema, + work_database_schema = conceptCountsDatabaseSchema, + concept_counts_table = conceptCountsTable, + concept_counts_table_is_temp = conceptCountsTableIsTemp, + concept_ids = conceptIds, + use_codesets_table = useCodesetTable, + orphan_concept_table = orphanConceptTable, + instantiated_code_sets = instantiatedCodeSets, + codeset_id = codesetId + ) DatabaseConnector::executeSql(connection, sql) ParallelLogger::logTrace("- Fetching orphan concepts from server") sql <- "SELECT * FROM @orphan_concept_table;" - orphanConcepts <- DatabaseConnector::renderTranslateQuerySql(sql = sql, - connection = connection, - oracleTempSchema = oracleTempSchema, - orphan_concept_table = orphanConceptTable, - snakeCaseToCamelCase = TRUE) %>% + orphanConcepts <- + DatabaseConnector::renderTranslateQuerySql( + sql = sql, + connection = connection, + tempEmulationSchema = tempEmulationSchema, + orphan_concept_table = orphanConceptTable, + snakeCaseToCamelCase = TRUE + ) %>% tidyr::tibble() # For debugging: # x <- querySql(connection, "SELECT * FROM #starting_concepts;") # View(x) - # + # # x <- querySql(connection, "SELECT * FROM #concept_synonyms;") # View(x) - # + # # x <- querySql(connection, "SELECT * FROM #search_strings;") # View(x) - # + # # x <- querySql(connection, "SELECT * FROM #search_str_top1000;") # View(x) - # + # # x <- querySql(connection, "SELECT * FROM #search_string_subset;") # View(x) - # + # # x <- querySql(connection, "SELECT * FROM #recommended_concepts;") # View(x) ParallelLogger::logTrace("- Dropping orphan temp tables") - sql <- SqlRender::loadRenderTranslateSql("DropOrphanConceptTempTables.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - oracleTempSchema = oracleTempSchema) - DatabaseConnector::executeSql(connection = connection, - sql = sql, - progressBar = FALSE, - reportOverallTime = FALSE) + sql <- + SqlRender::loadRenderTranslateSql( + "DropOrphanConceptTempTables.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + tempEmulationSchema = tempEmulationSchema + ) + DatabaseConnector::executeSql( + connection = connection, + sql = sql, + progressBar = FALSE, + reportOverallTime = FALSE + ) return(orphanConcepts) } createConceptCountsTable <- function(connectionDetails = NULL, connection = NULL, cdmDatabaseSchema, - oracleTempSchema = NULL, + tempEmulationSchema = NULL, conceptCountsDatabaseSchema = cdmDatabaseSchema, conceptCountsTable = "concept_counts", conceptCountsTableIsTemp = FALSE) { @@ -96,13 +107,16 @@ createConceptCountsTable <- function(connectionDetails = NULL, connection <- DatabaseConnector::connect(connectionDetails) on.exit(DatabaseConnector::disconnect(connection)) } - sql <- SqlRender::loadRenderTranslateSql("CreateConceptCountTable.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - oracleTempSchema = oracleTempSchema, - cdm_database_schema = cdmDatabaseSchema, - work_database_schema = conceptCountsDatabaseSchema, - concept_counts_table = conceptCountsTable, - table_is_temp = conceptCountsTableIsTemp) + sql <- + SqlRender::loadRenderTranslateSql( + "CreateConceptCountTable.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + tempEmulationSchema = tempEmulationSchema, + cdm_database_schema = cdmDatabaseSchema, + work_database_schema = conceptCountsDatabaseSchema, + concept_counts_table = conceptCountsTable, + table_is_temp = conceptCountsTableIsTemp + ) DatabaseConnector::executeSql(connection, sql) } diff --git a/R/Private.R b/R/Private.R index 51e2fd0b3..956e6f43a 100644 --- a/R/Private.R +++ b/R/Private.R @@ -1,63 +1,107 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -createIfNotExist <- function(type, name, recursive = TRUE, errorMessage = NULL) { - if (is.null(errorMessage) | !class(errorMessage) == 'AssertColection') { - errorMessage <- checkmate::makeAssertCollection() - } - if (!is.null(type)) { - if (length(name) == 0) { - stop(ParallelLogger::logError("Must specify ", name)) +createIfNotExist <- + function(type, + name, + recursive = TRUE, + errorMessage = NULL) { + if (is.null(errorMessage) | + !class(errorMessage) == 'AssertColection') { + errorMessage <- checkmate::makeAssertCollection() } - if (type %in% c("folder")) { - if (!file.exists(gsub("/$", "", name))) { - dir.create(name, recursive = recursive) - ParallelLogger::logInfo("Created ", type, " at ", name) - } else { - # ParallelLogger::logInfo(type, " already exists at ", name) + if (!is.null(type)) { + if (length(name) == 0) { + stop(ParallelLogger::logError("Must specify ", name)) + } + if (type %in% c("folder")) { + if (!file.exists(gsub("/$", "", name))) { + dir.create(name, recursive = recursive) + ParallelLogger::logInfo("Created ", type, " at ", name) + } else { + # ParallelLogger::logInfo(type, " already exists at ", name) + } } + checkmate::assertDirectory(x = name, + access = 'x', + add = errorMessage) } - checkmate::assertDirectory(x = name, access = 'x', add = errorMessage) + invisible(errorMessage) } - invisible(errorMessage) -} -swapColumnContents <- function(df, column1 = "targetId", column2 = "comparatorId") { - temp <- df[, column1] - df[, column1] <- df[, column2] - df[, column2] <- temp - return(df) -} +swapColumnContents <- + function(df, + column1 = "targetId", + column2 = "comparatorId") { + temp <- df[, column1] + df[, column1] <- df[, column2] + df[, column2] <- temp + return(df) + } -enforceMinCellValue <- function(data, fieldName, minValues, silent = FALSE) { - toCensor <- !is.na(data[, fieldName]) & data[, fieldName] < minValues & data[, fieldName] != 0 - if (!silent) { - percent <- round(100 * sum(toCensor)/nrow(data), 1) - ParallelLogger::logInfo("- Censoring ", - sum(toCensor), - " values (", - percent, - "%) from ", - fieldName, - " because value below minimum") +enforceMinCellValue <- + function(data, fieldName, minValues, silent = FALSE) { + toCensor <- + !is.na(data[, fieldName]) & + data[, fieldName] < minValues & data[, fieldName] != 0 + if (!silent) { + percent <- round(100 * sum(toCensor) / nrow(data), 1) + ParallelLogger::logInfo( + "- Censoring ", + sum(toCensor), + " values (", + percent, + "%) from ", + fieldName, + " because value below minimum" + ) + } + if (length(minValues) == 1) { + data[toCensor, fieldName] <- -minValues + } else { + data[toCensor, fieldName] <- -minValues[toCensor] + } + return(data) } - if (length(minValues) == 1) { - data[toCensor, fieldName] <- -minValues - } else { - data[toCensor, fieldName] <- -minValues[toCensor] + + +#' Check character encoding of input file +#' +#' @description +#' For its input files, CohortDiagnostics only accepts UTF-8 or ASCII character encoding. This +#' function can be used to check whether a file meets these criteria. +#' +#' @param fileName The path to the file to check +#' +#' @return +#' Throws an error if the input file does not have the correct encoding. +#' +checkInputFileEncoding <- function(fileName) { + encoding <- readr::guess_encoding(file = fileName, n_max = min(1e7)) + + if (!encoding$encoding[1] %in% c("UTF-8", "ASCII")) { + stop( + "Illegal encoding found in file ", + basename(fileName), + ". Should be 'ASCII' or 'UTF-8', found:", + paste( + paste0(encoding$encoding, " (", encoding$confidence, ")"), + collapse = ", " + ) + ) } - return(data) + invisible(TRUE) } diff --git a/R/ResultsDataModel.R b/R/ResultsDataModel.R index f89aa29d9..9f9607093 100644 --- a/R/ResultsDataModel.R +++ b/R/ResultsDataModel.R @@ -1,146 +1,227 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# +# #' Get specifications for Cohort Diagnostics results data model -#' -#' @return +#' +#' @return #' A tibble data frame object with specifications -#' +#' #' @export getResultsDataModelSpecifications <- function() { - pathToCsv <- system.file("settings", "resultsDataModelSpecification.csv", package = "CohortDiagnostics") - resultsDataModelSpecifications <- readr::read_csv(file = pathToCsv, col_types = readr::cols()) + pathToCsv <- + system.file("settings", "resultsDataModelSpecification.csv", package = "CohortDiagnostics") + resultsDataModelSpecifications <- + readr::read_csv(file = pathToCsv, col_types = readr::cols()) return(resultsDataModelSpecifications) } -checkColumnNames <- function(table, tableName, zipFileName, specifications = getResultsDataModelSpecifications()) { - observeredNames <- colnames(table)[order(colnames(table))] - - tableSpecs <- specifications %>% - dplyr::filter(.data$tableName == !!tableName) - - optionalNames <- tableSpecs %>% - dplyr::filter(.data$optional == "Yes") %>% - dplyr::select(.data$fieldName) - - expectedNames <- tableSpecs %>% - dplyr::select(.data$fieldName) %>% - dplyr::anti_join(dplyr::filter(optionalNames, !.data$fieldName %in% observeredNames), by = "fieldName") %>% - dplyr::arrange(.data$fieldName) %>% - dplyr::pull() - - if (!isTRUE(all.equal(expectedNames, observeredNames))) { - stop(sprintf("Column names of table %s in zip file %s do not match specifications.\n- Observed columns: %s\n- Expected columns: %s", - tableName, - zipFileName, - paste(observeredNames, collapse = ", "), - paste(expectedNames, collapse = ", "))) - } -} - -checkAndFixDataTypes <- function(table, tableName, zipFileName, specifications = getResultsDataModelSpecifications()) { - tableSpecs <- specifications %>% - filter(.data$tableName == !!tableName) - - observedTypes <- sapply(table, class) - for (i in 1:length(observedTypes)) { - fieldName <- names(observedTypes)[i] - expectedType <- gsub("\\(.*\\)", "", tolower(tableSpecs$type[tableSpecs$fieldName == fieldName])) - if (expectedType == "bigint" || expectedType == "float") { - if (observedTypes[i] != "numeric" && observedTypes[i] != "double") { - ParallelLogger::logDebug(sprintf("Field %s in table %s in zip file %s is of type %s, but was expecting %s. Attempting to convert.", - fieldName, - tableName, - zipFileName, - observedTypes[i], - expectedType)) - table <- mutate_at(table, i, as.numeric) - } - } else if (expectedType == "int") { - if (observedTypes[i] != "integer") { - ParallelLogger::logDebug(sprintf("Field %s in table %s in zip file %s is of type %s, but was expecting %s. Attempting to convert.", - fieldName, - tableName, - zipFileName, - observedTypes[i], - expectedType)) - table <- mutate_at(table, i, as.integer) - } - } else if (expectedType == "varchar") { - if (observedTypes[i] != "character") { - ParallelLogger::logDebug(sprintf("Field %s in table %s in zip file %s is of type %s, but was expecting %s. Attempting to convert.", - fieldName, - tableName, - zipFileName, - observedTypes[i], - expectedType)) - table <- mutate_at(table, i, as.character) - } - } else if (expectedType == "date") { - if (observedTypes[i] != "Date") { - ParallelLogger::logDebug(sprintf("Field %s in table %s in zip file %s is of type %s, but was expecting %s. Attempting to convert.", - fieldName, - tableName, - zipFileName, - observedTypes[i], - expectedType)) - table <- mutate_at(table, i, as.Date) +fixTableMetadataForBackwardCompatibility <- function(table, tableName) { + if (tableName %in% c("cohort", "phenotype_description")) { + if (!'metadata' %in% colnames(table)) { + data <- list() + for (i in (1:nrow(table))) { + data[[i]] <- table[i,] + colnamesDf <- colnames(data[[i]]) + metaDataList <- list() + for (j in (1:length(colnamesDf))) { + metaDataList[[colnamesDf[[j]]]] = data[[i]][colnamesDf[[j]]] %>% dplyr::pull() + } + data[[i]]$metadata <- + RJSONIO::toJSON(metaDataList, pretty = TRUE, digits = 23) } + table <- dplyr::bind_rows(data) } - } + if ('referent_concept_id' %in% colnames(table)) { + table <- table %>% + dplyr::select(-.data$referent_concept_id) + } + } + if (tableName %in% c('covariate_value', 'temporal_covariate_value')) { + if (!'sum_value' %in% colnames(table)) { + table$sum_value <- -1 + } + } return(table) } -checkAndFixDuplicateRows <- function(table, tableName, zipFileName, specifications = getResultsDataModelSpecifications()) { - primaryKeys <- specifications %>% - dplyr::filter(.data$tableName == !!tableName & .data$primaryKey == "Yes") %>% - dplyr::select(.data$fieldName) %>% - dplyr::pull() - duplicatedRows <- duplicated(table[, primaryKeys]) - if (any(duplicatedRows)) { - warning(sprintf("Table %s in zip file %s has duplicate rows. Removing %s records.", - tableName, - zipFileName, - sum(duplicatedRows))) - return(table[!duplicatedRows, ]) - } else { +checkFixColumnNames <- + function(table, + tableName, + zipFileName, + specifications = getResultsDataModelSpecifications()) { + if (tableName %in% c('cohort', 'phenotype_description', + 'covariate_value', 'temporal_covariate_value')) { + table <- fixTableMetadataForBackwardCompatibility(table = table, + tableName = tableName) + } + observeredNames <- colnames(table)[order(colnames(table))] + + tableSpecs <- specifications %>% + dplyr::filter(.data$tableName == !!tableName) + + optionalNames <- tableSpecs %>% + dplyr::filter(.data$optional == "Yes") %>% + dplyr::select(.data$fieldName) + + expectedNames <- tableSpecs %>% + dplyr::select(.data$fieldName) %>% + dplyr::anti_join(dplyr::filter(optionalNames, !.data$fieldName %in% observeredNames), + by = "fieldName") %>% + dplyr::arrange(.data$fieldName) %>% + dplyr::pull() + + if (!isTRUE(all.equal(expectedNames, observeredNames))) { + stop( + sprintf( + "Column names of table %s in zip file %s do not match specifications.\n- Observed columns: %s\n- Expected columns: %s", + tableName, + zipFileName, + paste(observeredNames, collapse = ", "), + paste(expectedNames, collapse = ", ") + ) + ) + } + return(table) + } + +checkAndFixDataTypes <- + function(table, + tableName, + zipFileName, + specifications = getResultsDataModelSpecifications()) { + tableSpecs <- specifications %>% + filter(.data$tableName == !!tableName) + + observedTypes <- sapply(table, class) + for (i in 1:length(observedTypes)) { + fieldName <- names(observedTypes)[i] + expectedType <- + gsub("\\(.*\\)", "", tolower(tableSpecs$type[tableSpecs$fieldName == fieldName])) + if (expectedType == "bigint" || expectedType == "float") { + if (observedTypes[i] != "numeric" && observedTypes[i] != "double") { + ParallelLogger::logDebug( + sprintf( + "Field %s in table %s in zip file %s is of type %s, but was expecting %s. Attempting to convert.", + fieldName, + tableName, + zipFileName, + observedTypes[i], + expectedType + ) + ) + table <- mutate_at(table, i, as.numeric) + } + } else if (expectedType == "int") { + if (observedTypes[i] != "integer") { + ParallelLogger::logDebug( + sprintf( + "Field %s in table %s in zip file %s is of type %s, but was expecting %s. Attempting to convert.", + fieldName, + tableName, + zipFileName, + observedTypes[i], + expectedType + ) + ) + table <- mutate_at(table, i, as.integer) + } + } else if (expectedType == "varchar") { + if (observedTypes[i] != "character") { + ParallelLogger::logDebug( + sprintf( + "Field %s in table %s in zip file %s is of type %s, but was expecting %s. Attempting to convert.", + fieldName, + tableName, + zipFileName, + observedTypes[i], + expectedType + ) + ) + table <- mutate_at(table, i, as.character) + } + } else if (expectedType == "date") { + if (observedTypes[i] != "Date") { + ParallelLogger::logDebug( + sprintf( + "Field %s in table %s in zip file %s is of type %s, but was expecting %s. Attempting to convert.", + fieldName, + tableName, + zipFileName, + observedTypes[i], + expectedType + ) + ) + table <- mutate_at(table, i, as.Date) + } + } + } return(table) } -} -appendNewRows <- function(data, newData, tableName, specifications = getResultsDataModelSpecifications()) { - if (nrow(data) > 0) { +checkAndFixDuplicateRows <- + function(table, + tableName, + zipFileName, + specifications = getResultsDataModelSpecifications()) { primaryKeys <- specifications %>% - dplyr::filter(.data$tableName == !!tableName & .data$primaryKey == "Yes") %>% + dplyr::filter(.data$tableName == !!tableName & + .data$primaryKey == "Yes") %>% dplyr::select(.data$fieldName) %>% dplyr::pull() - newData <- newData %>% - dplyr::anti_join(data, by = primaryKeys) + duplicatedRows <- duplicated(table[, primaryKeys]) + if (any(duplicatedRows)) { + warning( + sprintf( + "Table %s in zip file %s has duplicate rows. Removing %s records.", + tableName, + zipFileName, + sum(duplicatedRows) + ) + ) + return(table[!duplicatedRows,]) + } else { + return(table) + } + } + +appendNewRows <- + function(data, + newData, + tableName, + specifications = getResultsDataModelSpecifications()) { + if (nrow(data) > 0) { + primaryKeys <- specifications %>% + dplyr::filter(.data$tableName == !!tableName & + .data$primaryKey == "Yes") %>% + dplyr::select(.data$fieldName) %>% + dplyr::pull() + newData <- newData %>% + dplyr::anti_join(data, by = primaryKeys) + } + return(dplyr::bind_rows(data, newData)) } - return(dplyr::bind_rows(data, newData)) -} #' Create the results data model tables on a database server. -#' -#' @details +#' +#' @details #' Only PostgreSQL servers are supported. #' -#' @template Connection +#' @template Connection #' @param schema The schema on the postgres server where the tables will be created. #' #' @export @@ -154,15 +235,31 @@ createResultsDataModel <- function(connection = NULL, } else { stop("No connection or connectionDetails provided.") } - } - schemas <- unlist(DatabaseConnector::querySql(connection, - "SELECT schema_name FROM information_schema.schemata;", - snakeCaseToCamelCase = TRUE)[, 1]) + } + schemas <- unlist( + DatabaseConnector::querySql( + connection, + "SELECT schema_name FROM information_schema.schemata;", + snakeCaseToCamelCase = TRUE + )[, 1] + ) if (!tolower(schema) %in% tolower(schemas)) { - stop("Schema '", schema, "' not found on database. Only found these schemas: '", paste(schemas, collapse = "', '"), "'") + stop( + "Schema '", + schema, + "' not found on database. Only found these schemas: '", + paste(schemas, collapse = "', '"), + "'" + ) } - DatabaseConnector::executeSql(connection, sprintf("SET search_path TO %s;", schema), progressBar = FALSE, reportOverallTime = FALSE) - pathToSql <- system.file("sql", "postgresql", "CreateResultsDataModel.sql", package = "CohortDiagnostics") + DatabaseConnector::executeSql( + connection, + sprintf("SET search_path TO %s;", schema), + progressBar = FALSE, + reportOverallTime = FALSE + ) + pathToSql <- + system.file("sql", "postgresql", "CreateResultsDataModel.sql", package = "CohortDiagnostics") sql <- SqlRender::readSql(pathToSql) DatabaseConnector::executeSql(connection, sql) } @@ -172,68 +269,80 @@ naToEmpty <- function(x) { return(x) } +naToZero <- function(x) { + x[is.na(x)] <- 0 + return(x) +} + #' Upload results to the database server. -#' -#' @description +#' +#' @description #' Requires the results data model tables have been created using the \code{\link{createResultsDataModel}} function. -#' +#' #' Set the POSTGRES_PATH environmental variable to the path to the folder containing the psql executable to enable #' bulk upload (recommended). #' #' @param connectionDetails An object of type \code{connectionDetails} as created using the #' \code{\link[DatabaseConnector]{createConnectionDetails}} function in the -#' DatabaseConnector package. -#' @param schema The schema on the postgres server where the tables will be created. +#' DatabaseConnector package. +#' @param schema The schema on the postgres server where the tables have been created. #' @param zipFileName The name of the zip file. -#' @param forceOverWriteOfSpecifications If TRUE, specifications of the phenotypes, cohort definitions, and analysis +#' @param forceOverWriteOfSpecifications If TRUE, specifications of the phenotypes, cohort definitions, and analysis #' will be overwritten if they already exist on the database. Only use this if these specifications #' have changed since the last upload. -#' @param purgeSiteDataBeforeUploading If TRUE, before inserting data for a specific databaseId all the data for -#' that site will be dropped. This assumes the input zip file contains the full data for that +#' @param purgeSiteDataBeforeUploading If TRUE, before inserting data for a specific databaseId all the data for +#' that site will be dropped. This assumes the input zip file contains the full data for that #' data site. #' @param tempFolder A folder on the local file system where the zip files are extracted to. Will be cleaned #' up when the function is finished. Can be used to specify a temp folder on a drive that -#' has sufficent space if the default system temp space is too limited. +#' has sufficient space if the default system temp space is too limited. #' #' @export uploadResults <- function(connectionDetails = NULL, schema, - zipFileName, + zipFileName, forceOverWriteOfSpecifications = FALSE, purgeSiteDataBeforeUploading = TRUE, tempFolder = tempdir()) { start <- Sys.time() connection <- DatabaseConnector::connect(connectionDetails) on.exit(DatabaseConnector::disconnect(connection)) - + unzipFolder <- tempfile("unzipTempFolder", tmpdir = tempFolder) dir.create(path = unzipFolder, recursive = TRUE) on.exit(unlink(unzipFolder, recursive = TRUE), add = TRUE) ParallelLogger::logInfo("Unzipping ", zipFileName) zip::unzip(zipFileName, exdir = unzipFolder) - - specifications = getResultsDataModelSpecifications() + + specifications <- getResultsDataModelSpecifications() if (purgeSiteDataBeforeUploading) { - database <- readr::read_csv(file = file.path(unzipFolder, "database.csv"), col_types = readr::cols()) - colnames(database) <- SqlRender::snakeCaseToCamelCase(colnames(database)) + database <- + readr::read_csv(file = file.path(unzipFolder, "database.csv"), + col_types = readr::cols()) + colnames(database) <- + SqlRender::snakeCaseToCamelCase(colnames(database)) databaseId <- database$databaseId } uploadTable <- function(tableName) { ParallelLogger::logInfo("Uploading table ", tableName) - + primaryKey <- specifications %>% - filter(.data$tableName == !!tableName & .data$primaryKey == "Yes") %>% + filter(.data$tableName == !!tableName & + .data$primaryKey == "Yes") %>% select(.data$fieldName) %>% pull() - if (purgeSiteDataBeforeUploading && "database_id" %in% primaryKey) { - deleteAllRecordsForDatabaseId(connection = connection, - schema = schema, - tableName = tableName, - databaseId = databaseId) + if (purgeSiteDataBeforeUploading && + "database_id" %in% primaryKey) { + deleteAllRecordsForDatabaseId( + connection = connection, + schema = schema, + tableName = tableName, + databaseId = databaseId + ) } csvFileName <- paste0(tableName, ".csv") @@ -242,45 +351,75 @@ uploadResults <- function(connectionDetails = NULL, env$schema <- schema env$tableName <- tableName env$primaryKey <- primaryKey - if (purgeSiteDataBeforeUploading && "database_id" %in% primaryKey) { + if (purgeSiteDataBeforeUploading && + "database_id" %in% primaryKey) { env$primaryKeyValuesInDb <- NULL } else { sql <- "SELECT DISTINCT @primary_key FROM @schema.@table_name;" - sql <- SqlRender::render(sql = sql, - primary_key = primaryKey, - schema = schema, - table_name = tableName) - primaryKeyValuesInDb <- DatabaseConnector::querySql(connection, sql) - colnames(primaryKeyValuesInDb) <- tolower(colnames(primaryKeyValuesInDb)) + sql <- SqlRender::render( + sql = sql, + primary_key = primaryKey, + schema = schema, + table_name = tableName + ) + primaryKeyValuesInDb <- + DatabaseConnector::querySql(connection, sql) + colnames(primaryKeyValuesInDb) <- + tolower(colnames(primaryKeyValuesInDb)) env$primaryKeyValuesInDb <- primaryKeyValuesInDb } - + uploadChunk <- function(chunk, pos) { - ParallelLogger::logInfo("- Preparing to upload rows ", pos, " through ", pos + nrow(chunk) - 1) + ParallelLogger::logInfo("- Preparing to upload rows ", + pos, + " through ", + pos + nrow(chunk) - 1) - checkColumnNames(table = chunk, - tableName = env$tableName, - zipFileName = zipFileName, - specifications = specifications) - chunk <- checkAndFixDataTypes(table = chunk, - tableName = env$tableName, - zipFileName = zipFileName, - specifications = specifications) - chunk <- checkAndFixDuplicateRows(table = chunk, - tableName = env$tableName, - zipFileName = zipFileName, - specifications = specifications) + chunk <- checkFixColumnNames( + table = chunk, + tableName = env$tableName, + zipFileName = zipFileName, + specifications = specifications + ) + chunk <- checkAndFixDataTypes( + table = chunk, + tableName = env$tableName, + zipFileName = zipFileName, + specifications = specifications + ) + chunk <- checkAndFixDuplicateRows( + table = chunk, + tableName = env$tableName, + zipFileName = zipFileName, + specifications = specifications + ) - # Primary key fields cannot be NULL, so for some tables convert NAs to empty: + # Primary key fields cannot be NULL, so for some tables convert NAs to empty or zero: toEmpty <- specifications %>% - filter(.data$tableName == env$tableName & .data$emptyIsNa == "No") %>% + filter( + .data$tableName == env$tableName & + .data$emptyIsNa == "No" & grepl("varchar", .data$type) + ) %>% select(.data$fieldName) %>% pull() if (length(toEmpty) > 0) { - chunk <- chunk %>% + chunk <- chunk %>% dplyr::mutate_at(toEmpty, naToEmpty) } + tozero <- specifications %>% + filter( + .data$tableName == env$tableName & + .data$emptyIsNa == "No" & + .data$type %in% c("int", "bigint", "float") + ) %>% + select(.data$fieldName) %>% + pull() + if (length(tozero) > 0) { + chunk <- chunk %>% + dplyr::mutate_at(tozero, naToZero) + } + # Check if inserting data would violate primary key constraints: if (!is.null(env$primaryKeyValuesInDb)) { primaryKeyValuesInChunk <- unique(chunk[env$primaryKey]) @@ -288,17 +427,28 @@ uploadResults <- function(connectionDetails = NULL, primaryKeyValuesInChunk, by = env$primaryKey) if (nrow(duplicates) != 0) { - if ("database_id" %in% env$primaryKey || forceOverWriteOfSpecifications) { - ParallelLogger::logInfo("- Found ", nrow(duplicates), " rows in database with the same primary key ", - "as the data to insert. Deleting from database before inserting.") - deleteFromServer(connection = connection, - schema = env$schema, - tableName = env$tableName, - keyValues = duplicates) + if ("database_id" %in% env$primaryKey || + forceOverWriteOfSpecifications) { + ParallelLogger::logInfo( + "- Found ", + nrow(duplicates), + " rows in database with the same primary key ", + "as the data to insert. Deleting from database before inserting." + ) + deleteFromServer( + connection = connection, + schema = env$schema, + tableName = env$tableName, + keyValues = duplicates + ) } else { - ParallelLogger::logInfo("- Found ", nrow(duplicates), " rows in database with the same primary key ", - "as the data to insert. Removing from data to insert.") + ParallelLogger::logInfo( + "- Found ", + nrow(duplicates), + " rows in database with the same primary key ", + "as the data to insert. Removing from data to insert." + ) chunk <- chunk %>% anti_join(duplicates, by = env$primaryKey) } @@ -310,19 +460,25 @@ uploadResults <- function(connectionDetails = NULL, if (nrow(chunk) == 0) { ParallelLogger::logInfo("- No data left to insert") } else { - insertDataIntoDb(connection = connection, - connectionDetails = connectionDetails, - schema = env$schema, - tableName = env$tableName, - data = chunk) + DatabaseConnector::insertTable( + connection = connection, + tableName = paste(env$schema, env$tableName, sep = "."), + data = chunk, + dropTableIfExists = FALSE, + createTable = FALSE, + tempTable = FALSE, + progressBar = TRUE + ) } } - readr::read_csv_chunked(file = file.path(unzipFolder, csvFileName), - callback = uploadChunk, - chunk_size = 1e7, - col_types = readr::cols(), - guess_max = 1e6, - progress = FALSE) + readr::read_csv_chunked( + file = file.path(unzipFolder, csvFileName), + callback = uploadChunk, + chunk_size = 1e7, + col_types = readr::cols(), + guess_max = 1e6, + progress = FALSE + ) # chunk <- readr::read_csv(file = file.path(unzipFolder, csvFileName), # col_types = readr::cols(), @@ -335,135 +491,70 @@ uploadResults <- function(connectionDetails = NULL, writeLines(paste("Uploading data took", signif(delta, 3), attr(delta, "units"))) } -deleteFromServer <- function(connection, schema, tableName, keyValues) { - createSqlStatement <- function(i) { - sql <- paste0("DELETE FROM ", - schema, - ".", - tableName, - "\nWHERE ", - paste(paste0(colnames(keyValues), " = '", keyValues[i, ], "'"), collapse = " AND "), - ";") - return(sql) - } - batchSize <- 1000 - for (start in seq(1, nrow(keyValues), by = batchSize)) { - end <- min(start + batchSize - 1, nrow(keyValues)) - sql <- sapply(start:end, createSqlStatement) - sql <- paste(sql, collapse = "\n") - DatabaseConnector::executeSql(connection, sql, progressBar = FALSE, reportOverallTime = FALSE, runAsBatch = TRUE) +deleteFromServer <- + function(connection, schema, tableName, keyValues) { + createSqlStatement <- function(i) { + sql <- paste0( + "DELETE FROM ", + schema, + ".", + tableName, + "\nWHERE ", + paste(paste0( + colnames(keyValues), " = '", keyValues[i,], "'" + ), collapse = " AND "), + ";" + ) + return(sql) + } + batchSize <- 1000 + for (start in seq(1, nrow(keyValues), by = batchSize)) { + end <- min(start + batchSize - 1, nrow(keyValues)) + sql <- sapply(start:end, createSqlStatement) + sql <- paste(sql, collapse = "\n") + DatabaseConnector::executeSql( + connection, + sql, + progressBar = FALSE, + reportOverallTime = FALSE, + runAsBatch = TRUE + ) + } } -} deleteAllRecordsForDatabaseId <- function(connection, schema, tableName, databaseId) { - sql <- "SELECT COUNT(*) FROM @schema.@table_name WHERE database_id = '@database_id';" - sql <- SqlRender::render(sql = sql, - schema = schema, - table_name = tableName, - database_id = databaseId) - databaseIdCount <- DatabaseConnector::querySql(connection, sql)[, 1] + sql <- + "SELECT COUNT(*) FROM @schema.@table_name WHERE database_id = '@database_id';" + sql <- SqlRender::render( + sql = sql, + schema = schema, + table_name = tableName, + database_id = databaseId + ) + databaseIdCount <- + DatabaseConnector::querySql(connection, sql)[, 1] if (databaseIdCount != 0) { - ParallelLogger::logInfo(sprintf("- Found %s rows in database with database ID '%s'. Deleting all before inserting.", - databaseIdCount, - databaseId)) - sql <- "DELETE FROM @schema.@table_name WHERE database_id = '@database_id';" - sql <- SqlRender::render(sql = sql, - schema = schema, - table_name = tableName, - database_id = databaseId) - DatabaseConnector::executeSql(connection, sql, progressBar = FALSE, reportOverallTime = FALSE) - } -} - -insertDataIntoDb <- function(connection, - connectionDetails, - schema, - tableName, - data) { - if (nrow(data) < 1e4 || is.null(Sys.getenv("POSTGRES_PATH"))) { - ParallelLogger::logInfo("- Inserting ", nrow(data), " rows into database") - DatabaseConnector::insertTable(connection = connection, - tableName = paste(schema, tableName, sep = "."), - data = as.data.frame(data), - dropTableIfExists = FALSE, - createTable = FALSE, - tempTable = FALSE, - progressBar = TRUE) - } else { - ParallelLogger::logInfo("- Inserting ", nrow(data), " rows into database using bulk import") - tempFile <- tempfile(fileext = ".csv") - readr::write_excel_csv(data, tempFile) - on.exit(unlink(tempFile)) - DatabaseConnector::executeSql(connection, "COMMIT;", progressBar = FALSE, reportOverallTime = FALSE) - bulkUploadTable(connectionDetails = connectionDetails, - schema = schema, - csvFileName = tempFile, - tableName = tableName) - } -} - -bulkUploadTable <- function(connectionDetails, - schema, - csvFileName, - tableName) { - startTime <- Sys.time() - - # For backwards compatibility with older versions of DatabaseConnector: - if (is(connectionDetails$server, "function")) { - hostServerDb <- strsplit(connectionDetails$server(), "/")[[1]] - port <- connectionDetails$port() - user <- connectionDetails$user() - password <- connectionDetails$password() - } else { - hostServerDb <- strsplit(connectionDetails$server, "/")[[1]] - port <- connectionDetails$port - user <- connectionDetails$user - password <- connectionDetails$password + ParallelLogger::logInfo( + sprintf( + "- Found %s rows in database with database ID '%s'. Deleting all before inserting.", + databaseIdCount, + databaseId + ) + ) + sql <- + "DELETE FROM @schema.@table_name WHERE database_id = '@database_id';" + sql <- SqlRender::render( + sql = sql, + schema = schema, + table_name = tableName, + database_id = databaseId + ) + DatabaseConnector::executeSql(connection, + sql, + progressBar = FALSE, + reportOverallTime = FALSE) } - - # Required by psql: - Sys.setenv("PGPASSWORD" = password) - rm(password) - on.exit(Sys.unsetenv("PGPASSWORD")) - - if (.Platform$OS.type == "windows") { - winPsqlPath <- Sys.getenv("POSTGRES_PATH") - command <- file.path(winPsqlPath, "psql.exe") - if (!file.exists(command)) { - stop("Could not find psql.exe in ", winPsqlPath) - } - command <- paste0("\"", command, "\"") - } else { - command <- "psql" - } - - head <- readr::read_csv(file = csvFileName, n_max = 1, col_types = readr::cols()) - headers <- paste(names(head), collapse = ", ") - headers <- paste0("(", headers, ")") - tablePath <- paste(schema, tableName, sep = ".") - filePathStr <- paste0("'", csvFileName, "'") - - if (is.null(port)) { - port <- 5432 - } - copyCommand <- paste(command, - "-h", hostServerDb[[1]], # Host - "-d", hostServerDb[[2]], # Database - "-p", port, - "-U", user, - "-c \"\\copy", tablePath, - headers, - "FROM", filePathStr, - "NULL 'NA' DELIMITER ',' CSV HEADER;\"") - - result <- base::system(copyCommand) - - if (result != 0) { - stop("Error while bulk uploading data, psql returned a non zero status. Status = ", result) - } - delta <- Sys.time() - startTime - writeLines(paste("Uploading data took", signif(delta, 3), attr(delta, "units"))) } diff --git a/R/RunDiagnostics.R b/R/RunDiagnostics.R index 87c9bd38a..8db5a79bf 100644 --- a/R/RunDiagnostics.R +++ b/R/RunDiagnostics.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,7 @@ #' @description #' Runs the cohort diagnostics on all (or a subset of) the cohorts instantiated using the #' \code{ROhdsiWebApi::insertCohortDefinitionSetInPackage} function. Assumes the cohorts have already been instantiated. -#' +#' #' Characterization: #' If runTemporalCohortCharacterization argument is TRUE, then the following default covariateSettings object will be created #' using \code{RFeatureExtraction::createTemporalCovariateSettings} @@ -28,26 +28,16 @@ #' @template Connection #' #' @template CdmDatabaseSchema +#' @template VocabularyDatabaseSchema #' @template CohortDatabaseSchema +#' @template TempEmulationSchema #' @template OracleTempSchema #' #' @template CohortTable #' #' @template CohortSetSpecs -#' +#' #' @template CohortSetReference -#' @param phenotypeDescriptionFile (Optional) The location of the phenotype description file within the package. -#' The file must be .csv file and have the following columns that may be read into following -#' data types: phenotypeId (double), phenotypeName (character), -#' referentConceptId (double), clinicalDescription (character), -#' literatureReview (character), phenotypeNotes (character). Note: the field -#' names are in snake_case. Also, character fields should not have 'NA' in it. -#' 'NA's are commonly added by R when R functions exports data from dataframe -#' into CSV. Instead please use '' (empty string) to represent absence of data. -#' The literature_review field is expected to be a html link to page that contains -#' resources related to literature review for the phenotype, and will be used -#' to create link-out object. This csv file is expected to be encoded in either -#' ASCII or UTF-8, if not, an error message will be displayed and process stopped. #' @param inclusionStatisticsFolder The folder where the inclusion rule statistics are stored. Can be #' left NULL if \code{runInclusionStatistics = FALSE}. #' @param exportFolder The folder where the output will be exported to. If this folder @@ -55,8 +45,8 @@ #' @param cohortIds Optionally, provide a subset of cohort IDs to restrict the #' diagnostics to. #' @param databaseId A short string for identifying the database (e.g. 'Synpuf'). -#' @param databaseName The full name of the database. -#' @param databaseDescription A short description (several sentences) of the database. +#' @param databaseName The full name of the database. If NULL, defaults to databaseId. +#' @param databaseDescription A short description (several sentences) of the database. If NULL, defaults to databaseId. #' @template cdmVersion #' @param runInclusionStatistics Generate and export statistic on the cohort inclusion rules? #' @param runIncludedSourceConcepts Generate and export the source concepts included in the cohorts? @@ -65,10 +55,11 @@ #' @param runVisitContext Generate and export index-date visit context? #' @param runBreakdownIndexEvents Generate and export the breakdown of index events? #' @param runIncidenceRate Generate and export the cohort incidence rates? +#' @param runTimeSeries Generate and export the cohort prevalence rates? #' @param runCohortOverlap Generate and export the cohort overlap? Overlaps are checked within cohortIds -#' that have the same phenotype ID sourced from the CohortSetReference or +#' that have the same phenotype ID sourced from the CohortSetReference or #' cohortToCreateFile. -#' @param runCohortCharacterization Generate and export the cohort characterization? +#' @param runCohortCharacterization Generate and export the cohort characterization? #' Only records with values greater than 0.0001 are returned. #' @param covariateSettings Either an object of type \code{covariateSettings} as created using one of #' the createCovariateSettings function in the FeatureExtraction package, or a list @@ -87,19 +78,20 @@ runCohortDiagnostics <- function(packageName = NULL, cohortToCreateFile = "settings/CohortsToCreate.csv", baseUrl = NULL, cohortSetReference = NULL, - phenotypeDescriptionFile = NULL, connectionDetails = NULL, connection = NULL, cdmDatabaseSchema, oracleTempSchema = NULL, + tempEmulationSchema = NULL, cohortDatabaseSchema, + vocabularyDatabaseSchema = cdmDatabaseSchema, cohortTable = "cohort", cohortIds = NULL, inclusionStatisticsFolder = file.path(exportFolder, "inclusionStatistics"), exportFolder, databaseId, - databaseName = NULL, - databaseDescription = NULL, + databaseName = databaseId, + databaseDescription = databaseId, cdmVersion = 5, runInclusionStatistics = TRUE, runIncludedSourceConcepts = TRUE, @@ -108,24 +100,42 @@ runCohortDiagnostics <- function(packageName = NULL, runVisitContext = TRUE, runBreakdownIndexEvents = TRUE, runIncidenceRate = TRUE, + runTimeSeries = TRUE, runCohortOverlap = TRUE, runCohortCharacterization = TRUE, covariateSettings = createDefaultCovariateSettings(), runTemporalCohortCharacterization = TRUE, temporalCovariateSettings = createTemporalCovariateSettings( - useConditionOccurrence = TRUE, - useDrugEraStart = TRUE, - useProcedureOccurrence = TRUE, - useMeasurement = TRUE, - temporalStartDays = c(-365,-30,0,1,31), - temporalEndDays = c(-31,-1,0,30,365)), + useConditionOccurrence = TRUE, + useDrugEraStart = TRUE, + useProcedureOccurrence = TRUE, + useMeasurement = TRUE, + temporalStartDays = c(-365, -30, 0, 1, 31), + temporalEndDays = c(-31, -1, 0, 30, 365) + ), minCellCount = 5, incremental = FALSE, incrementalFolder = file.path(exportFolder, "incremental")) { + if (!is.null(cohortSetReference)) { + ParallelLogger::logInfo("Found cohortSetReference. Cohort Diagnostics is running in WebApi mode.") + cohortToCreateFile <- NULL + } start <- Sys.time() ParallelLogger::logInfo("Run Cohort Diagnostics started at ", start) + if (all(!is.null(oracleTempSchema), is.null(tempEmulationSchema))) { + tempEmulationSchema <- oracleTempSchema + warning('OracleTempSchema has been deprecated by DatabaseConnector') + } + + if (any(is.null(databaseName), is.na(databaseName))) { + databaseName <- databaseId + } + if (any(is.null(databaseDescription), is.na(databaseDescription))) { + databaseDescription <- databaseId + } + errorMessage <- checkmate::makeAssertCollection() checkmate::assertLogical(runInclusionStatistics, add = errorMessage) checkmate::assertLogical(runIncludedSourceConcepts, add = errorMessage) @@ -135,55 +145,159 @@ runCohortDiagnostics <- function(packageName = NULL, checkmate::assertLogical(runIncidenceRate, add = errorMessage) checkmate::assertLogical(runCohortOverlap, add = errorMessage) checkmate::assertLogical(runCohortCharacterization, add = errorMessage) - checkmate::assertInt(x = cdmVersion, na.ok = FALSE, lower = 5, upper = 5, null.ok = FALSE, add = errorMessage) + checkmate::assertInt( + x = cdmVersion, + na.ok = FALSE, + lower = 5, + upper = 5, + null.ok = FALSE, + add = errorMessage + ) minCellCount <- utils::type.convert(minCellCount) checkmate::assertInteger(x = minCellCount, lower = 0, add = errorMessage) checkmate::assertLogical(incremental, add = errorMessage) - if (any(runInclusionStatistics, runIncludedSourceConcepts, runOrphanConcepts, - runTimeDistributions, runBreakdownIndexEvents, runIncidenceRate, - runCohortOverlap, runCohortCharacterization)) { - checkmate::assertCharacter(x = cdmDatabaseSchema, min.len = 1, add = errorMessage) - checkmate::assertCharacter(x = cohortDatabaseSchema, min.len = 1, add = errorMessage) - checkmate::assertCharacter(x = cohortTable, min.len = 1, add = errorMessage) - checkmate::assertCharacter(x = databaseId, min.len = 1, add = errorMessage) - checkmate::assertCharacter(x = databaseDescription, min.len = 1, add = errorMessage) + if (any( + runInclusionStatistics, + runIncludedSourceConcepts, + runOrphanConcepts, + runTimeDistributions, + runBreakdownIndexEvents, + runIncidenceRate, + runCohortOverlap, + runCohortCharacterization + )) { + checkmate::assertCharacter(x = cdmDatabaseSchema, + min.len = 1, + add = errorMessage) + checkmate::assertCharacter(x = vocabularyDatabaseSchema, + min.len = 1, + add = errorMessage) + checkmate::assertCharacter(x = cohortDatabaseSchema, + min.len = 1, + add = errorMessage) + checkmate::assertCharacter(x = cohortTable, + min.len = 1, + add = errorMessage) + checkmate::assertCharacter(x = databaseId, + min.len = 1, + add = errorMessage) } checkmate::reportAssertions(collection = errorMessage) - errorMessage <- createIfNotExist(type = "folder", name = exportFolder, errorMessage = errorMessage) + errorMessage <- + createIfNotExist(type = "folder", + name = exportFolder, + errorMessage = errorMessage) if (incremental) { - errorMessage <- createIfNotExist(type = "folder", name = incrementalFolder, errorMessage = errorMessage) + errorMessage <- + createIfNotExist(type = "folder", + name = incrementalFolder, + errorMessage = errorMessage) } if (isTRUE(runInclusionStatistics)) { - errorMessage <- createIfNotExist(type = "folder", name = inclusionStatisticsFolder, errorMessage = errorMessage) + errorMessage <- + createIfNotExist(type = "folder", + name = inclusionStatisticsFolder, + errorMessage = errorMessage) } checkmate::reportAssertions(collection = errorMessage) - cohorts <- getCohortsJsonAndSql(packageName = packageName, - cohortToCreateFile = cohortToCreateFile, - baseUrl = baseUrl, - cohortSetReference = cohortSetReference, - cohortIds = cohortIds) - - if (!is.null(phenotypeDescriptionFile)) { - phenotypeDescription <- loadAndExportPhenotypeDescription(packageName = packageName, - phenotypeDescriptionFile = phenotypeDescriptionFile, - exportFolder = exportFolder, - cohorts = cohorts, - errorMessage = errorMessage) - } else { - phenotypeDescription <- NULL - } + cohorts <- getCohortsJsonAndSql( + packageName = packageName, + cohortToCreateFile = cohortToCreateFile, + baseUrl = baseUrl, + cohortSetReference = cohortSetReference, + cohortIds = cohortIds + ) if (nrow(cohorts) == 0) { stop("No cohorts specified") } if ('name' %in% colnames(cohorts)) { - cohorts <- cohorts %>% + cohorts <- cohorts %>% dplyr::select(-.data$name) } - writeToCsv(data = cohorts, fileName = file.path(exportFolder, "cohort.csv")) + cohortTableColumnNamesObserved <- colnames(cohorts) %>% + sort() + cohortTableColumnNamesExpected <- + getResultsDataModelSpecifications() %>% + dplyr::filter(.data$tableName == 'cohort') %>% + dplyr::pull(.data$fieldName) %>% + SqlRender::snakeCaseToCamelCase() %>% + sort() + cohortTableColumnNamesRequired <- + getResultsDataModelSpecifications() %>% + dplyr::filter(.data$tableName == 'cohort') %>% + dplyr::filter(.data$isRequired == 'Yes') %>% + dplyr::pull(.data$fieldName) %>% + SqlRender::snakeCaseToCamelCase() %>% + sort() + + expectedButNotObsevered <- + setdiff(x = cohortTableColumnNamesExpected, y = cohortTableColumnNamesObserved) + if (length(expectedButNotObsevered) > 0) { + requiredButNotObsevered <- + setdiff(x = cohortTableColumnNamesRequired, y = cohortTableColumnNamesObserved) + } + obseveredButNotExpected <- + setdiff(x = cohortTableColumnNamesObserved, y = cohortTableColumnNamesExpected) + + if (length(requiredButNotObsevered) > 0) { + stop(paste( + "The following required fields not found in cohort table:", + paste0(requiredButNotObsevered, collapse = ", ") + )) + } + + if ('logicDescription' %in% expectedButNotObsevered) { + cohorts$logicDescription <- cohorts$cohortName + } + if ('phenotypeId' %in% expectedButNotObsevered) { + cohorts$phenotypeId <- + 0 # phenotypeId is assigned = 0 when no phenotypeId is provided. + # This is required for cohort overlap + } + if ('metadata' %in% expectedButNotObsevered) { + if (length(obseveredButNotExpected) > 0) { + writeLines( + paste( + "The following columns were observed in the cohort table, \n + that are not expected and will be available as part of json object \n + in a newly created 'metadata' column.", + paste0(obseveredButNotExpected, collapse = ", ") + ) + ) + } + columnsToAddToJson <- + setdiff(x = cohortTableColumnNamesObserved, + y = c('json', 'sql')) %>% + unique() %>% + sort() + cohorts <- cohorts %>% + dplyr::mutate(metadata = as.list(columnsToAddToJson) %>% RJSONIO::toJSON(digits = 23)) + } else { + if (length(obseveredButNotExpected) > 0) { + writeLines( + paste( + "The following columns were observed in the cohort table, \n + that are not expected. If you would like to retain them please \n + them as JSON objects in the 'metadata' column.", + paste0(obseveredButNotExpected, collapse = ", ") + ) + ) + stop(paste0( + "Terminating - please update the metadata column to include: ", + paste0(obseveredButNotExpected, collapse = ", ") + )) + } + } + + cohorts <- cohorts %>% + dplyr::select(cohortTableColumnNamesExpected) + writeToCsv(data = cohorts, + fileName = file.path(exportFolder, "cohort.csv")) + if (!"phenotypeId" %in% colnames(cohorts)) { cohorts$phenotypeId <- NA } @@ -198,224 +312,368 @@ runCohortDiagnostics <- function(packageName = NULL, } } + tryCatch({ + vocabularyVersionCdm <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = "select * from @cdm_database_schema.cdm_source;", + cdm_database_schema = cdmDatabaseSchema, + snakeCaseToCamelCase = TRUE + ) %>% + dplyr::tibble() + }, error = function(...) { + warning("Problem getting vocabulary version. cdm_source table not found in the database.") + if (connection@dbms == "postgresql") { #this is for test that automated testing purpose + DatabaseConnector::dbExecute(connection, "ABORT;") + } + }) + + if (all(exists('vocabularyVersionCdm'), + !is.null(vocabularyVersionCdm), + nrow(vocabularyVersionCdm) > 0, + 'vocabularyVersion' %in% colnames(vocabularyVersionCdm))) { + vocabularyVersionCdm <- vocabularyVersionCdm %>% + dplyr::rename(vocabularyVersionCdm = .data$vocabularyVersion) %>% + dplyr::pull(vocabularyVersionCdm) %>% + unique() + } else { + warning("Problem getting vocabulary version. cdm_source table either does not have data, or does not have the field vocabulary_version.") + vocabularyVersionCdm <- NULL + } + + vocabularyVersion <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = "select * from @vocabulary_database_schema.vocabulary where vocabulary_id = 'None';", + vocabulary_database_schema = vocabularyDatabaseSchema, + snakeCaseToCamelCase = TRUE + ) %>% + dplyr::tibble() %>% + dplyr::rename(vocabularyVersion = .data$vocabularyVersion) %>% + dplyr::pull(.data$vocabularyVersion) %>% + unique() + if (incremental) { ParallelLogger::logDebug("Working in incremental mode.") cohorts$checksum <- computeChecksum(cohorts$sql) - recordKeepingFile <- file.path(incrementalFolder, "CreatedDiagnostics.csv") + recordKeepingFile <- + file.path(incrementalFolder, "CreatedDiagnostics.csv") if (file.exists(path = recordKeepingFile)) { - ParallelLogger::logInfo("Found existing record keeping file in incremental folder - CreatedDiagnostics.csv") + ParallelLogger::logInfo( + "Found existing record keeping file in incremental folder - CreatedDiagnostics.csv" + ) } } # Database metadata --------------------------------------------- ParallelLogger::logInfo("Saving database metadata") startMetaData <- Sys.time() - database <- dplyr::tibble(databaseId = databaseId, - databaseName = dplyr::coalesce(databaseName,databaseId), - description = dplyr::coalesce(databaseDescription,databaseId), - isMetaAnalysis = 0) - writeToCsv(data = database, + database <- dplyr::tibble( + databaseId = databaseId, + databaseName = dplyr::coalesce(databaseName, databaseId), + description = dplyr::coalesce(databaseDescription, databaseId), + vocabularyVersionCdm = !!vocabularyVersionCdm, + vocabularyVersion = !!vocabularyVersion, + isMetaAnalysis = 0 + ) + writeToCsv(data = database, fileName = file.path(exportFolder, "database.csv")) delta <- Sys.time() - startMetaData - writeLines(paste("Saving database metadata took", signif(delta, 3), attr(delta, "units"))) + writeLines(paste( + "Saving database metadata took", + signif(delta, 3), + attr(delta, "units") + )) # Create concept table ------------------------------------------ ParallelLogger::logTrace("Creating concept ID table for tracking concepts used in diagnostics") - sql <- SqlRender::loadRenderTranslateSql("CreateConceptIdTable.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - oracleTempSchema = oracleTempSchema, - table_name = "#concept_ids") - DatabaseConnector::executeSql(connection = connection, sql = sql, progressBar = FALSE, reportOverallTime = FALSE) - if (!is.null(phenotypeDescription)) { - data <- phenotypeDescription %>% - dplyr::filter(!is.na(.data$referentConceptId)) %>% - dplyr::transmute(conceptId = as.integer(.data$referentConceptId)) %>% - dplyr::distinct() %>% - as.data.frame() #DatabaseConnector currently does not support tibble - if (nrow(data) > 0) { - ParallelLogger::logInfo(sprintf("Inserting %s referent concept IDs into the concept ID table. This may take a while.", - nrow(data))) - DatabaseConnector::insertTable(connection = connection, - tableName = "#concept_ids", - data = data, - dropTableIfExists = FALSE, - createTable = FALSE, - progressBar = TRUE, - tempTable = TRUE, - oracleTempSchema = oracleTempSchema, - camelCaseToSnakeCase = TRUE) - ParallelLogger::logTrace("Done inserting") - } + sql <- + SqlRender::loadRenderTranslateSql( + "CreateConceptIdTable.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + tempEmulationSchema = tempEmulationSchema, + table_name = "#concept_ids" + ) + DatabaseConnector::executeSql( + connection = connection, + sql = sql, + progressBar = FALSE, + reportOverallTime = FALSE + ) + + referentConceptIdToInsert <- dplyr::tibble() + if ('referentConceptId' %in% colnames(cohorts)) { + referentConceptIdToInsert <- + dplyr::bind_rows(referentConceptIdToInsert, + cohorts %>% + dplyr::transmute(conceptId = as.double(.data$referentConceptId))) %>% + dplyr::distinct() + } + if (nrow(referentConceptIdToInsert) > 0) { + ParallelLogger::logInfo( + sprintf( + "Inserting %s referent concept IDs into the concept ID table. This may take a while.", + nrow(referentConceptIdToInsert) + ) + ) + DatabaseConnector::insertTable( + connection = connection, + tableName = "#concept_ids", + data = referentConceptIdToInsert, + dropTableIfExists = FALSE, + createTable = FALSE, + progressBar = TRUE, + tempTable = TRUE, + tempEmulationSchema = tempEmulationSchema, + camelCaseToSnakeCase = TRUE + ) + ParallelLogger::logTrace("Done inserting") } # Counting cohorts ----------------------------------------------------------------------- ParallelLogger::logInfo("Counting cohort records and subjects") - cohortCounts <- getCohortCounts(connection = connection, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortIds = cohorts$cohortId) - cohortCounts <- cohortCounts %>% - dplyr::mutate(databaseId = !!databaseId) - if (nrow(cohortCounts) > 0) { - cohortCounts <- enforceMinCellValue(data = cohortCounts, fieldName = "cohortEntries", minValues = minCellCount) - cohortCounts <- enforceMinCellValue(data = cohortCounts, fieldName = "cohortSubjects", minValues = minCellCount) - } - writeToCsv(data = cohortCounts, - fileName = file.path(exportFolder, "cohort_count.csv"), - incremental = FALSE, - cohortId = subset$cohortId) - - if (nrow(cohortCounts) > 0) { - instantiatedCohorts <- cohortCounts %>% - dplyr::pull(.data$cohortId) - ParallelLogger::logInfo(sprintf("Found %s of %s (%1.2f%%) submitted cohorts instantiated. ", - length(instantiatedCohorts), - nrow(cohorts), - 100*(length(instantiatedCohorts)/nrow(cohorts))), - "Beginning cohort diagnostics for instantiated cohorts. ") + cohortCounts <- getCohortCounts( + connection = connection, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cohortIds = cohorts$cohortId + ) + if (!is.null(cohortCounts)) { + cohortCounts <- cohortCounts %>% + dplyr::mutate(databaseId = !!databaseId) + if (nrow(cohortCounts) > 0) { + cohortCounts <- + enforceMinCellValue(data = cohortCounts, + fieldName = "cohortEntries", + minValues = minCellCount) + cohortCounts <- + enforceMinCellValue(data = cohortCounts, + fieldName = "cohortSubjects", + minValues = minCellCount) + } + writeToCsv( + data = cohortCounts, + fileName = file.path(exportFolder, "cohort_count.csv"), + incremental = FALSE, + cohortId = subset$cohortId + ) + + if (nrow(cohortCounts) > 0) { + instantiatedCohorts <- cohortCounts %>% + dplyr::pull(.data$cohortId) + ParallelLogger::logInfo( + sprintf( + "Found %s of %s (%1.2f%%) submitted cohorts instantiated. ", + length(instantiatedCohorts), + nrow(cohorts), + 100 * (length(instantiatedCohorts) / + nrow(cohorts)) + ), + "Beginning cohort diagnostics for instantiated cohorts. " + ) + } else { + stop("All cohorts were either not instantiated or all have 0 records.") + } } else { - stop("All cohorts were either not instantiated or all have 0 records.") + stop( + "Cohort table should be instantiated. If there is no cohort table, there are no cohorts to diagnose." + ) } - + # Inclusion statistics ----------------------------------------------------------------------- if (runInclusionStatistics) { ParallelLogger::logInfo("Fetching inclusion statistics from files") - subset <- subsetToRequiredCohorts(cohorts = cohorts %>% - dplyr::filter(.data$cohortId %in% instantiatedCohorts), - task = "runInclusionStatistics", - incremental = incremental, - recordKeepingFile = recordKeepingFile) + subset <- subsetToRequiredCohorts( + cohorts = cohorts %>% + dplyr::filter(.data$cohortId %in% instantiatedCohorts), + task = "runInclusionStatistics", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) - if (incremental && (length(instantiatedCohorts) - nrow(subset)) > 0) { - ParallelLogger::logInfo(sprintf("Skipping %s cohorts in incremental mode.", - length(instantiatedCohorts) - nrow(subset))) + if (incremental && + (length(instantiatedCohorts) - nrow(subset)) > 0) { + ParallelLogger::logInfo(sprintf( + "Skipping %s cohorts in incremental mode.", + length(instantiatedCohorts) - nrow(subset) + )) } if (nrow(subset) > 0) { - stats <- getInclusionStatisticsFromFiles(cohortIds = subset$cohortId, - folder = inclusionStatisticsFolder, - simplify = TRUE) - if (nrow(stats) > 0) { - stats <- stats %>% - dplyr::mutate(databaseId = !!databaseId) - stats <- enforceMinCellValue(data = stats, fieldName = "meetSubjects", minValues = minCellCount) - stats <- enforceMinCellValue(data = stats, fieldName = "gainSubjects", minValues = minCellCount) - stats <- enforceMinCellValue(data = stats, fieldName = "totalSubjects", minValues = minCellCount) - stats <- enforceMinCellValue(data = stats, fieldName = "remainSubjects", minValues = minCellCount) - } - if ("cohortDefinitionId" %in% (colnames(stats))) { - stats <- stats %>% - dplyr::rename(cohortId = .data$cohortDefinitionId) + stats <- + getInclusionStatisticsFromFiles( + cohortIds = subset$cohortId, + folder = inclusionStatisticsFolder, + simplify = TRUE + ) + if (!is.null(stats)) { + if (nrow(stats) > 0) { + stats <- stats %>% + dplyr::mutate(databaseId = !!databaseId) + stats <- + enforceMinCellValue(data = stats, + fieldName = "meetSubjects", + minValues = minCellCount) + stats <- + enforceMinCellValue(data = stats, + fieldName = "gainSubjects", + minValues = minCellCount) + stats <- + enforceMinCellValue(data = stats, + fieldName = "totalSubjects", + minValues = minCellCount) + stats <- + enforceMinCellValue(data = stats, + fieldName = "remainSubjects", + minValues = minCellCount) + } + if ("cohortDefinitionId" %in% (colnames(stats))) { + stats <- stats %>% + dplyr::rename(cohortId = .data$cohortDefinitionId) + } + colnames(stats) <- + SqlRender::camelCaseToSnakeCase(colnames(stats)) + writeToCsv( + data = stats, + fileName = file.path(exportFolder, "inclusion_rule_stats.csv"), + incremental = incremental, + cohortId = subset$cohortId + ) + recordTasksDone( + cohortId = subset$cohortId, + task = "runInclusionStatistics", + checksum = subset$checksum, + recordKeepingFile = recordKeepingFile, + incremental = incremental + ) + } else { + warning("Cohort Inclusion statistics file not found. Inclusion Statistis not run.") } - colnames(stats) <- SqlRender::camelCaseToSnakeCase(colnames(stats)) - writeToCsv(data = stats, - fileName = file.path(exportFolder, "inclusion_rule_stats.csv"), - incremental = incremental, - cohortId = subset$cohortId) - recordTasksDone(cohortId = subset$cohortId, - task = "runInclusionStatistics", - checksum = subset$checksum, - recordKeepingFile = recordKeepingFile, - incremental = incremental) } } # Concept set diagnostics ----------------------------------------------- - if (runIncludedSourceConcepts || runOrphanConcepts || runBreakdownIndexEvents) { - runConceptSetDiagnostics(connection = connection, - oracleTempSchema = oracleTempSchema, - cdmDatabaseSchema = cdmDatabaseSchema, - databaseId = databaseId, - cohorts = cohorts, - runIncludedSourceConcepts = runIncludedSourceConcepts, - runOrphanConcepts = runOrphanConcepts, - runBreakdownIndexEvents = runBreakdownIndexEvents, - exportFolder = exportFolder, - minCellCount = minCellCount, - conceptCountsDatabaseSchema = NULL, - conceptCountsTable = "#concept_counts", - conceptCountsTableIsTemp = TRUE, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - useExternalConceptCountsTable = FALSE, - incremental = incremental, - conceptIdTable = "#concept_ids", - recordKeepingFile = recordKeepingFile) + if (runIncludedSourceConcepts || + runOrphanConcepts || runBreakdownIndexEvents) { + runConceptSetDiagnostics( + connection = connection, + tempEmulationSchema = tempEmulationSchema, + cdmDatabaseSchema = cdmDatabaseSchema, + vocabularyDatabaseSchema = vocabularyDatabaseSchema, + databaseId = databaseId, + cohorts = cohorts, + runIncludedSourceConcepts = runIncludedSourceConcepts, + runOrphanConcepts = runOrphanConcepts, + runBreakdownIndexEvents = runBreakdownIndexEvents, + exportFolder = exportFolder, + minCellCount = minCellCount, + conceptCountsDatabaseSchema = NULL, + conceptCountsTable = "#concept_counts", + conceptCountsTableIsTemp = TRUE, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + useExternalConceptCountsTable = FALSE, + incremental = incremental, + conceptIdTable = "#concept_ids", + recordKeepingFile = recordKeepingFile + ) } # Time distributions ---------------------------------------------------------------------- if (runTimeDistributions) { ParallelLogger::logInfo("Creating time distributions") - subset <- subsetToRequiredCohorts(cohorts = cohorts %>% - dplyr::filter(.data$cohortId %in% instantiatedCohorts), - task = "runTimeDistributions", - incremental = incremental, - recordKeepingFile = recordKeepingFile) + subset <- subsetToRequiredCohorts( + cohorts = cohorts %>% + dplyr::filter(.data$cohortId %in% instantiatedCohorts), + task = "runTimeDistributions", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) - if (incremental && (length(instantiatedCohorts) - nrow(subset)) > 0) { - ParallelLogger::logInfo(sprintf("Skipping %s cohorts in incremental mode.", - length(instantiatedCohorts) - nrow(subset))) + if (incremental && + (length(instantiatedCohorts) - nrow(subset)) > 0) { + ParallelLogger::logInfo(sprintf( + "Skipping %s cohorts in incremental mode.", + length(instantiatedCohorts) - nrow(subset) + )) } if (nrow(subset) > 0) { - data <- getTimeDistributions(connection = connection, - oracleTempSchema = oracleTempSchema, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cdmVersion = cdmVersion, - cohortIds = subset$cohortId) + data <- getTimeDistributions( + connection = connection, + tempEmulationSchema = tempEmulationSchema, + cdmDatabaseSchema = cdmDatabaseSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cdmVersion = cdmVersion, + cohortIds = subset$cohortId + ) if (nrow(data) > 0) { data <- data %>% dplyr::mutate(databaseId = !!databaseId) - writeToCsv(data = data, - fileName = file.path(exportFolder, "time_distribution.csv"), - incremental = incremental, - cohortId = subset$cohortId) + writeToCsv( + data = data, + fileName = file.path(exportFolder, "time_distribution.csv"), + incremental = incremental, + cohortId = subset$cohortId + ) } - recordTasksDone(cohortId = subset$cohortId, - task = "runTimeDistributions", - checksum = subset$checksum, - recordKeepingFile = recordKeepingFile, - incremental = incremental) + recordTasksDone( + cohortId = subset$cohortId, + task = "runTimeDistributions", + checksum = subset$checksum, + recordKeepingFile = recordKeepingFile, + incremental = incremental + ) } } # Visit context ---------------------------------------------------------------------------- if (runVisitContext) { ParallelLogger::logInfo("Retrieving visit context for index dates") - subset <- subsetToRequiredCohorts(cohorts = cohorts %>% - dplyr::filter(.data$cohortId %in% instantiatedCohorts), - task = "runVisitContext", - incremental = incremental, - recordKeepingFile = recordKeepingFile) + subset <- subsetToRequiredCohorts( + cohorts = cohorts %>% + dplyr::filter(.data$cohortId %in% instantiatedCohorts), + task = "runVisitContext", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) - if (incremental && (length(instantiatedCohorts) - nrow(subset)) > 0) { - ParallelLogger::logInfo(sprintf("Skipping %s cohorts in incremental mode.", - length(instantiatedCohorts) - nrow(subset))) + if (incremental && + (length(instantiatedCohorts) - nrow(subset)) > 0) { + ParallelLogger::logInfo(sprintf( + "Skipping %s cohorts in incremental mode.", + length(instantiatedCohorts) - nrow(subset) + )) } if (nrow(subset) > 0) { - data <- getVisitContext(connection = connection, - oracleTempSchema = oracleTempSchema, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cdmVersion = cdmVersion, - cohortIds = subset$cohortId, - conceptIdTable = "#concept_ids") + data <- getVisitContext( + connection = connection, + tempEmulationSchema = tempEmulationSchema, + cdmDatabaseSchema = cdmDatabaseSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cdmVersion = cdmVersion, + cohortIds = subset$cohortId, + conceptIdTable = "#concept_ids" + ) if (nrow(data) > 0) { data <- data %>% dplyr::mutate(databaseId = !!databaseId) data <- enforceMinCellValue(data, "subjects", minCellCount) - writeToCsv(data = data, - fileName = file.path(exportFolder, "visit_context.csv"), - incremental = incremental, - cohortId = subset$cohortId) + writeToCsv( + data = data, + fileName = file.path(exportFolder, "visit_context.csv"), + incremental = incremental, + cohortId = subset$cohortId + ) } - recordTasksDone(cohortId = subset$cohortId, - task = "runVisitContext", - checksum = subset$checksum, - recordKeepingFile = recordKeepingFile, - incremental = incremental) + recordTasksDone( + cohortId = subset$cohortId, + task = "runVisitContext", + checksum = subset$checksum, + recordKeepingFile = recordKeepingFile, + incremental = incremental + ) } } @@ -423,57 +681,232 @@ runCohortDiagnostics <- function(packageName = NULL, if (runIncidenceRate) { ParallelLogger::logInfo("Computing incidence rates") startIncidenceRate <- Sys.time() - subset <- subsetToRequiredCohorts(cohorts = cohorts %>% - dplyr::filter(.data$cohortId %in% instantiatedCohorts), - task = "runIncidenceRate", - incremental = incremental, - recordKeepingFile = recordKeepingFile) + subset <- subsetToRequiredCohorts( + cohorts = cohorts %>% + dplyr::filter(.data$cohortId %in% instantiatedCohorts), + task = "runIncidenceRate", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) - if (incremental && (length(instantiatedCohorts) - nrow(subset)) > 0) { - ParallelLogger::logInfo(sprintf("Skipping %s cohorts in incremental mode.", - length(instantiatedCohorts) - nrow(subset))) + if (incremental && + (length(instantiatedCohorts) - nrow(subset)) > 0) { + ParallelLogger::logInfo(sprintf( + "Skipping %s cohorts in incremental mode.", + length(instantiatedCohorts) - nrow(subset) + )) } if (nrow(subset) > 0) { runIncidenceRate <- function(row) { - ParallelLogger::logInfo(" Computing incidence rate for cohort '", row$cohortName, "'") - cohortExpression <- RJSONIO::fromJSON(row$json) + ParallelLogger::logInfo(" Computing incidence rate for cohort '", + row$cohortName, + "'") + cohortExpression <- RJSONIO::fromJSON(row$json, digits = 23) washoutPeriod <- tryCatch({ cohortExpression$PrimaryCriteria$ObservationWindow$PriorDays }, error = function(e) { 0 }) - data <- getIncidenceRate(connection = connection, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortId = row$cohortId, - firstOccurrenceOnly = TRUE, - washoutPeriod = washoutPeriod) + data <- getIncidenceRate( + connection = connection, + cdmDatabaseSchema = cdmDatabaseSchema, + tempEmulationSchema = tempEmulationSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cohortId = row$cohortId, + firstOccurrenceOnly = TRUE, + washoutPeriod = washoutPeriod + ) if (nrow(data) > 0) { data <- data %>% dplyr::mutate(cohortId = row$cohortId) } return(data) } - data <- lapply(split(subset, subset$cohortId), runIncidenceRate) + data <- + lapply(split(subset, subset$cohortId), runIncidenceRate) data <- dplyr::bind_rows(data) if (nrow(data) > 0) { data <- data %>% dplyr::mutate(databaseId = !!databaseId) - data <- enforceMinCellValue(data, "cohortCount", minCellCount) - data <- enforceMinCellValue(data, "incidenceRate", 1000*minCellCount/data$personYears) + data <- + enforceMinCellValue(data, "cohortCount", minCellCount) + data <- + enforceMinCellValue(data, + "incidenceRate", + 1000 * minCellCount / data$personYears) } - writeToCsv(data = data, - fileName = file.path(exportFolder, "incidence_rate.csv"), - incremental = incremental, - cohortId = subset$cohortId) + writeToCsv( + data = data, + fileName = file.path(exportFolder, "incidence_rate.csv"), + incremental = incremental, + cohortId = subset$cohortId + ) } - recordTasksDone(cohortId = subset$cohortId, - task = "runIncidenceRate", - checksum = subset$checksum, - recordKeepingFile = recordKeepingFile, - incremental = incremental) + recordTasksDone( + cohortId = subset$cohortId, + task = "runIncidenceRate", + checksum = subset$checksum, + recordKeepingFile = recordKeepingFile, + incremental = incremental + ) delta <- Sys.time() - startIncidenceRate - ParallelLogger::logInfo("Running Incidence Rate took ", signif(delta, 3), " ", attr(delta, "units")) + ParallelLogger::logInfo("Running Incidence Rate took ", + signif(delta, 3), + " ", + attr(delta, "units")) + } + + # Cohort time series ----------------------------------------------------------------------- + if (runTimeSeries) { + ParallelLogger::logInfo("Calculating time series of subjects and records.") + startPrevalenceRate <- Sys.time() + + subset <- subsetToRequiredCohorts( + cohorts = cohorts %>% + dplyr::filter(.data$cohortId %in% instantiatedCohorts), + task = "runTimeSeries", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) + + if (incremental && + (length(instantiatedCohorts) - nrow(subset)) > 0) { + ParallelLogger::logInfo(sprintf( + "Skipping %s cohorts in incremental mode.", + length(instantiatedCohorts) - nrow(subset) + )) + } + if (nrow(subset) > 0) { + cohortDateRange <- DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = "SELECT MIN(year(cohort_start_date)) MIN_YEAR, + MAX(year(cohort_end_date)) MAX_YEAR + FROM @cohort_database_schema.@cohort_table;", + cohort_database_schema = cohortDatabaseSchema, + cohort_table = cohortTable, + snakeCaseToCamelCase = TRUE, + tempEmulationSchema = tempEmulationSchema + ) + + calendarQuarter <- dplyr::tibble(periodBegin = clock::date_seq(from = clock::date_build(year = max(2000, + cohortDateRange$minYear %>% as.integer())), + to = clock::date_build(year = min(clock::get_year(clock::date_today("")), + (cohortDateRange$maxYear %>% as.integer())) + + 1), + by = clock::duration_months(3))) %>% + dplyr::mutate(periodEnd = clock::add_months(x = .data$periodBegin, n = 3) - 1) %>% + dplyr::mutate(calendarInterval = 'q') + + calendarMonth <- dplyr::tibble(periodBegin = clock::date_seq(from = clock::date_build(year = max(2000, + cohortDateRange$minYear %>% as.integer())), + to = clock::date_build(year = min(clock::get_year(clock::date_today("")), + (cohortDateRange$maxYear %>% as.integer())) + + 1), + by = clock::duration_months(1))) %>% + dplyr::mutate(periodEnd = clock::add_months(x = .data$periodBegin, n = 1) - 1) %>% + dplyr::mutate(calendarInterval = 'm') + + calendarYear <- dplyr::tibble(periodBegin = clock::date_seq(from = clock::date_build(year = cohortDateRange$minYear %>% as.integer()), + to = clock::date_build(year = (cohortDateRange$maxYear %>% as.integer()) + 1), + by = clock::duration_years(1))) %>% + dplyr::mutate(periodEnd = clock::add_years(x = .data$periodBegin, n = 1) - 1) %>% + dplyr::mutate(calendarInterval = 'y') + + # calendarWeek <- dplyr::tibble(periodBegin = clock::date_seq(from = (clock::year_month_weekday(year = cohortDateRange$minYear %>% as.integer(), + # month = clock::clock_months$january, + # day = clock::clock_weekdays$monday, + # index = 1) %>% + # clock::as_date() %>% + # clock::add_weeks(n = -1)), + # to = (clock::year_month_weekday(year = (cohortDateRange$maxYear %>% as.integer()) + 1, + # month = clock::clock_months$january, + # day = clock::clock_weekdays$sunday, + # index = 1) %>% + # clock::as_date()), + # by = clock::duration_weeks(n = 1))) %>% + # dplyr::mutate(periodEnd = clock::add_days(x = .data$periodBegin, n = 6)) + + calendarPeriods <- dplyr::bind_rows(calendarMonth, calendarQuarter, calendarYear) %>% #calendarWeek + dplyr::filter(.data$periodBegin >= as.Date('1999-12-25')) %>% + dplyr::filter(.data$periodEnd <= clock::date_today("")) %>% + dplyr::distinct() + + ParallelLogger::logTrace("Inserting calendar periods into temporay table. This might take time.") + DatabaseConnector::insertTable( + connection = connection, + tableName = "#calendar_periods", + data = calendarPeriods, + dropTableIfExists = TRUE, + createTable = TRUE, + progressBar = TRUE, + tempTable = TRUE, + tempEmulationSchema = tempEmulationSchema, + camelCaseToSnakeCase = TRUE + ) + ParallelLogger::logTrace("Done inserting calendar periods") + + sql <- + SqlRender::loadRenderTranslateSql( + "ComputeTimeSeries.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms + ) + + data <- DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = sql, + cohort_database_schema = cohortDatabaseSchema, + cohort_table = cohortTable, + snakeCaseToCamelCase = TRUE, + tempEmulationSchema = tempEmulationSchema, + cohort_ids = subset$cohortId + ) %>% + dplyr::tibble() %>% + dplyr::mutate(databaseId = !!databaseId) %>% + dplyr::select(.data$cohortId, .data$databaseId, + .data$periodBegin, .data$calendarInterval, + .data$records, .data$subjects, + .data$personDays, .data$recordsIncidence, + .data$subjectsIncidence) + + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = "IF OBJECT_ID('tempdb..#calendar_periods', 'U') IS NOT NULL DROP TABLE #calendar_periods;", + progressBar = TRUE, + tempEmulationSchema = tempEmulationSchema + ) + data <- + enforceMinCellValue(data, "records", minCellCount) + data <- + enforceMinCellValue(data, "subjects", minCellCount) + data <- + enforceMinCellValue(data, "personDays", minCellCount) + data <- + enforceMinCellValue(data, "recordsIncidence", minCellCount) + data <- + enforceMinCellValue(data, "subjectsIncidence", minCellCount) + + if (nrow(data) > 0) { + writeToCsv( + data = data, + fileName = file.path(exportFolder, "time_series.csv"), + incremental = incremental, + cohortId = subset$cohortId + ) + } + + recordTasksDone( + cohortId = subset$cohortId, + task = "runTimeSeries", + checksum = subset$checksum, + recordKeepingFile = recordKeepingFile, + incremental = incremental + ) + delta <- Sys.time() - startPrevalenceRate + ParallelLogger::logInfo("Running Prevalence Rate took ", + signif(delta, 3), + " ", + attr(delta, "units")) + } } # Cohort overlap --------------------------------------------------------------------------------- @@ -481,201 +914,288 @@ runCohortDiagnostics <- function(packageName = NULL, ParallelLogger::logInfo("Computing cohort overlap") startCohortOverlap <- Sys.time() - combis <- cohorts %>% - dplyr::select(.data$phenotypeId, .data$cohortId) %>% - dplyr::rename(targetCohortId = .data$cohortId) %>% - dplyr::inner_join(cohorts %>% - dplyr::select(.data$phenotypeId, .data$cohortId) %>% + combis <- cohorts %>% + dplyr::select(.data$phenotypeId, .data$cohortId) %>% + dplyr::distinct() + + combis <- combis %>% + dplyr::rename(targetCohortId = .data$cohortId) %>% + dplyr::inner_join(combis %>% dplyr::rename(comparatorCohortId = .data$cohortId), - by = "phenotypeId") %>% - dplyr::filter(.data$targetCohortId < .data$comparatorCohortId) %>% - dplyr::select(.data$targetCohortId, .data$comparatorCohortId) %>% + by = "phenotypeId") %>% + dplyr::filter(.data$targetCohortId < .data$comparatorCohortId) %>% + dplyr::select(.data$targetCohortId, .data$comparatorCohortId) %>% dplyr::distinct() if (incremental) { - combis <- combis %>% - dplyr::inner_join(dplyr::tibble(targetCohortId = cohorts$cohortId, - targetChecksum = cohorts$checksum), - by = "targetCohortId") %>% - dplyr::inner_join(dplyr::tibble(comparatorCohortId = cohorts$cohortId, - comparatorChecksum = cohorts$checksum), - by = "comparatorCohortId") %>% + combis <- combis %>% + dplyr::inner_join( + dplyr::tibble( + targetCohortId = cohorts$cohortId, + targetChecksum = cohorts$checksum + ), + by = "targetCohortId" + ) %>% + dplyr::inner_join( + dplyr::tibble( + comparatorCohortId = cohorts$cohortId, + comparatorChecksum = cohorts$checksum + ), + by = "comparatorCohortId" + ) %>% dplyr::mutate(checksum = paste(.data$targetChecksum, .data$comparatorChecksum)) } - subset <- subsetToRequiredCombis(combis = combis, - task = "runCohortOverlap", - incremental = incremental, - recordKeepingFile = recordKeepingFile) + subset <- subsetToRequiredCombis( + combis = combis, + task = "runCohortOverlap", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) - if (incremental && (length(combis) - nrow(subset)) > 0) { - ParallelLogger::logInfo(sprintf("Skipping %s cohort combinations in incremental mode.", - length(combis) - nrow(subset))) + if (incremental && (nrow(combis) - nrow(subset)) > 0) { + ParallelLogger::logInfo(sprintf( + "Skipping %s cohort combinations in incremental mode.", + nrow(combis) - nrow(subset) + )) } if (nrow(subset) > 0) { runCohortOverlap <- function(row) { - ParallelLogger::logInfo("- Computing overlap for cohorts ", - row$targetCohortId, - " and ", - row$comparatorCohortId) - data <- computeCohortOverlap(connection = connection, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - targetCohortId = row$targetCohortId, - comparatorCohortId = row$comparatorCohortId) + ParallelLogger::logInfo( + "- Computing overlap for cohorts ", + row$targetCohortId, + " and ", + row$comparatorCohortId + ) + data <- computeCohortOverlap( + connection = connection, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + targetCohortId = row$targetCohortId, + comparatorCohortId = row$comparatorCohortId + ) if (nrow(data) > 0) { - data <- data %>% - dplyr::mutate(targetCohortId = row$targetCohortId, - comparatorCohortId = row$comparatorCohortId) + data <- data %>% + dplyr::mutate( + targetCohortId = row$targetCohortId, + comparatorCohortId = row$comparatorCohortId + ) } return(data) } - data <- lapply(split(subset, 1:nrow(subset)), runCohortOverlap) + data <- + lapply(split(subset, 1:nrow(subset)), runCohortOverlap) data <- dplyr::bind_rows(data) if (nrow(data) > 0) { revData <- data - revData <- swapColumnContents(revData, "targetCohortId", "comparatorCohortId") - revData <- swapColumnContents(revData, "tOnlySubjects", "cOnlySubjects") - revData <- swapColumnContents(revData, "tBeforeCSubjects", "cBeforeTSubjects") - revData <- swapColumnContents(revData, "tInCSubjects", "cInTSubjects") - data <- dplyr::bind_rows(data, revData) %>% + revData <- + swapColumnContents(revData, "targetCohortId", "comparatorCohortId") + revData <- + swapColumnContents(revData, "tOnlySubjects", "cOnlySubjects") + revData <- + swapColumnContents(revData, "tBeforeCSubjects", "cBeforeTSubjects") + revData <- + swapColumnContents(revData, "tInCSubjects", "cInTSubjects") + data <- dplyr::bind_rows(data, revData) %>% dplyr::mutate(databaseId = !!databaseId) - data <- enforceMinCellValue(data, "eitherSubjects", minCellCount) - data <- enforceMinCellValue(data, "bothSubjects", minCellCount) - data <- enforceMinCellValue(data, "tOnlySubjects", minCellCount) - data <- enforceMinCellValue(data, "cOnlySubjects", minCellCount) - data <- enforceMinCellValue(data, "tBeforeCSubjects", minCellCount) - data <- enforceMinCellValue(data, "cBeforeTSubjects", minCellCount) - data <- enforceMinCellValue(data, "sameDaySubjects", minCellCount) - data <- enforceMinCellValue(data, "tInCSubjects", minCellCount) - data <- enforceMinCellValue(data, "cInTSubjects", minCellCount) - data <- data %>% - dplyr::mutate(dplyr::across(.cols = everything(), ~tidyr::replace_na(data = ., replace = 0))) + data <- + enforceMinCellValue(data, "eitherSubjects", minCellCount) + data <- + enforceMinCellValue(data, "bothSubjects", minCellCount) + data <- + enforceMinCellValue(data, "tOnlySubjects", minCellCount) + data <- + enforceMinCellValue(data, "cOnlySubjects", minCellCount) + data <- + enforceMinCellValue(data, "tBeforeCSubjects", minCellCount) + data <- + enforceMinCellValue(data, "cBeforeTSubjects", minCellCount) + data <- + enforceMinCellValue(data, "sameDaySubjects", minCellCount) + data <- + enforceMinCellValue(data, "tInCSubjects", minCellCount) + data <- + enforceMinCellValue(data, "cInTSubjects", minCellCount) + data <- data %>% + dplyr::mutate(dplyr::across(.cols = everything(), ~ tidyr::replace_na( + data = ., replace = 0 + ))) - writeToCsv(data = data, - fileName = file.path(exportFolder, "cohort_overlap.csv"), - incremental = incremental, - targetCohortId = subset$targetCohortId, - comparatorCohortId = subset$comparatorCohortId) + writeToCsv( + data = data, + fileName = file.path(exportFolder, "cohort_overlap.csv"), + incremental = incremental, + targetCohortId = subset$targetCohortId, + comparatorCohortId = subset$comparatorCohortId + ) } - recordTasksDone(cohortId = subset$targetCohortId, - comparatorId = subset$comparatorCohortId, - task = "runCohortOverlap", - checksum = subset$checksum, - recordKeepingFile = recordKeepingFile, - incremental = incremental) + recordTasksDone( + cohortId = subset$targetCohortId, + comparatorId = subset$comparatorCohortId, + task = "runCohortOverlap", + checksum = subset$checksum, + recordKeepingFile = recordKeepingFile, + incremental = incremental + ) } delta <- Sys.time() - startCohortOverlap - ParallelLogger::logInfo("Running Cohort Overlap took ", signif(delta, 3), " ", attr(delta, "units")) + ParallelLogger::logInfo("Running Cohort Overlap took ", + signif(delta, 3), + " ", + attr(delta, "units")) } # Cohort characterization --------------------------------------------------------------- if (runCohortCharacterization) { ParallelLogger::logInfo("Characterizing cohorts") startCohortCharacterization <- Sys.time() - subset <- subsetToRequiredCohorts(cohorts = cohorts %>% - dplyr::filter(.data$cohortId %in% instantiatedCohorts), - task = "runCohortCharacterization", - incremental = incremental, - recordKeepingFile = recordKeepingFile) + subset <- subsetToRequiredCohorts( + cohorts = cohorts %>% + dplyr::filter(.data$cohortId %in% instantiatedCohorts), + task = "runCohortCharacterization", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) - if (incremental && (length(instantiatedCohorts) - nrow(subset)) > 0) { - ParallelLogger::logInfo(sprintf("Skipping %s cohorts in incremental mode.", - length(instantiatedCohorts) - nrow(subset))) + if (incremental && + (length(instantiatedCohorts) - nrow(subset)) > 0) { + ParallelLogger::logInfo(sprintf( + "Skipping %s cohorts in incremental mode.", + length(instantiatedCohorts) - nrow(subset) + )) + } + if (nrow(subset) > 0) { + ParallelLogger::logInfo(sprintf( + "Starting large scale characterization of %s cohort(s)", + nrow(subset) + )) + characteristics <- + getCohortCharacteristics( + connection = connection, + cdmDatabaseSchema = cdmDatabaseSchema, + tempEmulationSchema = tempEmulationSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cohortIds = subset$cohortId, + covariateSettings = covariateSettings, + cdmVersion = cdmVersion + ) + exportCharacterization( + characteristics = characteristics, + databaseId = databaseId, + incremental = incremental, + covariateValueFileName = file.path(exportFolder, "covariate_value.csv"), + covariateValueContFileName = file.path(exportFolder, "covariate_value_dist.csv"), + covariateRefFileName = file.path(exportFolder, "covariate_ref.csv"), + analysisRefFileName = file.path(exportFolder, "analysis_ref.csv"), + counts = cohortCounts, + minCellCount = minCellCount + ) } - if (nrow(subset) > 0) { - ParallelLogger::logInfo(sprintf("Starting large scale characterization of %s cohort(s)", nrow(subset))) - characteristics <- getCohortCharacteristics(connection = connection, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortIds = subset$cohortId, - covariateSettings = covariateSettings, - cdmVersion = cdmVersion) - exportCharacterization(characteristics = characteristics, - databaseId = databaseId, - incremental = incremental, - covariateValueFileName = file.path(exportFolder, "covariate_value.csv"), - covariateRefFileName = file.path(exportFolder, "covariate_ref.csv"), - analysisRefFileName = file.path(exportFolder, "analysis_ref.csv"), - counts = cohortCounts, - minCellCount = minCellCount) - } - recordTasksDone(cohortId = subset$cohortId, - task = "runCohortCharacterization", - checksum = subset$checksum, - recordKeepingFile = recordKeepingFile, - incremental = incremental) + recordTasksDone( + cohortId = subset$cohortId, + task = "runCohortCharacterization", + checksum = subset$checksum, + recordKeepingFile = recordKeepingFile, + incremental = incremental + ) delta <- Sys.time() - startCohortCharacterization - ParallelLogger::logInfo("Running Characterization took ", signif(delta, 3), " ", attr(delta, "units")) + ParallelLogger::logInfo("Running Characterization took ", + signif(delta, 3), + " ", + attr(delta, "units")) } # Temporal Cohort characterization --------------------------------------------------------------- if (runTemporalCohortCharacterization) { ParallelLogger::logInfo("Temporal Cohort characterization") startTemporalCohortCharacterization <- Sys.time() - subset <- subsetToRequiredCohorts(cohorts = cohorts %>% - dplyr::filter(.data$cohortId %in% instantiatedCohorts), - task = "runTemporalCohortCharacterization", - incremental = incremental, - recordKeepingFile = recordKeepingFile) + subset <- subsetToRequiredCohorts( + cohorts = cohorts %>% + dplyr::filter(.data$cohortId %in% instantiatedCohorts), + task = "runTemporalCohortCharacterization", + incremental = incremental, + recordKeepingFile = recordKeepingFile + ) - if (incremental && (length(instantiatedCohorts) - nrow(subset)) > 0) { - ParallelLogger::logInfo(sprintf("Skipping %s cohorts in incremental mode.", - length(instantiatedCohorts) - nrow(subset))) + if (incremental && + (length(instantiatedCohorts) - nrow(subset)) > 0) { + ParallelLogger::logInfo(sprintf( + "Skipping %s cohorts in incremental mode.", + length(instantiatedCohorts) - nrow(subset) + )) } - if (nrow(subset) > 0) { - ParallelLogger::logInfo(sprintf("Starting large scale temporal characterization of %s cohort(s)", nrow(subset)) ) - characteristics <- getCohortCharacteristics(connection = connection, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortIds = subset$cohortId, - covariateSettings = temporalCovariateSettings, - cdmVersion = cdmVersion) - exportCharacterization(characteristics = characteristics, - databaseId = databaseId, - incremental = incremental, - covariateValueFileName = file.path(exportFolder, "temporal_covariate_value.csv"), - covariateRefFileName = file.path(exportFolder, "temporal_covariate_ref.csv"), - analysisRefFileName = file.path(exportFolder, "temporal_analysis_ref.csv"), - timeRefFileName = file.path(exportFolder, "temporal_time_ref.csv"), - counts = cohortCounts, - minCellCount = minCellCount) - } - recordTasksDone(cohortId = subset$cohortId, - task = "runTemporalCohortCharacterization", - checksum = subset$checksum, - recordKeepingFile = recordKeepingFile, - incremental = incremental) + if (nrow(subset) > 0) { + ParallelLogger::logInfo(sprintf( + "Starting large scale temporal characterization of %s cohort(s)", + nrow(subset) + )) + characteristics <- + getCohortCharacteristics( + connection = connection, + cdmDatabaseSchema = cdmDatabaseSchema, + tempEmulationSchema = tempEmulationSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cohortIds = subset$cohortId, + covariateSettings = temporalCovariateSettings, + cdmVersion = cdmVersion + ) + exportCharacterization( + characteristics = characteristics, + databaseId = databaseId, + incremental = incremental, + covariateValueFileName = file.path(exportFolder, "temporal_covariate_value.csv"), + covariateRefFileName = file.path(exportFolder, "temporal_covariate_ref.csv"), + analysisRefFileName = file.path(exportFolder, "temporal_analysis_ref.csv"), + timeRefFileName = file.path(exportFolder, "temporal_time_ref.csv"), + counts = cohortCounts, + minCellCount = minCellCount + ) + } + recordTasksDone( + cohortId = subset$cohortId, + task = "runTemporalCohortCharacterization", + checksum = subset$checksum, + recordKeepingFile = recordKeepingFile, + incremental = incremental + ) delta <- Sys.time() - startTemporalCohortCharacterization - ParallelLogger::logInfo("Running Temporal Characterization took ", signif(delta, 3), " ", attr(delta, "units")) + ParallelLogger::logInfo( + "Running Temporal Characterization took ", + signif(delta, 3), + " ", + attr(delta, "units") + ) } # Store information from the vocabulary on the concepts used ------------------------- ParallelLogger::logInfo("Retrieving concept information") - exportConceptInformation(connection = connection, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - conceptIdTable = "#concept_ids", - incremental = incremental, - exportFolder = exportFolder) + exportConceptInformation( + connection = connection, + cdmDatabaseSchema = cdmDatabaseSchema, + tempEmulationSchema = tempEmulationSchema, + conceptIdTable = "#concept_ids", + incremental = incremental, + exportFolder = exportFolder + ) # Delete unique concept ID table --------------------------------- ParallelLogger::logTrace("Deleting concept ID table") sql <- "TRUNCATE TABLE @table;\nDROP TABLE @table;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - table = "#concept_ids", - progressBar = FALSE, - reportOverallTime = FALSE) + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + table = "#concept_ids", + progressBar = FALSE, + reportOverallTime = FALSE + ) # Add all to zip file ------------------------------------------------------------------------------- ParallelLogger::logInfo("Adding results to zip file") - zipName <- file.path(exportFolder, paste0("Results_", databaseId, ".zip")) + zipName <- + file.path(exportFolder, paste0("Results_", databaseId, ".zip")) files <- list.files(exportFolder, pattern = ".*\\.csv$") oldWd <- setwd(exportFolder) on.exit(setwd(oldWd), add = TRUE) @@ -683,140 +1203,16 @@ runCohortDiagnostics <- function(packageName = NULL, ParallelLogger::logInfo("Results are ready for sharing at: ", zipName) delta <- Sys.time() - start - ParallelLogger::logInfo("Computing all diagnostics took ", signif(delta, 3), " ", attr(delta, "units")) -} - - -loadAndExportPhenotypeDescription <- function(packageName, - phenotypeDescriptionFile, - exportFolder, - cohorts, - errorMessage = NULL) { - if (is.null(errorMessage)) { - errorMessage <- checkmate::makeAssertCollection(errorMessage) - } - pathToCsv <- system.file(phenotypeDescriptionFile, package = packageName) - if (file.exists(pathToCsv)) { - ParallelLogger::logInfo("Found phenotype description file. Loading.") - - checkInputFileEncoding(pathToCsv) - - phenotypeDescription <- readr::read_csv(file = pathToCsv, - col_types = readr::cols(), - na = 'NA', - guess_max = min(1e7)) %>% - dplyr::arrange(.data$phenotypeName, .data$phenotypeId) - - checkmate::assertTibble(x = phenotypeDescription, - any.missing = TRUE, - min.rows = 1, - min.cols = 6, - add = errorMessage) - checkmate::assertNames(x = colnames(phenotypeDescription), - must.include = c("phenotypeId", "phenotypeName", - "referentConceptId", "clinicalDescription", - "literatureReview", "phenotypeNotes"), - add = errorMessage) - checkmate::reportAssertions(collection = errorMessage) - - phenotypeDescription <- phenotypeDescription %>% - dplyr::mutate(phenotypeName = dplyr::coalesce(as.character(.data$phenotypeName),""), - clinicalDescription = dplyr::coalesce(as.character(.data$clinicalDescription),""), - literatureReview = dplyr::coalesce(as.character(.data$literatureReview),""), - phenotypeNotes = dplyr::coalesce(as.character(.data$phenotypeNotes),"") - ) - checkmate::assertTibble(x = phenotypeDescription, - types = c("double", "character")) - checkmate::reportAssertions(collection = errorMessage) - - ParallelLogger::logInfo(sprintf("Phenotype description file has %s rows. Matching with submitted cohorts", - nrow(phenotypeDescription))) - - phenotypeDescription <- phenotypeDescription %>% - dplyr::filter(.data$phenotypeId %in% unique(cohorts$phenotypeId)) - - ParallelLogger::logInfo(sprintf("%s rows matched", nrow(phenotypeDescription))) - - if (nrow(phenotypeDescription) > 0) { - writeToCsv(phenotypeDescription, file.path(exportFolder, "phenotype_description.csv")) - } else { - warning("Phentoype description csv file found, but records dont match the referent concept ids of the cohorts being diagnosed.") - } - return(phenotypeDescription) - } else { - warning("Phentoype description file not found") - return(NULL) - } -} - -exportCharacterization <- function(characteristics, - databaseId, - incremental, - covariateValueFileName, - covariateRefFileName, - analysisRefFileName, - timeRefFileName = NULL, - counts, - minCellCount) { - if (!"covariates" %in% names(characteristics)) { - warning("No characterization output for submitted cohorts") - } else if (dplyr::pull(dplyr::count(characteristics$covariateRef)) > 0) { - characteristics$filteredCovariates <- characteristics$covariates %>% - dplyr::filter(mean >= 0.0001) %>% - dplyr::mutate(databaseId = !!databaseId) %>% - dplyr::left_join(counts, by = c("cohortId", "databaseId"), copy = TRUE) %>% - dplyr::mutate(mean = dplyr::case_when(.data$mean != 0 & .data$mean < minCellCount / .data$cohortEntries ~ -minCellCount / .data$cohortEntries, - TRUE ~ .data$mean)) %>% - dplyr::mutate(sd = dplyr::case_when(.data$mean >= 0 ~ sd)) %>% - dplyr::mutate(mean = round(.data$mean, digits = 4), - sd = round(.data$sd, digits = 4)) %>% - dplyr::select(-.data$cohortEntries, -.data$cohortSubjects) - - if (dplyr::pull(dplyr::count(characteristics$filteredCovariates)) > 0) { - covariateRef <- dplyr::collect(characteristics$covariateRef) - writeToCsv(data = covariateRef, - fileName = covariateRefFileName, - incremental = incremental, - covariateId = covariateRef$covariateId) - analysisRef <- dplyr::collect(characteristics$analysisRef) - writeToCsv(data = analysisRef, - fileName = analysisRefFileName, - incremental = incremental, - analysisId = analysisRef$analysisId) - if (!is.null(timeRefFileName)) { - timeRef <- dplyr::collect(characteristics$timeRef) - writeToCsv(data = timeRef, - fileName = timeRefFileName, - incremental = incremental, - analysisId = timeRef$timeId) - } - writeCovariateDataAndromedaToCsv(data = characteristics$filteredCovariates, - fileName = covariateValueFileName, - incremental = incremental) - } - } -} - -#' Check character encoding of input file -#' -#' @description -#' For its input files, CohortDiagnostics only accepts UTF-8 or ASCII character encoding. This -#' function can be used to check whether a file meets these criteria. -#' -#' @param fileName The path to the file to check -#' -#' @return -#' Throws an error if the input file does not have the correct encoding. -#' -#' @export -checkInputFileEncoding <- function(fileName) { - encoding <- readr::guess_encoding(file = fileName, n_max = min(1e7)) - - if (!encoding$encoding[1] %in% c("UTF-8", "ASCII")) { - stop("Illegal encoding found in file ", - basename(fileName), - ". Should be 'ASCII' or 'UTF-8', found:", - paste(paste0(encoding$encoding, " (", encoding$confidence, ")"), collapse = ", ")) - } - invisible(TRUE) + metaData <- dplyr::tibble( + databaseId = databaseId, + variableField = c('vocabularyVersionCdm', 'vocabularyVersion'), + valueField = c(vocabularyVersionCdm, vocabularyVersion) + ) + writeToCsv(data = metaData, + fileName = "metaData.csv") + + ParallelLogger::logInfo("Computing all diagnostics took ", + signif(delta, 3), + " ", + attr(delta, "units")) } diff --git a/R/RunDiagnosticsExternalCounts.R b/R/RunDiagnosticsExternalCounts.R deleted file mode 100644 index d98fa7ba4..000000000 --- a/R/RunDiagnosticsExternalCounts.R +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics -# -# This file is part of CohortDiagnostics -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -#' Run cohort diagnostics using external concept counts -#' -#' @description -#' Runs cohort diagnostics on all (or a subset of) the cohorts, but using external concept counts. The external counts -#' must have the following columns: -#' -#' \describe{ -#' \item{concept_id}{The source or target concept ID.} -#' \item{concept_count}{The number of records having the concept.} -#' \item{concept_subjects}{The number of unique persons having the concept.} -#' } -#' -#' @template Connection -#' -#' @template CdmDatabaseSchema -#' -#' @template OracleTempSchema -#' -#' @template CohortSetSpecs -#' -#' @template CohortSetReference -#' -#' @param conceptCountsDatabaseSchema Schema name where your concept counts table resides. Note that -#' for SQL Server, this should include both the database and -#' schema name, for example 'scratch.dbo'. Ignored if -#' \code{conceptCountsTableIsTemp = TRUE}. -#' @param conceptCountsTable Name of the concept counts table. -#' @param conceptCountsTableIsTemp Is the concept counts table a temp table? -#' @param exportFolder The folder where the output will be exported to. If this folder -#' does not exist it will be created. -#' @param cohortIds Optionally, provide a subset of cohort IDs to restrict the -#' diagnostics to. -#' @param databaseId A short string for identifying the database (e.g. 'Synpuf'). -#' @param databaseName The full name of the database. -#' @param databaseDescription A short description (several sentences) of the database. -#' @param runIncludedSourceConcepts Generate and export the source concepts included in the cohorts? -#' @param runOrphanConcepts Generate and export potential orphan concepts? -#' @param minCellCount The minimum cell count for fields contains person counts or fractions. -#' -# Disabling because currently doesn't work -# runCohortDiagnosticsUsingExternalCounts <- function(packageName = NULL, -# cohortToCreateFile = "settings/CohortsToCreate.csv", -# baseUrl = NULL, -# cohortSetReference = NULL, -# connectionDetails = NULL, -# connection = NULL, -# cdmDatabaseSchema, -# oracleTempSchema = NULL, -# cohortIds = NULL, -# conceptCountsDatabaseSchema = cdmDatabaseSchema, -# conceptCountsTable = "concept_counts", -# conceptCountsTableIsTemp = FALSE, -# exportFolder, -# databaseId, -# databaseName = databaseId, -# databaseDescription = "", -# runIncludedSourceConcepts = TRUE, -# runOrphanConcepts = TRUE, -# minCellCount = 5) { -# if (is.null(packageName) && is.null(baseUrl)) { -# stop("Must provide either packageName and cohortToCreateFile, or baseUrl and cohortSetReference") -# } -# if (!is.null(cohortSetReference)) { -# if (is.null(cohortSetReference$atlasId)) -# stop("cohortSetReference must contain atlasId field") -# if (is.null(cohortSetReference$atlasName)) -# stop("cohortSetReference must contain atlasName field") -# if (is.null(cohortSetReference$cohortId)) -# stop("cohortSetReference must contain cohortId field") -# if (is.null(cohortSetReference$name)) -# stop("cohortSetReference must contain name field") -# } -# -# start <- Sys.time() -# if (!file.exists(exportFolder)) { -# dir.create(exportFolder) -# } -# -# if (is.null(connection)) { -# connection <- DatabaseConnector::connect(connectionDetails) -# on.exit(DatabaseConnector::disconnect(connection)) -# } -# -# cohorts <- getCohortsJsonAndSql(packageName = packageName, -# cohortToCreateFile = cohortToCreateFile, -# baseUrl = baseUrl, -# cohortSetReference = cohortSetReference, -# cohortIds = cohortIds) -# -# writeToCsv(cohorts, file.path(exportFolder, "cohort.csv")) -# -# ParallelLogger::logInfo("Saving database metadata") -# database <- data.frame(databaseId = databaseId, -# databaseName = databaseName, -# description = databaseDescription, -# isMetaAnalysis = 0) -# writeToCsv(database, file.path(exportFolder, "database.csv")) -# if (runIncludedSourceConcepts || runOrphanConcepts) { -# runConceptSetDiagnostics(connection = connection, -# oracleTempSchema = oracleTempSchema, -# cdmDatabaseSchema = cdmDatabaseSchema, -# databaseId = databaseId, -# cohorts = cohorts, -# runIncludedSourceConcepts = runIncludedSourceConcepts, -# runOrphanConcepts = runOrphanConcepts, -# exportFolder = exportFolder, -# minCellCount = minCellCount, -# conceptCountsDatabaseSchema = conceptCountsDatabaseSchema, -# conceptCountsTable = conceptCountsTable, -# conceptCountsTableIsTemp = conceptCountsTableIsTemp, -# useExternalConceptCountsTable = TRUE) -# } -# -# # Add all to zip file ------------------------------------------------------------------------------- -# ParallelLogger::logInfo("Adding results to zip file") -# zipName <- file.path(exportFolder, paste0("Results_", databaseId, ".zip")) -# files <- list.files(exportFolder, pattern = ".*\\.csv$") -# oldWd <- setwd(exportFolder) -# on.exit(setwd(oldWd), add = TRUE) -# DatabaseConnector::createZipFile(zipFile = zipName, files = files) -# ParallelLogger::logInfo("Results are ready for sharing at:", zipName) -# -# delta <- Sys.time() - start -# ParallelLogger::logInfo(paste("Computing all diagnostics took", -# signif(delta, 3), -# attr(delta, "units"))) -# } - diff --git a/R/Shiny.R b/R/Shiny.R index 7f44016fe..3f098c18a 100644 --- a/R/Shiny.R +++ b/R/Shiny.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,51 +18,80 @@ #' @param connectionDetails An object of type \code{connectionDetails} as created using the #' \code{\link[DatabaseConnector]{createConnectionDetails}} function in the #' DatabaseConnector package, specifying how to connect to the server where -#' the CohortDiagnostics results have been uploaded using the +#' the CohortDiagnostics results have been uploaded using the #' \code{\link{uploadResults}} function. -#' @param resultsDatabaseSchema The schema on the database server where the CohortDiagnostics results -#' have been uploaded. -#' @param vocabularyDatabaseSchema The schema on the database server where the vocabulary tables are located. +#' @param resultsDatabaseSchema The schema on the database server where the CohortDiagnostics results +#' have been uploaded. +#' @param vocabularyDatabaseSchema (Deprecated) Please use vocabularyDatabaseSchemas. +#' @param vocabularyDatabaseSchemas (optional) A list of one or more schemas on the database server where the vocabulary tables are located. +#' The default value is the value of the resultsDatabaseSchema. We can provide a list of vocabulary schema +#' that might represent different versions of the OMOP vocabulary tables. It allows us to compare the impact +#' of vocabulary changes on Diagnostics. #' @param dataFolder A folder where the premerged file is stored. Use #' the \code{\link{preMergeDiagnosticsFiles}} function to generate this file. +#' @param dataFile (Optional) The name of the .RData file with results. It is commonly known as the +#' Premerged file. #' @param runOverNetwork (optional) Do you want the app to run over your network? -#' @param port (optional) Only used if \code{runOverNetwork} = TRUE. +#' @param port (optional) Only used if \code{runOverNetwork} = TRUE. #' @param launch.browser Should the app be launched in your default browser, or in a Shiny window. #' Note: copying to clipboard will not work in a Shiny window. -#' @param cohortBaseUrl The base URL for constructing linkouts to an ATLAS instance, using the -#' webApiCohortId in the cohortsToCreate file. If NULL, no linkouts will be -#' created. -#' @param conceptBaseUrl The base URL for constructing linkouts to an Athena instance, using the -#' concept ID. +#' @param aboutText Text (using HTML markup) that will be displayed in an About tab in the Shiny app. +#' If not provided, no About tab will be shown. #' #' @details #' Launches a Shiny app that allows the user to explore the diagnostics #' #' @export -launchDiagnosticsExplorer <- function(dataFolder = "data", +launchDiagnosticsExplorer <- function(dataFolder = "data", + dataFile = "PreMerged.RData", connectionDetails = NULL, resultsDatabaseSchema = NULL, - vocabularyDatabaseSchema = resultsDatabaseSchema, - cohortBaseUrl = "https://atlas.ohdsi.org/#/cohortdefinition/", - conceptBaseUrl = "https://athena.ohdsi.org/search-terms/terms/", + vocabularyDatabaseSchema = NULL, + vocabularyDatabaseSchemas = resultsDatabaseSchema, + aboutText = NULL, runOverNetwork = FALSE, port = 80, launch.browser = FALSE) { - if (!is.null(connectionDetails) && connectionDetails$dbms != "postgresql") + if (!is.null(connectionDetails) && + connectionDetails$dbms != "postgresql") { stop("Shiny application can only run against a Postgres database") + } + if (!is.null(connectionDetails)) { + dataFolder <- NULL + dataFile <- NULL + if (is.null(resultsDatabaseSchema)) { + stop("resultsDatabaseSchema is required to connect to the database.") + } + if (!is.null(vocabularyDatabaseSchema) & + is.null(vocabularyDatabaseSchemas)) { + vocabularyDatabaseSchemas <- vocabularyDatabaseSchema + warning( + 'vocabularyDatabaseSchema option is deprecated. Please use vocabularyDatabaseSchema.' + ) + } + } - ensure_installed("shiny") - ensure_installed("shinydashboard") - ensure_installed("shinyWidgets") + ensure_installed("checkmate") + ensure_installed("DatabaseConnector") + ensure_installed("dplyr") ensure_installed("DT") + ensure_installed("ggplot2") + ensure_installed("ggiraph") + ensure_installed("gtable") ensure_installed("htmltools") + ensure_installed("lubridate") + ensure_installed("pool") + ensure_installed("purrr") ensure_installed("scales") - ensure_installed("plotly") - ensure_installed("dplyr") + ensure_installed("shiny") + ensure_installed("shinydashboard") + ensure_installed("shinyWidgets") + ensure_installed("stringr") + ensure_installed("SqlRender") ensure_installed("tidyr") - ensure_installed("ggiraph") - - appDir <- system.file("shiny", "DiagnosticsExplorer", package = "CohortDiagnostics") + + appDir <- + system.file("shiny", "DiagnosticsExplorer", package = "CohortDiagnostics") if (launch.browser) { options(shiny.launch.browser = TRUE) @@ -75,122 +104,150 @@ launchDiagnosticsExplorer <- function(dataFolder = "data", options(shiny.port = port) options(shiny.host = myIpAddress) } - shinySettings <- list(connectionDetails = connectionDetails, - resultsDatabaseSchema = resultsDatabaseSchema, - vocabularyDatabaseSchema = vocabularyDatabaseSchema, - dataFolder = dataFolder, - cohortBaseUrl = cohortBaseUrl, - conceptBaseUrl = conceptBaseUrl) + shinySettings <- list( + connectionDetails = connectionDetails, + resultsDatabaseSchema = resultsDatabaseSchema, + vocabularyDatabaseSchemas = vocabularyDatabaseSchemas, + dataFolder = dataFolder, + dataFile = dataFile, + aboutText = aboutText + ) .GlobalEnv$shinySettings <- shinySettings on.exit(rm("shinySettings", envir = .GlobalEnv)) shiny::runApp(appDir = appDir) } #' Premerge Shiny diagnostics files -#' -#' @description +#' +#' @description #' This function combines diagnostics results from one or more databases into a single file. The result is a #' single file that can be used as input for the Diagnostics Explorer Shiny app. -#' +#' #' It also checks whether the results conform to the results data model specifications. #' #' @param dataFolder folder where the exported zip files for the diagnostics are stored. Use -#' the \code{\link{runCohortDiagnostics}} function to generate these zip files. +#' the \code{\link{runCohortDiagnostics}} function to generate these zip files. #' Zip files containing results from multiple databases may be placed in the same -#' folder. +#' folder. #' @param tempFolder A folder on the local file system where the zip files are extracted to. Will be cleaned #' up when the function is finished. Can be used to specify a temp folder on a drive that #' has sufficient space if the default system temp space is too limited. -#' +#' #' @export -preMergeDiagnosticsFiles <- function(dataFolder, tempFolder = tempdir()) { - - zipFiles <- dplyr::tibble(zipFile = list.files(dataFolder, pattern = ".zip", full.names = TRUE, recursive = TRUE), - unzipFolder = "") - ParallelLogger::logInfo("Merging ", nrow(zipFiles), " zip files.") - - unzipMainFolder <- tempfile("unzipTempFolder", tmpdir = tempFolder) - dir.create(path = unzipMainFolder, recursive = TRUE) - on.exit(unlink(unzipMainFolder, recursive = TRUE)) - - for (i in 1:nrow(zipFiles)) { - ParallelLogger::logInfo("- Unzipping ", basename(zipFiles$zipFile[i])) - unzipFolder <- file.path(unzipMainFolder, sub(".zip", "", basename(zipFiles$zipFile[i]))) - dir.create(unzipFolder) - zip::unzip(zipFiles$zipFile[i], exdir = unzipFolder) - zipFiles$unzipFolder[i] <- unzipFolder - } +preMergeDiagnosticsFiles <- + function(dataFolder, tempFolder = tempdir()) { + zipFiles <- + dplyr::tibble( + zipFile = list.files( + dataFolder, + pattern = ".zip", + full.names = TRUE, + recursive = TRUE + ), + unzipFolder = "" + ) + ParallelLogger::logInfo("Merging ", nrow(zipFiles), " zip files.") + + unzipMainFolder <- + tempfile("unzipTempFolder", tmpdir = tempFolder) + dir.create(path = unzipMainFolder, recursive = TRUE) + on.exit(unlink(unzipMainFolder, recursive = TRUE)) - specifications = getResultsDataModelSpecifications() - - # Storing output in an environment for now. If things get too big, we may want to write - # directly to CSV files for insertion into database: - newEnvironment <- new.env() - - processTable <- function(tableName, env) { - ParallelLogger::logInfo("Processing table ", tableName) - csvFileName <- paste0(tableName, ".csv") - data <- dplyr::tibble() for (i in 1:nrow(zipFiles)) { - if (csvFileName %in% list.files(zipFiles$unzipFolder[i])) { - newData <- readr::read_csv(file.path(zipFiles$unzipFolder[i], csvFileName), - col_types = readr::cols(), - guess_max = min(1e6)) - if (nrow(newData) > 0) { - checkColumnNames(table = newData, - tableName = tableName, - zipFileName = zipFiles$zipFile[i], - specifications = specifications) - newData <- checkAndFixDataTypes(table = newData, - tableName = tableName, - zipFileName = zipFiles$zipFile[i], - specifications = specifications) - newData <- checkAndFixDuplicateRows(table = newData, - tableName = tableName, - zipFileName = zipFiles$zipFile[i], - specifications = specifications) - data <- appendNewRows(data = data, - newData = newData, - tableName = tableName, - specifications = specifications) - + ParallelLogger::logInfo("- Unzipping ", basename(zipFiles$zipFile[i])) + unzipFolder <- + file.path(unzipMainFolder, sub(".zip", "", basename(zipFiles$zipFile[i]))) + dir.create(unzipFolder) + zip::unzip(zipFiles$zipFile[i], exdir = unzipFolder) + zipFiles$unzipFolder[i] <- unzipFolder + } + + specifications <- getResultsDataModelSpecifications() + + # Storing output in an environment for now. If things get too big, we may want to write + # directly to CSV files for insertion into database: + newEnvironment <- new.env() + + processTable <- function(tableName, env) { + ParallelLogger::logInfo("Processing table ", tableName) + csvFileName <- paste0(tableName, ".csv") + data <- dplyr::tibble() + for (i in 1:nrow(zipFiles)) { + if (csvFileName %in% list.files(zipFiles$unzipFolder[i])) { + newData <- + readr::read_csv( + file.path(zipFiles$unzipFolder[i], csvFileName), + col_types = readr::cols(), + guess_max = min(1e6) + ) + if (nrow(newData) > 0) { + newData <- checkFixColumnNames( + table = newData, + tableName = tableName, + zipFileName = zipFiles$zipFile[i], + specifications = specifications + ) + newData <- checkAndFixDataTypes( + table = newData, + tableName = tableName, + zipFileName = zipFiles$zipFile[i], + specifications = specifications + ) + newData <- checkAndFixDuplicateRows( + table = newData, + tableName = tableName, + zipFileName = zipFiles$zipFile[i], + specifications = specifications + ) + data <- appendNewRows( + data = data, + newData = newData, + tableName = tableName, + specifications = specifications + ) + + } } } + if (nrow(data) == 0) { + ParallelLogger::logInfo("- No data found for table ", tableName) + } else { + colnames(data) <- SqlRender::snakeCaseToCamelCase(colnames(data)) + assign(SqlRender::snakeCaseToCamelCase(tableName), + data, + envir = env) + } } - if (nrow(data) == 0) { - ParallelLogger::logInfo("- No data found for table ", tableName) - } else { - colnames(data) <- SqlRender::snakeCaseToCamelCase(colnames(data)) - assign(SqlRender::snakeCaseToCamelCase(tableName), data, envir = env) - } + invisible(lapply(unique(specifications$tableName), processTable, env = newEnvironment)) + ParallelLogger::logInfo("Creating PreMerged.Rdata file. This might take some time.") + save( + list = ls(newEnvironment), + envir = newEnvironment, + compress = TRUE, + compression_level = 2, + file = file.path(dataFolder, "PreMerged.RData") + ) + rm(list = ls(newEnvironment), envir = newEnvironment) + ParallelLogger::logInfo("Merged data saved in ", + file.path(dataFolder, "PreMerged.RData")) } - invisible(lapply(unique(specifications$tableName), processTable, env = newEnvironment)) - ParallelLogger::logInfo("Creating PreMerged.Rdata file. This might take some time.") - save(list = ls(newEnvironment), - envir = newEnvironment, - compress = TRUE, - compression_level = 2, - file = file.path(dataFolder, "PreMerged.RData")) - rm(list = ls(newEnvironment), envir = newEnvironment) - ParallelLogger::logInfo("Merged data saved in ", file.path(dataFolder, "PreMerged.RData")) -} #' Launch the CohortExplorer Shiny app -#' +#' #' @template CohortTable -#' +#' #' @template CdmDatabaseSchema -#' +#' #' @param connectionDetails An object of type \code{connectionDetails} as created using the #' \code{\link[DatabaseConnector]{createConnectionDetails}} function in the #' DatabaseConnector package. #' @param cohortId The ID of the cohort. #' @param sampleSize Number of subjects to sample from the cohort. Ignored if subjectIds is specified. #' @param subjectIds A vector of subject IDs to view. -#' -#' @details +#' +#' @details #' Launches a Shiny app that allows the user to explore a cohort of interest. -#' +#' #' @export launchCohortExplorer <- function(connectionDetails, cdmDatabaseSchema, @@ -203,30 +260,43 @@ launchCohortExplorer <- function(connectionDetails, ensure_installed("DT") ensure_installed("plotly") ensure_installed("RColorBrewer") - .GlobalEnv$shinySettings <- list(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortId = cohortId, - sampleSize = sampleSize, - subjectIds = subjectIds) + ensure_installed("ggplot2") + ensure_installed("magrittr") + + .GlobalEnv$shinySettings <- + list( + connectionDetails = connectionDetails, + cdmDatabaseSchema = cdmDatabaseSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cohortDefinitionId = cohortId, + sampleSize = sampleSize, + subjectIds = subjectIds + ) on.exit(rm("shinySettings", envir = .GlobalEnv)) - appDir <- system.file("shiny", "CohortExplorer", package = "CohortDiagnostics") + appDir <- + system.file("shiny", "CohortExplorer", package = "CohortDiagnostics") shiny::runApp(appDir) } # Borrowed from devtools: # https://github.com/hadley/devtools/blob/ba7a5a4abd8258c52cb156e7b26bb4bf47a79f0b/R/utils.r#L44 is_installed <- function(pkg, version = 0) { - installed_version <- tryCatch(utils::packageVersion(pkg), error = function(e) NA) - !is.na(installed_version) && installed_version >= version + installed_version <- + tryCatch( + utils::packageVersion(pkg), + error = function(e) + NA + ) + ! is.na(installed_version) && installed_version >= version } # Borrowed and adapted from devtools: # https://github.com/hadley/devtools/blob/ba7a5a4abd8258c52cb156e7b26bb4bf47a79f0b/R/utils.r#L74 ensure_installed <- function(pkg) { if (!is_installed(pkg)) { - msg <- paste0(sQuote(pkg), " must be installed for this functionality.") + msg <- + paste0(sQuote(pkg), " must be installed for this functionality.") if (interactive()) { message(msg, "\nWould you like to install it?") if (menu(c("Yes", "No")) == 1) { diff --git a/R/TimeDistributions.R b/R/TimeDistributions.R index 4b604911d..a64189365 100644 --- a/R/TimeDistributions.R +++ b/R/TimeDistributions.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,45 +17,58 @@ getTimeDistributions <- function(connectionDetails = NULL, connection = NULL, cdmDatabaseSchema, - oracleTempSchema = NULL, + tempEmulationSchema = NULL, cohortDatabaseSchema = cdmDatabaseSchema, cohortTable = "cohort", cohortIds, cdmVersion = 5) { - start <- Sys.time() if (is.null(connection)) { connection <- DatabaseConnector::connect(connectionDetails) on.exit(DatabaseConnector::disconnect(connection)) } - - covariateSettings <- FeatureExtraction::createCovariateSettings(useDemographicsPriorObservationTime = TRUE, - useDemographicsPostObservationTime = TRUE, - useDemographicsTimeInCohort = TRUE) - data <- FeatureExtraction::getDbCovariateData(connection = connection, - oracleTempSchema = oracleTempSchema, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortId = cohortIds, - covariateSettings = covariateSettings, - cdmVersion = cdmVersion, - aggregated = TRUE) + covariateSettings <- + FeatureExtraction::createCovariateSettings( + useDemographicsPriorObservationTime = TRUE, + useDemographicsPostObservationTime = TRUE, + useDemographicsTimeInCohort = TRUE + ) + + data <- + FeatureExtraction::getDbCovariateData( + connection = connection, + oracleTempSchema = tempEmulationSchema, + cdmDatabaseSchema = cdmDatabaseSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + cohortId = cohortIds, + covariateSettings = covariateSettings, + cdmVersion = cdmVersion, + aggregated = TRUE + ) if (is.null(data$covariatesContinuous)) { result <- tidyr::tibble() } else { result <- data$covariatesContinuous %>% dplyr::inner_join(data$covariateRef, by = "covariateId") %>% - dplyr::select(-.data$conceptId, -.data$analysisId, -.data$covariateId, -.data$result$countValue) %>% + dplyr::select( + -.data$conceptId, + -.data$analysisId, + -.data$covariateId, + -.data$result$countValue + ) %>% dplyr::rename(timeMetric = .data$covariateName, cohortId = .data$cohortDefinitionId) %>% dplyr::collect() } attr(result, "cohortSize") <- data$metaData$populationSize delta <- Sys.time() - start - ParallelLogger::logInfo("Computing time distributions took ", signif(delta, 3), " ", attr(delta, "units")) + ParallelLogger::logInfo("Computing time distributions took ", + signif(delta, 3), + " ", + attr(delta, "units")) return(result) } diff --git a/R/VisitContext.R b/R/VisitContext.R index e68e71cdf..124415c43 100644 --- a/R/VisitContext.R +++ b/R/VisitContext.R @@ -1,13 +1,13 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,12 +17,15 @@ getVisitContext <- function(connectionDetails = NULL, connection = NULL, cdmDatabaseSchema, - oracleTempSchema = NULL, + tempEmulationSchema = NULL, cohortDatabaseSchema = cdmDatabaseSchema, cohortTable = "cohort", cohortIds, conceptIdTable = NULL, cdmVersion = 5) { + if (!cdmVersion == 5) { + warning('Only OMOP CDM v5.x.x is supported. Continuing execution.') + } start <- Sys.time() @@ -31,44 +34,57 @@ getVisitContext <- function(connectionDetails = NULL, on.exit(DatabaseConnector::disconnect(connection)) } - sql <- SqlRender::loadRenderTranslateSql("VisitContext.sql", - packageName = "CohortDiagnostics", - dbms = connection@dbms, - oracleTempSchema = oracleTempSchema, - visit_context_table = "#visit_context", - cdm_database_schema = cdmDatabaseSchema, - cohort_database_schema = cohortDatabaseSchema, - cohort_table = cohortTable, - cohort_ids = cohortIds) + sql <- SqlRender::loadRenderTranslateSql( + "VisitContext.sql", + packageName = "CohortDiagnostics", + dbms = connection@dbms, + tempEmulationSchema = tempEmulationSchema, + visit_context_table = "#visit_context", + cdm_database_schema = cdmDatabaseSchema, + cohort_database_schema = cohortDatabaseSchema, + cohort_table = cohortTable, + cohort_ids = cohortIds + ) DatabaseConnector::executeSql(connection, sql) sql <- "SELECT * FROM @visit_context_table;" - visitContext <- DatabaseConnector::renderTranslateQuerySql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - visit_context_table = "#visit_context", - snakeCaseToCamelCase = TRUE) + visitContext <- + DatabaseConnector::renderTranslateQuerySql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + visit_context_table = "#visit_context", + snakeCaseToCamelCase = TRUE + ) if (!is.null(conceptIdTable)) { sql <- "INSERT INTO @unique_concept_id_table (concept_id) SELECT DISTINCT visit_concept_id FROM @visit_context_table;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - unique_concept_id_table = conceptIdTable, - visit_context_table = "#visit_context", - progressBar = FALSE, - reportOverallTime = FALSE) + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + unique_concept_id_table = conceptIdTable, + visit_context_table = "#visit_context", + progressBar = FALSE, + reportOverallTime = FALSE + ) } - sql <- "TRUNCATE TABLE @visit_context_table;\nDROP TABLE @visit_context_table;" - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql, - oracleTempSchema = oracleTempSchema, - visit_context_table = "#visit_context", - progressBar = FALSE, - reportOverallTime = FALSE) + sql <- + "TRUNCATE TABLE @visit_context_table;\nDROP TABLE @visit_context_table;" + DatabaseConnector::renderTranslateExecuteSql( + connection = connection, + sql = sql, + tempEmulationSchema = tempEmulationSchema, + visit_context_table = "#visit_context", + progressBar = FALSE, + reportOverallTime = FALSE + ) delta <- Sys.time() - start - ParallelLogger::logInfo("Retrieving visit context took ", signif(delta, 3), " ", attr(delta, "units")) + ParallelLogger::logInfo("Retrieving visit context took ", + signif(delta, 3), + " ", + attr(delta, "units")) return(visitContext) } diff --git a/README.md b/README.md index 085342ef0..53268a072 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ CohortDiagnostics ================= -[![Build Status](https://travis-ci.org/OHDSI/CohortDiagnostics.svg?branch=master)](https://travis-ci.org/OHDSI/CohortDiagnostics) +[![Build Status](https://github.com/OHDSI/CohortDiagnostics/workflows/R-CMD-check/badge.svg)](https://github.com/OHDSI/CohortDiagnostics/actions?query=workflow%3AR-CMD-check) [![codecov.io](https://codecov.io/github/OHDSI/CohortDiagnostics/coverage.svg?branch=master)](https://codecov.io/github/OHDSI/CohortDiagnostics?branch=master) CohortDiagnostics is part of [HADES](https://ohdsi.github.io/Hades). @@ -18,7 +18,7 @@ Features - Compute cohort incidence across calendar years, age, and gender. - Break down index events into the specific concepts that triggered them. - Compute overlap between two cohorts. -- Characterize cohorts, and compare these characterizations. +- Characterize cohorts, and compare these characterizations. Perform cohort comparison and temporal comparisons. - Explore patient profiles of a random sample of subjects in a cohort. Screenshot @@ -41,7 +41,7 @@ Installation 2. In R, use the following commands to download and install CohortDiagnostics: ```r - remotes::install.github("OHDSI/CohortDiagnostics") + remotes::install_github("OHDSI/CohortDiagnostics") ``` User Documentation @@ -50,7 +50,13 @@ Documentation can be found on the [package website](https://ohdsi.github.io/Coho PDF versions of the documentation are also available: * Package manual: [CohortDiagnostics manual](https://raw.githubusercontent.com/OHDSI/CohortDiagnostics/master/extras/CohortDiagnostics.pdf) +* Vignette: [What is Cohort Diagnostics](https://raw.githubusercontent.com/OHDSI/CohortDiagnostics/master/inst/doc/WhatIsCohortDiagnostics.pdf) +* Vignette: [Running Cohort Diagnostics](https://raw.githubusercontent.com/OHDSI/CohortDiagnostics/master/inst/doc/RunningCohortDiagnostics.pdf) * Vignette: [Running cohort diagnostics using WebAPI](https://raw.githubusercontent.com/OHDSI/CohortDiagnostics/master/inst/doc/CohortDiagnosticsUsingWebApi.pdf) +* Vignette: [Running cohort diagnostics in OHDSI Package mode WebAPI](https://raw.githubusercontent.com/OHDSI/CohortDiagnostics/master/inst/doc/CohortDiagnosticsInPackageMode.pdf) +* Vignette: [Running cohort diagnostics using WebApi WebAPI](https://raw.githubusercontent.com/OHDSI/CohortDiagnostics/master/inst/doc/CohortDiagnosticsUsingWebApi.pdf) +* Vignette: [Database Mode in Diagnostics Explorer](https://raw.githubusercontent.com/OHDSI/CohortDiagnostics/master/inst/doc/DatabaseModeInDiagnosticsExplorer.pdf) + Support ======= @@ -71,4 +77,4 @@ CohortDiagnostics is being developed in R Studio. ### Development status -Beta testing +Stable diff --git a/compare_versions b/compare_versions index 0d451b2b7..4fe88e201 100644 --- a/compare_versions +++ b/compare_versions @@ -9,8 +9,6 @@ $r_major = $1; $r_minor = $2; $r_mod = $3; -print "New R version: $r_major-$r_minor-$r_mod\n"; - open(GIT_VERSION, "git describe --tags |"); $git = ; close(GIT_VERSION); @@ -20,49 +18,10 @@ $git_major = $1; $git_minor = $2; $git_mod = $3; -print "Current git version: $git_major-$git_minor-$git_mod\n"; - if ($r_major > $git_major || $r_minor > $git_minor || $r_mod > $git_mod) { - $monotonic = 0; + $new_version = "v$r_major.$r_minor.$r_mod"; } else { - $monotonic = -1; -} - -if ($monotonic != 0) { - print "Non-monotonically increasing versions numbers\n"; -} - -if ($monotonic == 0 & $ARGV[0] eq "--tag") { - - open(GIT_TAG, "git tag v$r_major.$r_minor.$r_mod |"); - - $fail = 0; - while ($line = ) { - if ($line =~ /fatal/) { - $fail = 1; - } - print "tag: $line"; - } # TODO Check for errors - close(GIT_TAG); - print "tag: END\n\n"; - - if ($fail eq 1) { - exit(-1); - } - - $cmd = "git config user.name \"Marc A. Suchard\"; " . - "git config user.email \"msuchard@ucla.edu\"; " . - "git tag v$r_major.$r_minor.$r_mod ; " . - "git push -q https://\$GH_TOKEN\@github.com/OHDSI/\$PKG_NAME.git --tags"; - - print "cmd: $cmd\n"; - - open(GIT_PUSH, "$cmd |"); - while ($line = ) { - print "push: $line"; - } # TODO Check for errors - close(GIT_PUSH); - print "push: END\n\n"; + $new_version = ""; } -exit($monotonic); +print($new_version); \ No newline at end of file diff --git a/deploy.sh b/deploy.sh index 2b0529b46..9d0891b43 100644 --- a/deploy.sh +++ b/deploy.sh @@ -3,12 +3,15 @@ set -o errexit -o nounset addToDrat(){ PKG_REPO=$PWD + ## Build package tar ball + export PKG_TARBALL=$(ls *.tar.gz) + cd ..; mkdir drat; cd drat ## Set up Repo parameters git init - git config user.name "Marc A. Suchard" - git config user.email "msuchard@ucla.edu" + git config user.name "Martijn Schuemie" + git config user.email "schuemie@ohdsi.org" git config --global push.default simple ## Get drat repo @@ -16,15 +19,13 @@ addToDrat(){ git fetch upstream 2>err.txt git checkout gh-pages - ## Use cached packages - mkdir -p ~/Rlib + ## Link to local R packages echo 'R_LIBS=~/Rlib' > .Renviron - - ## Deploy + Rscript -e "drat::insertPackage('$PKG_REPO/$PKG_TARBALL', \ repodir = '.', \ - commit='Travis update: $PKG_TARBALL build $TRAVIS_BUILD_NUMBER')" + commit='GitHub Actions release: $PKG_TARBALL run $GITHUB_RUN_ID')" git push } -addToDrat +addToDrat \ No newline at end of file diff --git a/docs/404.html b/docs/404.html index f31c87296..6ff85f0db 100644 --- a/docs/404.html +++ b/docs/404.html @@ -71,7 +71,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -79,7 +79,7 @@ @@ -108,7 +123,7 @@
  • - +
  • @@ -144,11 +159,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/articles/CohortDiagnosticsInPackageMode.html b/docs/articles/CohortDiagnosticsInPackageMode.html new file mode 100644 index 000000000..63f97e287 --- /dev/null +++ b/docs/articles/CohortDiagnosticsInPackageMode.html @@ -0,0 +1,266 @@ + + + + + + + +Runing Cohort Diagnostics in an OHDSI Package mode • CohortDiagnostics + + + + + + + + + + +
    +
    + + + + +
    +
    + + + + +
    +

    +Introduction

    +

    There are currently two approaches to run Cohort Diagnostics. - Embed in an OHDSI study package, where all the cohort definitions are stored as part of that study package, or - WebAPi mode - where cohort diagnostics dynamically pulls the cohort definition from a webapi instance. WebAPI is the backend of the OHDSI ATLAS application, allowing programmatic access to the cohort definitions created in ATLAS.

    +

    This vignette describes the former approach (package): how to run CohortDiagnostics using the WebAPI.

    +

    There are currently two approaches one can take to step 1: The cohort diagnostics can be embedded in an OHDSI study package, where all the cohort definitions are stored as part of that study package, or the cohort diagnostics can be used as a stand-alone solution, relying on a WebAPI instance to provide the cohort definitions. WebAPI is the backend of the OHDSI ATLAS application, allowing programmatic access to the cohort definitions created in ATLAS. This vignette describes the latter approach: how to run CohortDiagnostics using the WebAPI.

    +

    This vignette describes how to create a self contained shareable study package that can execute cohort diagnostics on a given set of cohort definitions. This is the recommended mode to run CohortDiagnostics for a study.

    +

    In this vignette, you will learn how to - use the Cohort Diagnostics template package - Hydrate the template package with the cohort definitions you want to diagnose. - Execute the diagnostics on one or more data sources. - Review the result set using the Diagnostics Explorer R shiny app of Cohort Diagnostics - (optional) Submit the results of your cohort diagnostics to the OHDSI Phenotype library.

    +
    +

    +Assumptions:

    +
      +
    • You have a set of valid cohort definition sql files (in parameterized OHDSI Sql format) that you want to run diagnostics on, or you are able to export cohort definitions that you want to diagnose from Atlas by using the export tab within cohort definition module of Atlas or using ROhdsiWebApi as described here.
    • +
    • You have access to person level data in OMOP CDM V5.x + format on a database, are able to execute and instantiate cohorts in cohort tables (i.e. you have access to a schema in the same database with Create, Read, Update, Delete privileges.)
    • +
    +
    +
    +
    +

    +Creating the study package

    +

    The cohorts to diagnose should have two attributes to them.

    +
      +
    • +id: A unique integer identifier for the cohort you are diagnosing. If you created your cohort using atlas, this is your atlas id.
    • +
    • +cohortName: The unique string name for your cohort. Usually it is the same as your Atlas cohort name, but it can be any name you wish to identify your cohort. This name will be used to display your cohort in the Diagnostics Explorer shiny app.
    • +
    +

    Example:

    + ++++ + + + + + + + + +
    idcohortName
    17561[PL 4112853001] Malignant tumor of breast referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation
    +
    +

    +option A: Using Hydra and ROhdsiWebApi

    +

    Note: this option is expected to be available starting version 2.2 of CohortDiagnostics. It is currently possible to do the steps described below, but is not fully tested.

    +

    The skeleton cohort diagnostics study package is here. A skeleton package is a special package that is designed to be used with Hydra. The input for Hydra is study a specifications file (in json format). Example is here.

    +

    We can create this json using the shiny app ‘Diagnostics Editor’ available here(XX– to do –XXXX). A version is deployed at data.ohdsi.org/XXXXXXXXXXXXX. The user interface of this shiny app allows you to make selections that are then used to create the specifications json file. The application also allows you to hydrate a package using Hydra, and download a .zip that contains your study package.

    +

    Alternatively, you can take the example specification-json file and edit it in notepad. You can then use to create the study package as follows

    +

    XXX—to do—XXXXXXx

    +

    Now you may install your package and execute the study.

    +
    +
    +

    +option B: using only ROhdsiWebApi

    +

    Start with the skeleton cohort diagnostics study package is here. See Vignette from ROhdsiWebApi here. Create the ‘CohortsToCreate.csv’ file by extracting the cohorts from your atlas as described. Now, open your study package and run

    +
    +ROhdsiWebApi::insertCohortDefinitionSetInPackage(fileName = "CohortsToCreate.csv",
    +                                                 baseUrl = Sys.getenv("baseUrl"),
    +                                                 insertTableSql = TRUE,
    +                                                 insertCohortCreationR = TRUE,
    +                                                 generateStats = TRUE,
    +                                                 packageName = "SkeletonCohortDiagnosticsStudy")
    +

    This will create the relevant files in your package.

    +

    The next step is to rename the generic name of the package ‘SkeletonCohortDiagnosticsStudy’ into something more meaningful to identify your study such as ‘CandidateHypertensionCohorts’. One way of doing this is to use Notepad ++ find and replace ‘SkeletonCohortDiagnosticsStudy’ with a name for your study. Also change the ‘SkeletonCohortDiagnosticsStudy.Rproj’ to your study name ‘CandidateHypertensionCohorts.Rproj’.

    +

    Now you may install your package and execute the study.

    +
    +
    +

    +Option C: Manual (advanced users)

    +

    Start with the skeleton cohort diagnostics study package is here. Manually populate the CohortToCreate.csv file with the atlasId, cohortId and cohortName. In most cases atlasId = cohortId and should be an integer. cohortName is a meaningful name to identify your cohorts.

    +

    Next - create a new folder called ‘sql’ in the ‘inst’ folder and put all your SQLs. The sql file should be named to match the cohortId e.g. if the cohortId is 1232 then the sql file should be 1232.sql. Optionally, you can also add the cohort json in another folder in ‘inst’ folder of your package called ‘cohorts’. The names of the cohorts should be the same as the sql files, except they will end with .json instead of .sql.

    +

    If your cohorts have inclusion-rules, then you will have to create a file called ‘InclusionRules.csv’ and populate it as shown in this example:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    cohortNameruleSequenceruleNamecohortId
    149070With no history of gastrointestinal hemorrhage14907
    183490Gender is male18349
    183500Gender is male18350
    183501Metabolic disease at any time18350
    183520With gastrointestinal hemorrhage at some point18352
    +

    Now you may install your package and execute the study.

    +
    +
    +
    +

    +Running Cohort Diagnostics

    +

    The Cohort Diagnostics package has an examplePackage that may be used to understand the structure of a study package.

    +

    See Vignette on ‘Running Cohort Diagnostics’ on how to connect cohort diagnostics to CDM and creating cohort table.

    +

    In the extras folder of your study package will be a CodeToRun.R file. Please update the conectionDetails object as described in the vignette on ‘Running Cohort Diagnostics’. Also the page based on your local configuration information.

    +

    Run the entire script.

    +
    +
    + + + +
    + + + +
    + +
    +

    Site built with pkgdown 1.6.1.

    +
    + +
    +
    + + + + + + diff --git a/docs/articles/CohortDiagnosticsInPackageMode_files/accessible-code-block-0.0.1/empty-anchor.js b/docs/articles/CohortDiagnosticsInPackageMode_files/accessible-code-block-0.0.1/empty-anchor.js new file mode 100644 index 000000000..ca349fd6a --- /dev/null +++ b/docs/articles/CohortDiagnosticsInPackageMode_files/accessible-code-block-0.0.1/empty-anchor.js @@ -0,0 +1,15 @@ +// Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> +// v0.0.1 +// Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. + +document.addEventListener('DOMContentLoaded', function() { + const codeList = document.getElementsByClassName("sourceCode"); + for (var i = 0; i < codeList.length; i++) { + var linkList = codeList[i].getElementsByTagName('a'); + for (var j = 0; j < linkList.length; j++) { + if (linkList[j].innerHTML === "") { + linkList[j].setAttribute('aria-hidden', 'true'); + } + } + } +}); diff --git a/docs/articles/CohortDiagnosticsInPackageMode_files/header-attrs-2.7/header-attrs.js b/docs/articles/CohortDiagnosticsInPackageMode_files/header-attrs-2.7/header-attrs.js new file mode 100644 index 000000000..dd57d92e0 --- /dev/null +++ b/docs/articles/CohortDiagnosticsInPackageMode_files/header-attrs-2.7/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/CohortDiagnosticsInPackageMode_files/header-attrs-2.8/header-attrs.js b/docs/articles/CohortDiagnosticsInPackageMode_files/header-attrs-2.8/header-attrs.js new file mode 100644 index 000000000..dd57d92e0 --- /dev/null +++ b/docs/articles/CohortDiagnosticsInPackageMode_files/header-attrs-2.8/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/CohortDiagnosticsUsingWebApi.html b/docs/articles/CohortDiagnosticsUsingWebApi.html index 1381fa0be..392dac865 100644 --- a/docs/articles/CohortDiagnosticsUsingWebApi.html +++ b/docs/articles/CohortDiagnosticsUsingWebApi.html @@ -31,7 +31,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -39,7 +39,7 @@ @@ -68,7 +83,7 @@
  • - +
  • @@ -82,13 +97,13 @@ -
    +
    instantiateCohort(connectionDetails = connectionDetails,
                       cdmDatabaseSchema = cdmDatabaseSchema,
    -                  oracleTempSchema = oracleTempSchema,
    +                  tempEmulationSchema = tempEmulationSchema,
                       cohortDatabaseSchema = cohortDatabaseSchema,
                       cohortTable = cohortTable,
                       baseUrl = baseUrl,
    diff --git a/docs/articles/RunningCohortDiagnostics.html b/docs/articles/RunningCohortDiagnostics.html
    new file mode 100644
    index 000000000..1999e8d95
    --- /dev/null
    +++ b/docs/articles/RunningCohortDiagnostics.html
    @@ -0,0 +1,186 @@
    +
    +
    +
    +
    +
    +
    +
    +Running cohort diagnostics • CohortDiagnostics
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +    
    +
    + + + + +
    +
    + + + + +
    +

    +Configuring the connection to the server

    +

    We need to tell R how to connect to the server where the data are. CohortDiagnostics uses the DatabaseConnector package, which provides the createConnectionDetails function. Type ?createConnectionDetails for the specific settings required for the various database management systems (DBMS). For example, one might connect to a PostgreSQL database using this code:

    +
    +connectionDetails <- createConnectionDetails(dbms = "postgresql",
    +                                             server = "localhost/ohdsi",
    +                                             user = "joe",
    +                                             password = "supersecret")
    +
    +cdmDatabaseSchema <- "my_cdm_data"
    +tempEmulationSchema <- NULL
    +cohortDatabaseSchema <- "my_schema"
    +cohortTable <- "my_cohort_table"
    +

    The last four lines define the cdmDatabaseSchema, tempEmulationSchema, cohortDatabaseSchema, and cohortTable variables. We’ll use the cdmDatabaseSchema later to tell R where the data in CDM format live. The tempEmulationSchema is needed only for Oracle users, since Oracle does not support temporary tables. The cohortDatabaseSchema, and cohortTable specify where we want to instantiate our cohorts. Note that for Microsoft SQL Server, databaseschemas need to specify both the database and the schema, so for example cdmDatabaseSchema <- "my_cdm_data.dbo".

    +
    +

    +Creating a new cohort table

    +

    In order to run most of the cohort diagnostics, we need to instantiate the cohorts. The best way is to instantiate the cohorts in a new cohort table. We can use the createCohortTable to create an empty cohort table:

    +
    +createCohortTable(connectionDetails = connectionDetails,
    +                  cohortDatabaseSchema = cohortDatabaseSchema,
    +                  cohortTable = cohortTable)
    +

    Note this this function will delete the table if it already exists before creating it.

    +
    +
    +

    +Inclusion rules

    +

    We have the option to also generate inclusion rule statistics while the cohorts are instantiated (recommended). If we want to do this, we need to provide a folder where the inclusion rule statistics will be stored for later use.

    +
    +
    +
    +

    +Cohort Diagnostics Output

    +

    Once diagnostics is completed, a zip file will have been created in the specified export folder. This zip file can be shared between sites, as it does not contain patient-identifiable information. When unzipped, the zip file will contain several .csv files that maybe easily audited. Note that cell counts smaller than 5 have been removed, as specified using the minCellCount argument, to ensure non-identifiability.

    +
    +

    +Creating a pre merged file

    +

    Assuming you completed the steps described above for one or more databases, you should now have a set of zip files, one per database. Make sure to place all zip files in a single folder, for example c:/temp/allZipFiles.

    +

    Optionally, we can pre-merge the zip files, so we can view results in the Shiny app:

    +
    +preMergeDiagnosticsFiles("C:/temp/allZipFiles")
    +
    +
    +
    + + + +
    + + + +
    + +
    +

    Site built with pkgdown 1.6.1.

    +
    + +
    +
    + + + + + + diff --git a/docs/articles/RunningCohortDiagnostics_files/header-attrs-2.7/header-attrs.js b/docs/articles/RunningCohortDiagnostics_files/header-attrs-2.7/header-attrs.js new file mode 100644 index 000000000..dd57d92e0 --- /dev/null +++ b/docs/articles/RunningCohortDiagnostics_files/header-attrs-2.7/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/RunningCohortDiagnostics_files/header-attrs-2.8/header-attrs.js b/docs/articles/RunningCohortDiagnostics_files/header-attrs-2.8/header-attrs.js new file mode 100644 index 000000000..dd57d92e0 --- /dev/null +++ b/docs/articles/RunningCohortDiagnostics_files/header-attrs-2.8/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/ViewingResultsUsingDiagnosticsExplorer.html b/docs/articles/ViewingResultsUsingDiagnosticsExplorer.html new file mode 100644 index 000000000..8b33a1b0e --- /dev/null +++ b/docs/articles/ViewingResultsUsingDiagnosticsExplorer.html @@ -0,0 +1,180 @@ + + + + + + + +Viewing results using Diagnostics Explorer • CohortDiagnostics + + + + + + + + + + +
    +
    + + + + +
    +
    + + + + +
    +

    +Viewing the diagnostics

    +

    The Diagnostics Explorer shiny application is able to present the results output of Cohort Diagnostics in either local mode (i.e. using premerged file) or database mode (connected to postgres database server). The Shiny app can be found here. Make sure to copy all files in the DiagnosticsExplorer folder. When launching the application. You maybe asked to install additional packages required by the app, such as shiny, shinydashboard, shinyWidgets, DT, htmltools, scales, plotly, dplyr, purrr, tidyr, ggiraph.

    +
    +

    The Diagnostics Explorer Shiny app

    +
    +

    Note that each of the tabs on the left has an information icon. Clicking on these icons will show additional information on each diagnostic, how they were computed, and how they may be interpreted.

    +
    +
    +

    +Launching Diagnostics Explorer

    +
      +
    • From R, launch the DiagnosticExplorer shiny application by calling the ‘launchDiagnosticsExplorer()’ function of CohortDiagnostics.
    • +
    • From R-studio, you may start the project by clicking on the ‘DiagnosticsExplorer.Rproj’ in the shiny folder, then open the global.R and press the ‘RunApp’ button. From R-server (shiny server), you will need to copy all the files in the DiagnosticsExplorer shiny app into a folder on the server. The server should automatically launch the application (please talk to the shiny server administrator for your site specific rules.)
    • +
    +
    +
    +

    +Running the app using local file mode (Premerged file).

    +

    Local mode is the most common mode to run the Shiny application. We recommend that you convert all the csv files that are the precomputed output of Cohort Diagnostics into a .RData file as follows

    +
    +preMergeDiagnosticsFiles("C:/temp/allZipFiles")
    +

    .RData files enables faster load of the Shiny application. Once you have converted your results data into a premerged file, you may launch the Diagnostics Explorer app as follows:

    +
    +launchDiagnosticsExplorer(dataFolder = "C:/temp", dataFile = "Premerged.RData")
    +

    If running the application from a R-studio environment, please make sure the ‘Premerged.RData’ is in a folder called ‘data’. Go to global.R and to the line that defaultDatabaseMode <- FALSE. Ensure defaultDatabaseMode is FALSE. This will prevent the application from attempting to connect to a remote database system, and only look for local premerged.RData file.

    +
    +
    +

    +Running the app using Database mode

    +

    We recommend the use of a database system, when file size of the cohort diagnostics output becomes large e.g. > 100mb, as using the premerged.RData may leading sluggish performance. Currently only postgres server is supported. See Vignette on Database mode on how to load data into remote database.

    +
    +
    +

    +Running over the network

    +

    If you want to run the application over the network then set runOverNetwork = TRUE while launching the application using ‘launchDiagnosticsExplorer()’. This will make the shiny application available over your network (i.e. within your networks firewall).

    +
    +
    + + + +
    + + + +
    + +
    +

    Site built with pkgdown 1.6.1.

    +
    + +
    +
    + + + + + + diff --git a/docs/articles/ViewingResultsUsingDiagnosticsExplorer_files/header-attrs-2.7/header-attrs.js b/docs/articles/ViewingResultsUsingDiagnosticsExplorer_files/header-attrs-2.7/header-attrs.js new file mode 100644 index 000000000..dd57d92e0 --- /dev/null +++ b/docs/articles/ViewingResultsUsingDiagnosticsExplorer_files/header-attrs-2.7/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/ViewingResultsUsingDiagnosticsExplorer_files/header-attrs-2.8/header-attrs.js b/docs/articles/ViewingResultsUsingDiagnosticsExplorer_files/header-attrs-2.8/header-attrs.js new file mode 100644 index 000000000..dd57d92e0 --- /dev/null +++ b/docs/articles/ViewingResultsUsingDiagnosticsExplorer_files/header-attrs-2.8/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/WhatIsCohortDiagnostics.html b/docs/articles/WhatIsCohortDiagnostics.html new file mode 100644 index 000000000..0595cd387 --- /dev/null +++ b/docs/articles/WhatIsCohortDiagnostics.html @@ -0,0 +1,167 @@ + + + + + + + +What is Cohort Diagnostics? • CohortDiagnostics + + + + + + + + + + +
    +
    + + + + +
    +
    + + + + +
    +

    +Introduction

    +

    The CohortDiagnostics package allows one to generate a wide set of diagnostics to evaluate cohort definitions against a database in the Common Data Model (CDM). These diagnostics include incidence rates (optionally stratified by age, gender, and calendar year), cohort characteristics (comorbidities, drug use, etc.), and the codes found in the data triggering the various rules in the cohort definitions.

    +

    The CohortDiagnostics package in general works in two steps:

    +
      +
    1. Generate the diagnostics against a database in the CDM.
    2. +
    3. Explore the generated diagnostics in a Shiny app included in the CohortDiagnostics package.
    4. +
    +

    The use of Cohort Diagnostics is a recommended best practice to help improve the confidence in your cohort definitions.

    +
    +
    +

    +Features

    +
      +
    • Show cohort inclusion rule attrition.
    • +
    • List all source codes used when running a cohort definition on a specific database.
    • +
    • Find orphan codes, (source) codes that should be, but are not included in a particular concept set.
    • +
    • Compute cohort incidence across calendar years, age, and gender.
    • +
    • Break down index events into the specific concepts that triggered them.
    • +
    • Compute overlap between two cohorts.
    • +
    • Characterize cohorts, and compare these characterizations. Perform cohort comparison and temporal comparisons.
    • +
    • Explore patient profiles of a random sample of subjects in a cohort.
    • +
    +
    +
    + + + +
    + + + +
    + +
    +

    Site built with pkgdown 1.6.1.

    +
    + +
    +
    + + + + + + diff --git a/docs/articles/WhatIsCohortDiagnostics_files/header-attrs-2.7/header-attrs.js b/docs/articles/WhatIsCohortDiagnostics_files/header-attrs-2.7/header-attrs.js new file mode 100644 index 000000000..dd57d92e0 --- /dev/null +++ b/docs/articles/WhatIsCohortDiagnostics_files/header-attrs-2.7/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/WhatIsCohortDiagnostics_files/header-attrs-2.8/header-attrs.js b/docs/articles/WhatIsCohortDiagnostics_files/header-attrs-2.8/header-attrs.js new file mode 100644 index 000000000..dd57d92e0 --- /dev/null +++ b/docs/articles/WhatIsCohortDiagnostics_files/header-attrs-2.8/header-attrs.js @@ -0,0 +1,12 @@ +// Pandoc 2.9 adds attributes on both header and div. We remove the former (to +// be compatible with the behavior of Pandoc < 2.8). +document.addEventListener('DOMContentLoaded', function(e) { + var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); + var i, h, a; + for (i = 0; i < hs.length; i++) { + h = hs[i]; + if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 + a = h.attributes; + while (a.length > 0) h.removeAttribute(a[0].name); + } +}); diff --git a/docs/articles/index.html b/docs/articles/index.html index 67d19a14a..16ae9fa79 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -71,7 +71,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0
    @@ -79,7 +79,7 @@ @@ -108,7 +123,7 @@
  • - +
  • @@ -133,8 +148,18 @@

    All vignettes

    +
    Runing Cohort Diagnostics in an OHDSI Package mode
    +
    Running cohort diagnostics using WebAPI
    +
    Database mode in Diagnostics Explorer
    +
    +
    Running cohort diagnostics
    +
    +
    Viewing results using Diagnostics Explorer
    +
    +
    What is Cohort Diagnostics?
    +
    @@ -143,11 +168,11 @@

    All vignettes

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/authors.html b/docs/authors.html index 396bf8687..bb20609d1 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -71,7 +71,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0
    @@ -79,7 +79,7 @@ @@ -108,7 +123,7 @@
  • - +
  • @@ -145,6 +160,10 @@

    Authors

    James Weaver. Author.

    +
  • +

    Jamie Gilbert. Author. +

    +
  • Observational Health Data Science and Informatics. Copyright holder.

    @@ -159,11 +178,11 @@

    Authors

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/index.html b/docs/index.html index d3d4e8ba7..238b72f5d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -31,7 +31,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -39,7 +39,7 @@ @@ -68,7 +83,7 @@
  • - +
  • @@ -106,7 +121,7 @@

  • Compute cohort incidence across calendar years, age, and gender.
  • Break down index events into the specific concepts that triggered them.
  • Compute overlap between two cohorts.
  • -
  • Characterize cohorts, and compare these characterizations.
  • +
  • Characterize cohorts, and compare these characterizations. Perform cohort comparison and temporal comparisons.
  • Explore patient profiles of a random sample of subjects in a cohort.
  • @@ -132,7 +147,8 @@

  • See the instructions here for configuring your R environment, including Java.

  • In R, use the following commands to download and install CohortDiagnostics:

  • -
    remotes::install.github("OHDSI/CohortDiagnostics")
    +
    +remotes::install_github("OHDSI/CohortDiagnostics")
    @@ -172,7 +198,7 @@

    Development status

    -

    Beta testing

    +

    Stable

    @@ -203,6 +229,7 @@

    Developers

  • Martijn Schuemie
    Author
  • Patrick Ryan
    Author
  • James Weaver
    Author
  • +
  • Jamie Gilbert
    Author
  • All authors...
  • @@ -210,7 +237,7 @@

    Developers

    Dev status

      -
    • Build Status
    • +
    • Build Status
    • codecov.io
    @@ -219,11 +246,11 @@

    Dev status

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/news/index.html b/docs/news/index.html index 555870eaa..0e6d2a2c6 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -71,7 +71,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -79,7 +79,7 @@ @@ -108,7 +123,7 @@
  • - +
  • @@ -129,6 +144,41 @@

    Changelog

    Source: NEWS.md +
    +

    +CohortDiagnostics 2.1.0

    +

    Changes:

    +
      +
    1. Diagnostics explorer Shiny app enhancements:
    2. +
    +
      +
    • Improved tool tip
    • +
    • Various improvements to plots for consistent color, axis labels and labels
    • +
    • Visit context table addition
    • +
    • Diagnostic explorer is now a distinct shiny application from phenotype library. PhenotypeExplorer is a stand alone shiny app in package PhenotypeLibrarian.
    • +
    • Lot of UX changes. Reactivity deferred on drop down menus.
    • +
    • Changes to improve app stability.
    • +
    +
      +
    1. Index event breakdown now has subject count

    2. +
    3. Index event breakdown calculates _source_concept_id from source fields in CDM tables.

    4. +
    5. Vocabulary database schema is now supported.

    6. +
    7. Metadata (vocabulary version information from data source) is now collected.

    8. +
    9. OracleTempSchema use deprecated in favor of tempEmulationSchema.

    10. +
    11. Run against external concept count has been removed, as concept counts data is not available. Function ‘runCohortDiagnosticsUsingExternalCounts’ is removed.

    12. +
    13. Removed code related to referentConceptId = phenotypeId/1000 as it does not always hold true.

    14. +
    15. Create cohort table function is now private. Please use instantiate cohort.

    16. +
    17. checkInputFileEncoding is not exported as a public function (as not the scope of CohortDiagnostics).

    18. +
    19. Updated results data model to include new tables (resolved_concepts).

    20. +
    21. Cohort Diagnostics results data model now compliant with standard characterization output.

    22. +
    23. Support for cohort_censor_stats table in webapi 2.8.1 #387

    24. +
    25. Add time series diagnostics computation. Output is not in Diagnostics explorer in this version.

    26. +
    27. Any improvements to help with usability and stability. Informative messages to help with debugbing as needed.

    28. +
    29. phenotypeDescription is no longer supported as input for cohort diagnostics. Bug fixes:

    30. +
    31. databaseName and databaseDescription should be non NULL

    32. +
    33. Fixed computation of standard deviation and standard difference of mean for binary covariates.

    34. +
    +

    CohortDiagnostics 2.0.0

    @@ -290,7 +340,7 @@

    1. Fixed error when cohort definition has no concept sets.

    2. Fixed error in index event breakdown when entry event contained multiple criteria for the same domain.

    3. -
    4. Fixed error related to oracleTempSchema argument (needed on Oracle and BigQuery).

    5. +
    6. Fixed error related to tempEmulationSchema argument (needed on Oracle and BigQuery).

    7. Fixed use of deprecated function, causing warnings and causing older versions of ParallelLogger to error.

    @@ -352,11 +402,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/pkgdown.css b/docs/pkgdown.css index c01e5923b..1273238dd 100644 --- a/docs/pkgdown.css +++ b/docs/pkgdown.css @@ -244,14 +244,14 @@ nav[data-toggle='toc'] .nav .nav > .active:focus > a { .ref-index th {font-weight: normal;} -.ref-index td {vertical-align: top;} +.ref-index td {vertical-align: top; min-width: 100px} .ref-index .icon {width: 40px;} .ref-index .alias {width: 40%;} .ref-index-icons .alias {width: calc(40% - 40px);} .ref-index .title {width: 60%;} .ref-arguments th {text-align: right; padding-right: 10px;} -.ref-arguments th, .ref-arguments td {vertical-align: top;} +.ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} .ref-arguments .name {width: 20%;} .ref-arguments .desc {width: 80%;} diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml index 6b848876f..104bb1b22 100644 --- a/docs/pkgdown.yml +++ b/docs/pkgdown.yml @@ -1,7 +1,12 @@ -pandoc: 2.7.3 -pkgdown: 1.5.1 +pandoc: 2.11.4 +pkgdown: 1.6.1 pkgdown_sha: ~ articles: + CohortDiagnosticsInPackageMode: CohortDiagnosticsInPackageMode.html CohortDiagnosticsUsingWebApi: CohortDiagnosticsUsingWebApi.html -last_built: 2020-10-07T09:31Z + DatabaseModeInDiagnosticsExplorer: DatabaseModeInDiagnosticsExplorer.html + RunningCohortDiagnostics: RunningCohortDiagnostics.html + ViewingResultsUsingDiagnosticsExplorer: ViewingResultsUsingDiagnosticsExplorer.html + WhatIsCohortDiagnostics: WhatIsCohortDiagnostics.html +last_built: 2021-05-24T14:31Z diff --git a/docs/reference/CohortDiagnostics-package.html b/docs/reference/CohortDiagnostics-package.html index f457799f3..f7657e289 100644 --- a/docs/reference/CohortDiagnostics-package.html +++ b/docs/reference/CohortDiagnostics-package.html @@ -72,7 +72,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -80,7 +80,7 @@ @@ -109,7 +124,7 @@
  • - +
  • @@ -146,6 +161,21 @@

    See a +

    Author

    + +

    Maintainer: Gowtham Rao rao@ohdsi.org

    +

    Authors:

    + +

    Other contributors:

      +
    • Observational Health Data Science and Informatics [copyright holder]

    • +
    + + @@ -81,7 +81,7 @@ @@ -110,7 +125,7 @@
  • - +
  • @@ -128,16 +143,16 @@
    -

    For its input files, CohortDiagnostics only accepts UTF-8 or ASCII character encoding. This +

    For its input files, CohortDiagnostics only accepts UTF-8 or ASCII character encoding. This function can be used to check whether a file meets these criteria.

    -
    checkInputFileEncoding(fileName)
    +
    checkInputFileEncoding(fileName)

    Arguments

    @@ -163,11 +178,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/createCohortTable.html b/docs/reference/createCohortTable.html index bd9423e51..fa3a7b004 100644 --- a/docs/reference/createCohortTable.html +++ b/docs/reference/createCohortTable.html @@ -73,7 +73,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -81,7 +81,7 @@ @@ -110,7 +125,7 @@
  • - +
  • @@ -137,18 +152,18 @@

    Create cohort table(s)

    store statistics on the various inclusion criteria.

    -
    createCohortTable(
    -  connectionDetails = NULL,
    -  connection = NULL,
    -  cohortDatabaseSchema,
    -  cohortTable = "cohort",
    -  createInclusionStatsTables = FALSE,
    -  resultsDatabaseSchema = cohortDatabaseSchema,
    -  cohortInclusionTable = paste0(cohortTable, "_inclusion"),
    -  cohortInclusionResultTable = paste0(cohortTable, "_inclusion_result"),
    -  cohortInclusionStatsTable = paste0(cohortTable, "_inclusion_stats"),
    -  cohortSummaryStatsTable = paste0(cohortTable, "_summary_stats")
    -)
    +
    createCohortTable(
    +  connectionDetails = NULL,
    +  connection = NULL,
    +  cohortDatabaseSchema,
    +  cohortTable = "cohort",
    +  createInclusionStatsTables = FALSE,
    +  resultsDatabaseSchema = cohortDatabaseSchema,
    +  cohortInclusionTable = paste0(cohortTable, "_inclusion"),
    +  cohortInclusionResultTable = paste0(cohortTable, "_inclusion_result"),
    +  cohortInclusionStatsTable = paste0(cohortTable, "_inclusion_stats"),
    +  cohortSummaryStatsTable = paste0(cohortTable, "_summary_stats")
    +)

    Arguments

    @@ -156,14 +171,14 @@

    Arg

    @@ -223,11 +238,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/createConceptCountsTable.html b/docs/reference/createConceptCountsTable.html index 71145fea7..8ace3cc65 100644 --- a/docs/reference/createConceptCountsTable.html +++ b/docs/reference/createConceptCountsTable.html @@ -139,7 +139,7 @@

    Create concept counts table

    connectionDetails =NULL, connection =NULL, cdmDatabaseSchema, - oracleTempSchema =NULL, + tempEmulationSchema =NULL, conceptCountsDatabaseSchema =cdmDatabaseSchema, conceptCountsTable ="concept_counts", conceptCountsTableIsTemp =FALSE @@ -170,7 +170,7 @@

    Arg schema name, for example 'cdm_data.dbo'.

    - + diff --git a/docs/reference/createResultsDataModel.html b/docs/reference/createResultsDataModel.html index d9147a7b7..3a3338ab2 100644 --- a/docs/reference/createResultsDataModel.html +++ b/docs/reference/createResultsDataModel.html @@ -72,7 +72,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -80,7 +80,7 @@ @@ -109,7 +124,7 @@
  • - +
  • @@ -135,7 +150,7 @@

    Create the results data model tables on a database server.

    Create the results data model tables on a database server.

    -
    createResultsDataModel(connection = NULL, connectionDetails = NULL, schema)
    +
    createResultsDataModel(connection = NULL, connectionDetails = NULL, schema)

    Arguments

    connectionDetails

    An object of type connectionDetails as created using the -createConnectionDetails function in the +createConnectionDetails function in the DatabaseConnector package. Can be left NULL if connection is provided.

    connection

    An object of type connection as created using the -connect function in the +connect function in the DatabaseConnector package. Can be left NULL if connectionDetails is provided, in which case a new connection will be opened at the start of the function, and closed when the function finishes.

    oracleTempSchematempEmulationSchema

    Should be used in Oracle to specify a schema where the user has write privileges for storing temporary tables.

    @@ -143,7 +158,7 @@

    Arg

    @@ -151,7 +166,7 @@

    Arg

    @@ -176,11 +191,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/findCohortIncludedSourceConcepts.html b/docs/reference/findCohortIncludedSourceConcepts.html index d8ccfec92..68146b287 100644 --- a/docs/reference/findCohortIncludedSourceConcepts.html +++ b/docs/reference/findCohortIncludedSourceConcepts.html @@ -141,7 +141,7 @@

    Check source codes used in a cohort definition

    connectionDetails =NULL, connection =NULL, cdmDatabaseSchema, - oracleTempSchema =NULL, + tempEmulationSchema =NULL, baseUrl =NULL, webApiCohortId =NULL, cohortJson =NULL, @@ -175,7 +175,7 @@

    Arg schema name, for example 'cdm_data.dbo'.

    - + diff --git a/docs/reference/findCohortOrphanConcepts.html b/docs/reference/findCohortOrphanConcepts.html index f13cdd913..bb04e1a77 100644 --- a/docs/reference/findCohortOrphanConcepts.html +++ b/docs/reference/findCohortOrphanConcepts.html @@ -143,7 +143,7 @@

    Find orphan concepts for all concept sets in a cohort

    connectionDetails =NULL, connection =NULL, cdmDatabaseSchema, - oracleTempSchema =NULL, + tempEmulationSchema =NULL, baseUrl =NULL, webApiCohortId =NULL, cohortJson =NULL, @@ -177,7 +177,7 @@

    Arg schema name, for example 'cdm_data.dbo'.

    - + diff --git a/docs/reference/findOrphanConcepts.html b/docs/reference/findOrphanConcepts.html index 4e41ab2ea..35dc3d1e9 100644 --- a/docs/reference/findOrphanConcepts.html +++ b/docs/reference/findOrphanConcepts.html @@ -141,7 +141,7 @@

    Find (source) concepts that do not roll up to their ancestor(s)

    connectionDetails =NULL, connection =NULL, cdmDatabaseSchema, - oracleTempSchema =NULL, + tempEmulationSchema =NULL, conceptIds, conceptCountsDatabaseSchema =cdmDatabaseSchema, conceptCountsTable ="concept_counts", @@ -173,7 +173,7 @@

    Arg schema name, for example 'cdm_data.dbo'.

    - + diff --git a/docs/reference/getCohortCharacteristics.html b/docs/reference/getCohortCharacteristics.html index 097b4971b..9c8121b7d 100644 --- a/docs/reference/getCohortCharacteristics.html +++ b/docs/reference/getCohortCharacteristics.html @@ -141,7 +141,7 @@

    Create characterization of a cohort

    connectionDetails =NULL, connection =NULL, cdmDatabaseSchema, - oracleTempSchema =NULL, + tempEmulationSchema =NULL, cohortDatabaseSchema =cdmDatabaseSchema, cohortTable ="cohort", cohortIds, @@ -175,7 +175,7 @@

    Arg schema name, for example 'cdm_data.dbo'.

    - + diff --git a/docs/reference/getCohortCounts.html b/docs/reference/getCohortCounts.html index 6c7af015c..187e1a86f 100644 --- a/docs/reference/getCohortCounts.html +++ b/docs/reference/getCohortCounts.html @@ -72,7 +72,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -80,7 +80,7 @@ @@ -109,7 +124,7 @@
  • - +
  • @@ -135,13 +150,13 @@

    Count the cohort(s)

    Computes the subject and entry count per cohort

    -
    getCohortCounts(
    -  connectionDetails = NULL,
    -  connection = NULL,
    -  cohortDatabaseSchema,
    -  cohortTable = "cohort",
    -  cohortIds = c()
    -)
    +
    getCohortCounts(
    +  connectionDetails = NULL,
    +  connection = NULL,
    +  cohortDatabaseSchema,
    +  cohortTable = "cohort",
    +  cohortIds = c()
    +)

    Arguments

    connection

    An object of type connection as created using the -connect function in the +connect function in the DatabaseConnector package. Can be left NULL if connectionDetails is provided, in which case a new connection will be opened at the start of the function, and closed when the function finishes.

    connectionDetails

    An object of type connectionDetails as created using the -createConnectionDetails function in the +createConnectionDetails function in the DatabaseConnector package. Can be left NULL if connection is provided.

    oracleTempSchematempEmulationSchema

    Should be used in Oracle to specify a schema where the user has write privileges for storing temporary tables.

    oracleTempSchematempEmulationSchema

    Should be used in Oracle to specify a schema where the user has write privileges for storing temporary tables.

    oracleTempSchematempEmulationSchema

    Should be used in Oracle to specify a schema where the user has write privileges for storing temporary tables.

    oracleTempSchematempEmulationSchema

    Should be used in Oracle to specify a schema where the user has write privileges for storing temporary tables.

    @@ -149,14 +164,14 @@

    Arg

    @@ -193,11 +208,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/getCohortsJsonAndSql.html b/docs/reference/getCohortsJsonAndSql.html index 7a13ee671..aa8b9abc0 100644 --- a/docs/reference/getCohortsJsonAndSql.html +++ b/docs/reference/getCohortsJsonAndSql.html @@ -197,7 +197,7 @@

    Details connect to the WebApi, and which cohorts to fetch, respectively.

    Note: if the parameters for both Package Mode and WebApi Mode are provided, then Package mode is preferred.

    The cohortSetReference argument must be a data frame with the following columns:

    -
    referentConceptId

    A standard omop concept id that serves as the referant phenotype definition for the cohort Id.

    +
    referentConceptId

    A standard OMOP concept id that serves as the referent phenotype definition for the cohort Id.

    cohortId

    The cohort Id is the id used to identify a cohort definition. This is required to be unique. It will be used to create file names. It is recommended to be (referrentConceptId * 1000) + a number between 3 to 999

    webApiCohortId

    Cohort Id in the webApi/atlas instance. It is a required field to run Cohort Diagnostics in WebApi mode. It is discarded in package mode.

    cohortName

    The full name of the cohort. This will be shown in the Shiny app.

    diff --git a/docs/reference/getConceptSetDataDiagnostics.html b/docs/reference/getConceptSetDataDiagnostics.html index 59c6ffaf4..29595bc56 100644 --- a/docs/reference/getConceptSetDataDiagnostics.html +++ b/docs/reference/getConceptSetDataDiagnostics.html @@ -233,3 +233,4 @@

    Contents

    +[1] TRUE diff --git a/docs/reference/getIncidenceRate.html b/docs/reference/getIncidenceRate.html index bceb0709b..1cb8de18c 100644 --- a/docs/reference/getIncidenceRate.html +++ b/docs/reference/getIncidenceRate.html @@ -142,7 +142,7 @@

    Compute incidence rate for a cohort

    cohortTable, cdmDatabaseSchema, cdmVersion = 5, - oracleTempSchema = oracleTempSchema, + tempEmulationSchema = tempEmulationSchema, firstOccurrenceOnly = TRUE, washoutPeriod = 365, cohortId @@ -187,7 +187,7 @@

    Arg

    - + diff --git a/docs/reference/getOmopVocabularyTables.html b/docs/reference/getOmopVocabularyTables.html index 4f8a842ec..9031c2194 100644 --- a/docs/reference/getOmopVocabularyTables.html +++ b/docs/reference/getOmopVocabularyTables.html @@ -6,7 +6,7 @@ -Get a copy of omop vocabulary as csv — getOmopVocabularyTables • CohortDiagnostics +Get a copy of OMOP vocabulary as csv — getOmopVocabularyTables • CohortDiagnostics @@ -39,8 +39,8 @@ - - + @@ -127,13 +127,13 @@
    -

    For a given list of conceptId's get a subset of omop vocabulary +

    For a given list of conceptId's get a subset of OMOP vocabulary of these conceptIds. These are written as csv in the export folder

    @@ -167,7 +167,7 @@

    Arg

    - @@ -183,7 +183,7 @@

    Arg

    - + diff --git a/docs/reference/getResultsDataModelSpecifications.html b/docs/reference/getResultsDataModelSpecifications.html index 522133146..2f5f2fcfc 100644 --- a/docs/reference/getResultsDataModelSpecifications.html +++ b/docs/reference/getResultsDataModelSpecifications.html @@ -72,7 +72,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -80,7 +80,7 @@ @@ -109,7 +124,7 @@
  • - +
  • @@ -135,7 +150,7 @@

    Get specifications for Cohort Diagnostics results data model

    Get specifications for Cohort Diagnostics results data model

    -
    getResultsDataModelSpecifications()
    +
    getResultsDataModelSpecifications()

    Value

    @@ -153,11 +168,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/getTimeDistributions.html b/docs/reference/getTimeDistributions.html index c01fff0d1..c33c0cd93 100644 --- a/docs/reference/getTimeDistributions.html +++ b/docs/reference/getTimeDistributions.html @@ -139,7 +139,7 @@

    Get time distributions for a set of cohorts

    connectionDetails =NULL, connection =NULL, cdmDatabaseSchema, - oracleTempSchema =NULL, + tempEmulationSchema =NULL, cohortDatabaseSchema =cdmDatabaseSchema, cohortTable ="cohort", cohortIds, @@ -171,7 +171,7 @@

    Arg schema name, for example 'cdm_data.dbo'.

    - + diff --git a/docs/reference/index.html b/docs/reference/index.html index 305536581..a294b4256 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -71,7 +71,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -79,7 +79,7 @@ @@ -108,7 +123,7 @@
  • - +
  • @@ -156,12 +171,6 @@

    createCohortTable()

    - -

    - - @@ -180,12 +189,6 @@

    instantiateCohort()

    - -

    - - @@ -235,11 +238,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/instantiateCohort.html b/docs/reference/instantiateCohort.html index 6abd6e5c5..9020cf0b4 100644 --- a/docs/reference/instantiateCohort.html +++ b/docs/reference/instantiateCohort.html @@ -41,8 +41,7 @@ +statistics are computed and stored in the inclusion rule statistics tables." /> @@ -74,7 +73,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -82,7 +81,7 @@ @@ -111,7 +125,7 @@
  • - +
  • @@ -135,28 +149,29 @@

    Instantiate a cohort

    This function instantiates the cohort in the cohort table. Optionally, the inclusion rule -statistics are computed and stored in the inclusion rule statistics tables described in -createCohortTable).

    +statistics are computed and stored in the inclusion rule statistics tables.

    -
    instantiateCohort(
    -  connectionDetails = NULL,
    -  connection = NULL,
    -  cdmDatabaseSchema,
    -  oracleTempSchema = NULL,
    -  cohortDatabaseSchema = cdmDatabaseSchema,
    -  cohortTable = "cohort",
    -  baseUrl = NULL,
    -  cohortJson = NULL,
    -  cohortSql = NULL,
    -  cohortId = NULL,
    -  generateInclusionStats = FALSE,
    -  resultsDatabaseSchema = cohortDatabaseSchema,
    -  cohortInclusionTable = paste0(cohortTable, "_inclusion"),
    -  cohortInclusionResultTable = paste0(cohortTable, "_inclusion_result"),
    -  cohortInclusionStatsTable = paste0(cohortTable, "_inclusion_stats"),
    -  cohortSummaryStatsTable = paste0(cohortTable, "_summary_stats")
    -)
    +
    instantiateCohort(
    +  connectionDetails = NULL,
    +  connection = NULL,
    +  cdmDatabaseSchema,
    +  oracleTempSchema = NULL,
    +  tempEmulationSchema = NULL,
    +  cohortDatabaseSchema = cdmDatabaseSchema,
    +  cohortTable = "cohort",
    +  baseUrl = NULL,
    +  cohortJson = NULL,
    +  cohortSql = NULL,
    +  cohortId = NULL,
    +  generateInclusionStats = FALSE,
    +  resultsDatabaseSchema = cohortDatabaseSchema,
    +  vocabularyDatabaseSchema = cdmDatabaseSchema,
    +  cohortInclusionTable = paste0(cohortTable, "_inclusion"),
    +  cohortInclusionResultTable = paste0(cohortTable, "_inclusion_result"),
    +  cohortInclusionStatsTable = paste0(cohortTable, "_inclusion_stats"),
    +  cohortSummaryStatsTable = paste0(cohortTable, "_summary_stats")
    +)

    Arguments

    connectionDetails

    An object of type connectionDetails as created using the -createConnectionDetails function in the +createConnectionDetails function in the DatabaseConnector package. Can be left NULL if connection is provided.

    connection

    An object of type connection as created using the -connect function in the +connect function in the DatabaseConnector package. Can be left NULL if connectionDetails is provided, in which case a new connection will be opened at the start of the function, and closed when the function finishes.

    The version of the OMOP CDM. Default 5. (Note: only 5 is supported.)

    oracleTempSchematempEmulationSchema

    Should be used in Oracle to specify a schema where the user has write privileges for storing temporary tables.

    cdmDatabaseSchema

    databaseSchema where the omop vocabulary files are located. +

    databaseSchema where the OMOP vocabulary files are located. These are most commonly the same as cdmDatabaseSchema.

    vocabularyTableNames

    (optional) A vector of omop vocabulary table names to download.

    (optional) A vector of OMOP vocabulary table names to download.

    exportFolder
    oracleTempSchematempEmulationSchema

    Should be used in Oracle to specify a schema where the user has write privileges for storing temporary tables.

    Create cohort table(s)

    createResultsDataModel()

    Instantiate a cohort

    instantiateCohortSet()

    @@ -164,14 +179,14 @@

    Arg

    @@ -184,8 +199,12 @@

    Arg

    - + + + + + @@ -226,6 +245,13 @@

    Arg

    + + + + @@ -261,11 +287,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/instantiateCohortSet.html b/docs/reference/instantiateCohortSet.html index 0a89906af..bc4b3134b 100644 --- a/docs/reference/instantiateCohortSet.html +++ b/docs/reference/instantiateCohortSet.html @@ -73,7 +73,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -81,7 +81,7 @@ @@ -110,7 +125,7 @@
  • - +
  • @@ -137,24 +152,26 @@

    Instantiate a set of cohort

    Optionally, the inclusion rule statistics are computed and stored in the inclusionStatisticsFolder.

    -
    instantiateCohortSet(
    -  connectionDetails = NULL,
    -  connection = NULL,
    -  cdmDatabaseSchema,
    -  oracleTempSchema = NULL,
    -  cohortDatabaseSchema = cdmDatabaseSchema,
    -  cohortTable = "cohort",
    -  cohortIds = NULL,
    -  packageName = NULL,
    -  cohortToCreateFile = "settings/CohortsToCreate.csv",
    -  baseUrl = NULL,
    -  cohortSetReference = NULL,
    -  generateInclusionStats = FALSE,
    -  inclusionStatisticsFolder = NULL,
    -  createCohortTable = FALSE,
    -  incremental = FALSE,
    -  incrementalFolder = NULL
    -)
    +
    instantiateCohortSet(
    +  connectionDetails = NULL,
    +  connection = NULL,
    +  cdmDatabaseSchema,
    +  vocabularyDatabaseSchema = cdmDatabaseSchema,
    +  tempEmulationSchema = NULL,
    +  oracleTempSchema = NULL,
    +  cohortDatabaseSchema = cdmDatabaseSchema,
    +  cohortTable = "cohort",
    +  cohortIds = NULL,
    +  packageName = NULL,
    +  cohortToCreateFile = "settings/CohortsToCreate.csv",
    +  baseUrl = NULL,
    +  cohortSetReference = NULL,
    +  generateInclusionStats = FALSE,
    +  inclusionStatisticsFolder = NULL,
    +  createCohortTable = TRUE,
    +  incremental = FALSE,
    +  incrementalFolder = NULL
    +)

    Arguments

    connectionDetails

    An object of type connectionDetails as created using the -createConnectionDetails function in the +createConnectionDetails function in the DatabaseConnector package. Can be left NULL if connection is provided.

    connection

    An object of type connection as created using the -connect function in the +connect function in the DatabaseConnector package. Can be left NULL if connectionDetails is provided, in which case a new connection will be opened at the start of the function, and closed when the function finishes.

    oracleTempSchema

    Should be used in Oracle to specify a schema where the user has write -privileges for storing temporary tables.

    DEPRECATED by DatabaseConnector: use tempEmulationSchema instead.

    tempEmulationSchema

    Some database platforms like Oracle and Impala do not truly support temp tables. To emulate temp +tables, provide a schema with write privileges where temp tables can be created.

    cohortDatabaseSchema

    Schema name where the statistics tables reside. Note that for SQL Server, this should include both the database and schema name, for example 'scratch.dbo'.

    vocabularyDatabaseSchema

    Schema name where your OMOP vocabulary data resides. This is +commonly the same as cdmDatabaseSchema. Note that for +SQL Server, this should include both the database and +schema name, for example 'vocabulary.dbo'.

    cohortInclusionTable
    @@ -162,14 +179,14 @@

    Arg

    @@ -179,11 +196,22 @@

    Arg

    + + + + + + + + - + @@ -256,15 +284,15 @@

    Value

    Details

    Currently two ways of executing this function are supported, either -(1) [Package Mode] embedded in a study package, assuming the cohort definitions are stored in that package using the ROhdsiWebApi::insertCohortDefinitionSetInPackage, or +(1) [Package Mode] embedded in a study package, assuming the cohort definitions are stored in that package using the ROhdsiWebApi::insertCohortDefinitionSetInPackage, or (2) [WebApi Mode] By using a WebApi interface to retrieve the cohort definitions.

    When using this function in Package Mode: Use the packageName and cohortToCreateFile to specify the name of the study package, and the name of the cohortToCreate file within that package, respectively

    When using this function in WebApi Mode: use the baseUrl and cohortSetReference to specify how to connect to the WebApi, and which cohorts to fetch, respectively.

    Note: if the parameters for both Package Mode and WebApi Mode are provided, then Package mode is preferred.

    -

    The cohortSetReference argument must be a data frame with the following columns:

    -
    referentConceptId

    A standard omop concept id that serves as the referant phenotype definition for the cohort Id.

    +

    The cohortSetReference argument must be a data frame with the following columns:

    +
    referentConceptId

    A standard omop concept id that serves as the referent phenotype definition for the cohort Id.

    cohortId

    The cohort Id is the id used to identify a cohort definition. This is required to be unique. It will be used to create file names. It is recommended to be (referrentConceptId * 1000) + a number between 3 to 999

    webApiCohortId

    Cohort Id in the webApi/atlas instance. It is a required field to run Cohort Diagnostics in WebApi mode. It is discarded in package mode.

    cohortName

    The full name of the cohort. This will be shown in the Shiny app.

    @@ -286,11 +314,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/launchCohortExplorer.html b/docs/reference/launchCohortExplorer.html index d723ba78a..d4d7cd223 100644 --- a/docs/reference/launchCohortExplorer.html +++ b/docs/reference/launchCohortExplorer.html @@ -72,7 +72,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -80,7 +80,7 @@ @@ -109,7 +124,7 @@
  • - +
  • @@ -135,15 +150,15 @@

    Launch the CohortExplorer Shiny app

    Launch the CohortExplorer Shiny app

    -
    launchCohortExplorer(
    -  connectionDetails,
    -  cdmDatabaseSchema,
    -  cohortDatabaseSchema,
    -  cohortTable,
    -  cohortId,
    -  sampleSize = 100,
    -  subjectIds = NULL
    -)
    +
    launchCohortExplorer(
    +  connectionDetails,
    +  cdmDatabaseSchema,
    +  cohortDatabaseSchema,
    +  cohortTable,
    +  cohortId,
    +  sampleSize = 100,
    +  subjectIds = NULL
    +)

    Arguments

    connectionDetails

    An object of type connectionDetails as created using the -createConnectionDetails function in the +createConnectionDetails function in the DatabaseConnector package. Can be left NULL if connection is provided.

    connection

    An object of type connection as created using the -connect function in the +connect function in the DatabaseConnector package. Can be left NULL if connectionDetails is provided, in which case a new connection will be opened at the start of the function, and closed when the function finishes.

    Schema name where your patient-level data in OMOP CDM format resides. Note that for SQL Server, this should include both the database and schema name, for example 'cdm_data.dbo'.

    vocabularyDatabaseSchema

    Schema name where your OMOP vocabulary data resides. This is +commonly the same as cdmDatabaseSchema. Note that for +SQL Server, this should include both the database and +schema name, for example 'vocabulary.dbo'.

    tempEmulationSchema

    Some database platforms like Oracle and Impala do not truly support temp tables. To emulate temp +tables, provide a schema with write privileges where temp tables can be created.

    oracleTempSchema

    Should be used in Oracle to specify a schema where the user has write -privileges for storing temporary tables.

    DEPRECATED by DatabaseConnector: use tempEmulationSchema instead.

    cohortDatabaseSchema
    @@ -151,7 +166,7 @@

    Arg

    @@ -199,11 +214,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/launchDiagnosticsExplorer.html b/docs/reference/launchDiagnosticsExplorer.html index 4d215e86a..3e6af3ab0 100644 --- a/docs/reference/launchDiagnosticsExplorer.html +++ b/docs/reference/launchDiagnosticsExplorer.html @@ -72,7 +72,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -80,7 +80,7 @@ @@ -109,7 +124,7 @@
  • - +
  • @@ -135,17 +150,18 @@

    Launch the Diagnostics Explorer Shiny app

    Launch the Diagnostics Explorer Shiny app

    -
    launchDiagnosticsExplorer(
    -  dataFolder = "data",
    -  connectionDetails = NULL,
    -  resultsDatabaseSchema = NULL,
    -  vocabularyDatabaseSchema = resultsDatabaseSchema,
    -  cohortBaseUrl = "https://atlas.ohdsi.org/#/cohortdefinition/",
    -  conceptBaseUrl = "https://athena.ohdsi.org/search-terms/terms/",
    -  runOverNetwork = FALSE,
    -  port = 80,
    -  launch.browser = FALSE
    -)
    +
    launchDiagnosticsExplorer(
    +  dataFolder = "data",
    +  dataFile = "PreMerged.RData",
    +  connectionDetails = NULL,
    +  resultsDatabaseSchema = NULL,
    +  vocabularyDatabaseSchema = NULL,
    +  vocabularyDatabaseSchemas = resultsDatabaseSchema,
    +  aboutText = NULL,
    +  runOverNetwork = FALSE,
    +  port = 80,
    +  launch.browser = FALSE
    +)

    Arguments

    connectionDetails

    An object of type connectionDetails as created using the -createConnectionDetails function in the +createConnectionDetails function in the DatabaseConnector package.

    @@ -154,34 +170,40 @@

    Arg

    + + + + - - + - - + + - - + + @@ -213,11 +235,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/preMergeDiagnosticsFiles.html b/docs/reference/preMergeDiagnosticsFiles.html index fc686fd8f..08e0ba2eb 100644 --- a/docs/reference/preMergeDiagnosticsFiles.html +++ b/docs/reference/preMergeDiagnosticsFiles.html @@ -74,7 +74,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -82,7 +82,7 @@ @@ -111,7 +126,7 @@
  • - +
  • @@ -139,7 +154,7 @@

    Premerge Shiny diagnostics files

    It also checks whether the results conform to the results data model specifications.

    -
    preMergeDiagnosticsFiles(dataFolder, tempFolder = tempdir())
    +
    preMergeDiagnosticsFiles(dataFolder, tempFolder = tempdir())

    Arguments

    dataFolder

    A folder where the premerged file is stored. Use the preMergeDiagnosticsFiles function to generate this file.

    dataFile

    (Optional) The name of the .RData file with results. It is commonly known as the +Premerged file.

    connectionDetails

    An object of type connectionDetails as created using the -createConnectionDetails function in the +createConnectionDetails function in the DatabaseConnector package, specifying how to connect to the server where -the CohortDiagnostics results have been uploaded using the +the CohortDiagnostics results have been uploaded using the uploadResults function.

    resultsDatabaseSchema

    The schema on the database server where the CohortDiagnostics results +

    The schema on the database server where the CohortDiagnostics results have been uploaded.

    vocabularyDatabaseSchema

    The schema on the database server where the vocabulary tables are located.

    (Deprecated) Please use vocabularyDatabaseSchemas.

    cohortBaseUrl

    The base URL for constructing linkouts to an ATLAS instance, using the -webApiCohortId in the cohortsToCreate file. If NULL, no linkouts will be -created.

    vocabularyDatabaseSchemas

    (optional) A list of one or more schemas on the database server where the vocabulary tables are located. +The default value is the value of the resultsDatabaseSchema. We can provide a list of vocabulary schema +that might represent different versions of the OMOP vocabulary tables. It allows us to compare the impact +of vocabulary changes on Diagnostics.

    conceptBaseUrl

    The base URL for constructing linkouts to an Athena instance, using the -concept ID.

    aboutText

    Text (using HTML markup) that will be displayed in an About tab in the Shiny app. +If not provided, no About tab will be shown.

    runOverNetwork
    @@ -147,7 +162,7 @@

    Arg

    @@ -171,11 +186,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/resolveCohortSqlToConceptIds.html b/docs/reference/resolveCohortSqlToConceptIds.html index 6ad8c1ed0..60ebd11a7 100644 --- a/docs/reference/resolveCohortSqlToConceptIds.html +++ b/docs/reference/resolveCohortSqlToConceptIds.html @@ -141,7 +141,7 @@

    Resolves cohort sql to concept_ids

    cdmDatabaseSchema, databaseId, conceptSetsConceptId = "#resolved_concept_set", - oracleTempSchema = NULL, + tempEmulationSchema = NULL, cohort ) @@ -165,7 +165,7 @@

    Arg

    - + @@ -176,7 +176,7 @@

    Arg

    - + diff --git a/docs/reference/runCohortDiagnostics.html b/docs/reference/runCohortDiagnostics.html index fb84f84c1..d422f0dfb 100644 --- a/docs/reference/runCohortDiagnostics.html +++ b/docs/reference/runCohortDiagnostics.html @@ -77,7 +77,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -85,7 +85,7 @@ @@ -114,7 +129,7 @@
  • - +
  • @@ -138,50 +153,52 @@

    Run cohort diagnostics

    Runs the cohort diagnostics on all (or a subset of) the cohorts instantiated using the -ROhdsiWebApi::insertCohortDefinitionSetInPackage function. Assumes the cohorts have already been instantiated.

    +ROhdsiWebApi::insertCohortDefinitionSetInPackage function. Assumes the cohorts have already been instantiated.

    Characterization: If runTemporalCohortCharacterization argument is TRUE, then the following default covariateSettings object will be created using RFeatureExtraction::createTemporalCovariateSettings Alternatively, a covariate setting object may be created using the above as an example.

    -
    runCohortDiagnostics(
    -  packageName = NULL,
    -  cohortToCreateFile = "settings/CohortsToCreate.csv",
    -  baseUrl = NULL,
    -  cohortSetReference = NULL,
    -  phenotypeDescriptionFile = NULL,
    -  connectionDetails = NULL,
    -  connection = NULL,
    -  cdmDatabaseSchema,
    -  oracleTempSchema = NULL,
    -  cohortDatabaseSchema,
    -  cohortTable = "cohort",
    -  cohortIds = NULL,
    -  inclusionStatisticsFolder = file.path(exportFolder, "inclusionStatistics"),
    -  exportFolder,
    -  databaseId,
    -  databaseName = NULL,
    -  databaseDescription = NULL,
    -  cdmVersion = 5,
    -  runInclusionStatistics = TRUE,
    -  runIncludedSourceConcepts = TRUE,
    -  runOrphanConcepts = TRUE,
    -  runTimeDistributions = TRUE,
    -  runVisitContext = TRUE,
    -  runBreakdownIndexEvents = TRUE,
    -  runIncidenceRate = TRUE,
    -  runCohortOverlap = TRUE,
    -  runCohortCharacterization = TRUE,
    -  covariateSettings = createDefaultCovariateSettings(),
    -  runTemporalCohortCharacterization = TRUE,
    -  temporalCovariateSettings = createTemporalCovariateSettings(useConditionOccurrence =
    -    TRUE, useDrugEraStart = TRUE, useProcedureOccurrence = TRUE, useMeasurement = TRUE,
    -    temporalStartDays = c(-365, -30, 0, 1, 31), temporalEndDays = c(-31, -1, 0, 30, 365)),
    -  minCellCount = 5,
    -  incremental = FALSE,
    -  incrementalFolder = file.path(exportFolder, "incremental")
    -)
    +
    runCohortDiagnostics(
    +  packageName = NULL,
    +  cohortToCreateFile = "settings/CohortsToCreate.csv",
    +  baseUrl = NULL,
    +  cohortSetReference = NULL,
    +  connectionDetails = NULL,
    +  connection = NULL,
    +  cdmDatabaseSchema,
    +  oracleTempSchema = NULL,
    +  tempEmulationSchema = NULL,
    +  cohortDatabaseSchema,
    +  vocabularyDatabaseSchema = cdmDatabaseSchema,
    +  cohortTable = "cohort",
    +  cohortIds = NULL,
    +  inclusionStatisticsFolder = file.path(exportFolder, "inclusionStatistics"),
    +  exportFolder,
    +  databaseId,
    +  databaseName = databaseId,
    +  databaseDescription = databaseId,
    +  cdmVersion = 5,
    +  runInclusionStatistics = TRUE,
    +  runIncludedSourceConcepts = TRUE,
    +  runOrphanConcepts = TRUE,
    +  runTimeDistributions = TRUE,
    +  runVisitContext = TRUE,
    +  runBreakdownIndexEvents = TRUE,
    +  runIncidenceRate = TRUE,
    +  runTimeSeries = TRUE,
    +  runCohortOverlap = TRUE,
    +  runCohortCharacterization = TRUE,
    +  covariateSettings = createDefaultCovariateSettings(),
    +  runTemporalCohortCharacterization = TRUE,
    +  temporalCovariateSettings = createTemporalCovariateSettings(useConditionOccurrence =
    +    TRUE, useDrugEraStart = TRUE, useProcedureOccurrence = TRUE, useMeasurement = TRUE,
    +    temporalStartDays = c(-365, -30, 0, 1, 31), temporalEndDays = c(-31, -1, 0, 30, 365)),
    +  minCellCount = 5,
    +  incremental = FALSE,
    +  incrementalFolder = file.path(exportFolder, "incremental")
    +)

    Arguments

    dataFolder

    folder where the exported zip files for the diagnostics are stored. Use -the runCohortDiagnostics function to generate these zip files. +the runCohortDiagnostics function to generate these zip files. Zip files containing results from multiple databases may be placed in the same folder.

    cdmDatabaseSchema

    DatabaseSchema where the omop vocabulary files are located.

    DatabaseSchema where the OMOP vocabulary files are located.

    databaseId

    Table to store the output on the database system. This is a temporary table.

    oracleTempSchematempEmulationSchema

    Should be used in Oracle to specify a schema where the user has write privileges for storing temporary tables.

    @@ -210,33 +227,18 @@

    Arg

    - - - - @@ -249,14 +251,25 @@

    Arg

    - + + + + + + + + + @@ -283,11 +296,11 @@

    Arg

    - + - + @@ -321,15 +334,19 @@

    Arg

    + + + + - @@ -367,15 +384,15 @@

    Arg

    Details

    Currently two ways of executing this function are supported, either -(1) [Package Mode] embedded in a study package, assuming the cohort definitions are stored in that package using the ROhdsiWebApi::insertCohortDefinitionSetInPackage, or +(1) [Package Mode] embedded in a study package, assuming the cohort definitions are stored in that package using the ROhdsiWebApi::insertCohortDefinitionSetInPackage, or (2) [WebApi Mode] By using a WebApi interface to retrieve the cohort definitions.

    When using this function in Package Mode: Use the packageName and cohortToCreateFile to specify the name of the study package, and the name of the cohortToCreate file within that package, respectively

    When using this function in WebApi Mode: use the baseUrl and cohortSetReference to specify how to connect to the WebApi, and which cohorts to fetch, respectively.

    Note: if the parameters for both Package Mode and WebApi Mode are provided, then Package mode is preferred.

    -

    The cohortSetReference argument must be a data frame with the following columns:

    -
    referentConceptId

    A standard omop concept id that serves as the referant phenotype definition for the cohort Id.

    +

    The cohortSetReference argument must be a data frame with the following columns:

    +
    referentConceptId

    A standard omop concept id that serves as the referent phenotype definition for the cohort Id.

    cohortId

    The cohort Id is the id used to identify a cohort definition. This is required to be unique. It will be used to create file names. It is recommended to be (referrentConceptId * 1000) + a number between 3 to 999

    webApiCohortId

    Cohort Id in the webApi/atlas instance. It is a required field to run Cohort Diagnostics in WebApi mode. It is discarded in package mode.

    cohortName

    The full name of the cohort. This will be shown in the Shiny app.

    @@ -397,11 +414,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/runCohortDiagnosticsUsingExternalCounts.html b/docs/reference/runCohortDiagnosticsUsingExternalCounts.html index 5c2edea4f..f0ad49543 100644 --- a/docs/reference/runCohortDiagnosticsUsingExternalCounts.html +++ b/docs/reference/runCohortDiagnosticsUsingExternalCounts.html @@ -159,7 +159,7 @@

    Run cohort diagnostics using external concept counts

    connectionDetails = NULL, connection = NULL, cdmDatabaseSchema, - oracleTempSchema = NULL, + tempEmulationSchema = NULL, cohortIds = NULL, conceptCountsDatabaseSchema = cdmDatabaseSchema, conceptCountsTable = "concept_counts", @@ -223,7 +223,7 @@

    Arg schema name, for example 'cdm_data.dbo'.

    - + @@ -290,7 +290,7 @@

    Details connect to the WebApi, and which cohorts to fetch, respectively.

    Note: if the parameters for both Package Mode and WebApi Mode are provided, then Package mode is preferred.

    The cohortSetReference argument must be a data frame with the following columns:

    -
    referentConceptId

    A standard omop concept id that serves as the referant phenotype definition for the cohort Id.

    +
    referentConceptId

    A standard OMOP concept id that serves as the referent phenotype definition for the cohort Id.

    cohortId

    The cohort Id is the id used to identify a cohort definition. This is required to be unique. It will be used to create file names. It is recommended to be (referrentConceptId * 1000) + a number between 3 to 999

    webApiCohortId

    Cohort Id in the webApi/atlas instance. It is a required field to run Cohort Diagnostics in WebApi mode. It is discarded in package mode.

    cohortName

    The full name of the cohort. This will be shown in the Shiny app.

    diff --git a/docs/reference/runStudyDiagnostics.html b/docs/reference/runStudyDiagnostics.html index bf638c7c0..0af49b724 100644 --- a/docs/reference/runStudyDiagnostics.html +++ b/docs/reference/runStudyDiagnostics.html @@ -137,7 +137,7 @@

    Run study diagnostics

    connectionDetails = NULL, connection = NULL, cdmDatabaseSchema, - oracleTempSchema = NULL, + tempEmulationSchema = NULL, cohortDatabaseSchema, cohortTable = "cohort", cohortIds = NULL, @@ -188,7 +188,7 @@

    Arg schema name, for example 'cdm_data.dbo'.

    - + diff --git a/docs/reference/uploadPrintFriendly.html b/docs/reference/uploadPrintFriendly.html new file mode 100644 index 000000000..28fdb89eb --- /dev/null +++ b/docs/reference/uploadPrintFriendly.html @@ -0,0 +1,200 @@ + + + + + + + + +Upload print-friendly cohort representations to the database server. — uploadPrintFriendly • CohortDiagnostics + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + +
    + +
    +
    + + +
    +

    For all the cohorts in the 'cohort' table, this will generate print-friendly text and store it +in a new table called 'cohort_extra'.

    +
    + +
    uploadPrintFriendly(connectionDetails = NULL, schema)
    + +

    Arguments

    +
    cohortSetReference

    A data frame with four columns, as described in the details. Can be left NULL if packageName and cohortToCreateFile have been specified.

    phenotypeDescriptionFile

    (Optional) The location of the phenotype description file within the package. -The file must be .csv file and have the following columns that may be read into following -data types: phenotypeId (double), phenotypeName (character), -referentConceptId (double), clinicalDescription (character), -literatureReview (character), phenotypeNotes (character). Note: the field -names are in snake_case. Also, character fields should not have 'NA' in it. -'NA's are commonly added by R when R functions exports data from dataframe -into CSV. Instead please use '' (empty string) to represent absence of data. -The literature_review field is expected to be a html link to page that contains -resources related to literature review for the phenotype, and will be used -to create link-out object. This csv file is expected to be encoded in either -ASCII or UTF-8, if not, an error message will be displayed and process stopped.

    connectionDetails

    An object of type connectionDetails as created using the -createConnectionDetails function in the +createConnectionDetails function in the DatabaseConnector package. Can be left NULL if connection is provided.

    connection

    An object of type connection as created using the -connect function in the +connect function in the DatabaseConnector package. Can be left NULL if connectionDetails is provided, in which case a new connection will be opened at the start of the function, and closed when the function finishes.

    oracleTempSchema

    Should be used in Oracle to specify a schema where the user has write -privileges for storing temporary tables.

    DEPRECATED by DatabaseConnector: use tempEmulationSchema instead.

    tempEmulationSchema

    Some database platforms like Oracle and Impala do not truly support temp tables. To emulate temp +tables, provide a schema with write privileges where temp tables can be created.

    cohortDatabaseSchema

    Schema name where your cohort table resides. Note that for SQL Server, this should include both the database and schema name, for example 'scratch.dbo'.

    vocabularyDatabaseSchema

    Schema name where your OMOP vocabulary data resides. This is +commonly the same as cdmDatabaseSchema. Note that for +SQL Server, this should include both the database and +schema name, for example 'vocabulary.dbo'.

    cohortTable
    databaseName

    The full name of the database.

    The full name of the database. If NULL, defaults to databaseId.

    databaseDescription

    A short description (several sentences) of the database.

    A short description (several sentences) of the database. If NULL, defaults to databaseId.

    cdmVersionrunIncidenceRate

    Generate and export the cohort incidence rates?

    runTimeSeries

    Generate and export the cohort prevalence rates?

    runCohortOverlap

    Generate and export the cohort overlap? Overlaps are checked within cohortIds -that have the same phenotype ID sourced from the CohortSetReference or +that have the same phenotype ID sourced from the CohortSetReference or cohortToCreateFile.

    runCohortCharacterization

    Generate and export the cohort characterization? +

    Generate and export the cohort characterization? Only records with values greater than 0.0001 are returned.

    oracleTempSchematempEmulationSchema

    Should be used in Oracle to specify a schema where the user has write privileges for storing temporary tables.

    oracleTempSchematempEmulationSchema

    Should be used in Oracle to specify a schema where the user has write privileges for storing temporary tables.

    + + + + + + + + + +
    connectionDetails

    An object of type connectionDetails as created using the +createConnectionDetails function in the +DatabaseConnector package.

    schema

    The schema on the postgres server where the results are stored.

    + + +
    + + + + +
    + + +
    +

    Site built with pkgdown 1.6.1.

    +
    + +
    + + + + + + + + + diff --git a/docs/reference/uploadResults.html b/docs/reference/uploadResults.html index ce381a74e..c9f6b2373 100644 --- a/docs/reference/uploadResults.html +++ b/docs/reference/uploadResults.html @@ -74,7 +74,7 @@ CohortDiagnostics - 2.0.0 + 2.1.0 @@ -82,7 +82,7 @@ @@ -111,7 +126,7 @@
  • - +
  • @@ -139,14 +154,14 @@

    Upload results to the database server.

    bulk upload (recommended).

    -
    uploadResults(
    -  connectionDetails = NULL,
    -  schema,
    -  zipFileName,
    -  forceOverWriteOfSpecifications = FALSE,
    -  purgeSiteDataBeforeUploading = TRUE,
    -  tempFolder = tempdir()
    -)
    +
    uploadResults(
    +  connectionDetails = NULL,
    +  schema,
    +  zipFileName,
    +  forceOverWriteOfSpecifications = FALSE,
    +  purgeSiteDataBeforeUploading = TRUE,
    +  tempFolder = tempdir()
    +)

    Arguments

    @@ -154,12 +169,12 @@

    Arg

    - + @@ -167,21 +182,21 @@

    Arg

    - - +has sufficient space if the default system temp space is too limited.

    connectionDetails

    An object of type connectionDetails as created using the -createConnectionDetails function in the +createConnectionDetails function in the DatabaseConnector package.

    schema

    The schema on the postgres server where the tables will be created.

    The schema on the postgres server where the tables have been created.

    zipFileName
    forceOverWriteOfSpecifications

    If TRUE, specifications of the phenotypes, cohort definitions, and analysis +

    If TRUE, specifications of the phenotypes, cohort definitions, and analysis will be overwritten if they already exist on the database. Only use this if these specifications have changed since the last upload.

    purgeSiteDataBeforeUploading

    If TRUE, before inserting data for a specific databaseId all the data for -that site will be dropped. This assumes the input zip file contains the full data for that +

    If TRUE, before inserting data for a specific databaseId all the data for +that site will be dropped. This assumes the input zip file contains the full data for that data site.

    tempFolder

    A folder on the local file system where the zip files are extracted to. Will be cleaned up when the function is finished. Can be used to specify a temp folder on a drive that -has sufficent space if the default system temp space is too limited.

    @@ -197,11 +212,11 @@

    Contents

    -

    Site built with pkgdown 1.5.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/writeOmopvocabularyTables.html b/docs/reference/writeOmopvocabularyTables.html index 0e68aa1f6..4f7f341da 100644 --- a/docs/reference/writeOmopvocabularyTables.html +++ b/docs/reference/writeOmopvocabularyTables.html @@ -6,7 +6,7 @@ -Get a copy of omop vocabulary as csv — writeOmopvocabularyTables • CohortDiagnostics +Get a copy of OMOP vocabulary as csv — writeOmopvocabularyTables • CohortDiagnostics @@ -39,8 +39,8 @@ - - + @@ -135,13 +135,13 @@
    -

    For a given list of conceptId's get a subset of omop vocabulary +

    For a given list of conceptId's get a subset of OMOP vocabulary of these conceptIds. These are written as csv in the export folder

    @@ -180,21 +180,21 @@

    Arg vocabularyDatabaseSchema -

    databaseSchema where the omop vocabulary files are located. +

    databaseSchema where the OMOP vocabulary files are located. These are most commonly the same as cdmDatabaseSchema.

    conceptIds <<<<<<< HEAD -

    (optional) A vector of conceptIds to filter the extract of omop +

    (optional) A vector of conceptIds to filter the extract of OMOP vocabulary files. If NULL, all conceptIds are extracted.

    ======= -

    A vector of conceptIds to extract omop vocabulary files.

    +

    A vector of conceptIds to extract OMOP vocabulary files.

    >>>>>>> master vocabularyTableNames -

    (optional) A vector of omop vocabulary table names to download.

    +

    (optional) A vector of OMOP vocabulary table names to download.

    exportFolder diff --git a/examplePackage/.Rbuildignore b/examplePackage/.Rbuildignore deleted file mode 100644 index 01de75db6..000000000 --- a/examplePackage/.Rbuildignore +++ /dev/null @@ -1,9 +0,0 @@ -^.*\.Rproj$ -^\.Rproj\.user$ -extras -^\.Rprofile$ -documents -readme.md -studyReadme.md -HydraConfig.json - diff --git a/examplePackage/.Rprofile b/examplePackage/.Rprofile deleted file mode 100644 index 8b1378917..000000000 --- a/examplePackage/.Rprofile +++ /dev/null @@ -1 +0,0 @@ - diff --git a/examplePackage/.gitignore b/examplePackage/.gitignore deleted file mode 100644 index 116177baf..000000000 --- a/examplePackage/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.Rproj.user -.Rhistory -.RData -.Ruserdata -*.tmp diff --git a/examplePackage/DESCRIPTION b/examplePackage/DESCRIPTION deleted file mode 100644 index 056061625..000000000 --- a/examplePackage/DESCRIPTION +++ /dev/null @@ -1,20 +0,0 @@ -Package: examplePackage -Type: Package -Title: A Package Skeleton for Cohort Diagnostics -Version: 0.0.1 -Author: Martijn Schuemie [aut, cre] -Maintainer: Martijn J. Schuemie -Description: A skeleton package, to be used as a starting point when you just want to run cohort diagnostics. -Depends: - DatabaseConnector (>= 2.2.0) -Imports: - CohortDiagnostics -Suggests: - knitr, - rmarkdown, - ROhdsiWebApi, - OhdsiRTools -License: Apache License 2.0 -VignetteBuilder: knitr -LazyData: TRUE -RoxygenNote: 7.1.1 diff --git a/examplePackage/NAMESPACE b/examplePackage/NAMESPACE deleted file mode 100644 index 59c3cfd60..000000000 --- a/examplePackage/NAMESPACE +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by roxygen2: do not edit by hand - -export(runCohortDiagnostics) diff --git a/examplePackage/R/CohortDiagnostics.R b/examplePackage/R/CohortDiagnostics.R deleted file mode 100644 index f9705bcbe..000000000 --- a/examplePackage/R/CohortDiagnostics.R +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics -# -# This file is part of examplePackage -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -#' Execute the cohort diagnostics -#' -#' @details -#' This function executes the cohort diagnostics. -#' -#' @param connectionDetails An object of type \code{connectionDetails} as created using the -#' \code{\link[DatabaseConnector]{createConnectionDetails}} function in the -#' DatabaseConnector package. -#' @param cdmDatabaseSchema Schema name where your patient-level data in OMOP CDM format resides. -#' Note that for SQL Server, this should include both the database and -#' schema name, for example 'cdm_data.dbo'. -#' @param cohortDatabaseSchema Schema name where intermediate data can be stored. You will need to have -#' write priviliges in this schema. Note that for SQL Server, this should -#' include both the database and schema name, for example 'cdm_data.dbo'. -#' @param cohortTable The name of the table that will be created in the work database schema. -#' This table will hold the exposure and outcome cohorts used in this -#' study. -#' @param oracleTempSchema Should be used in Oracle to specify a schema where the user has write -#' priviliges for storing temporary tables. -#' @param outputFolder Name of local folder to place results; make sure to use forward slashes -#' (/). Do not use a folder on a network drive since this greatly impacts -#' performance. -#' @param databaseId A short string for identifying the database (e.g. -#' 'Synpuf'). -#' @param databaseName The full name of the database (e.g. 'Medicare Claims -#' Synthetic Public Use Files (SynPUFs)'). -#' @param databaseDescription A short description (several sentences) of the database. -#' @param createCohorts Create the cohortTable table with the exposure and outcome cohorts? -#' @param runInclusionStatistics Generate and export statistic on the cohort incusion rules? -#' @param runIncludedSourceConcepts Generate and export the source concepts included in the cohorts? -#' @param runOrphanConcepts Generate and export potential orphan concepts? -#' @param runTimeDistributions Generate and export cohort time distributions? -#' @param runBreakdownIndexEvents Generate and export the breakdown of index events? -#' @param runIncidenceRates Generate and export the cohort incidence rates? -#' @param runCohortOverlap Generate and export the cohort overlap? -#' @param runCohortCharacterization Generate and export the cohort characterization? -#' @param runTemporalCohortCharacterization Generate and export the temporal cohort characterization? -#' @param minCellCount The minimum number of subjects contributing to a count before it can be included -#' in packaged results. -#' -#' @export -runCohortDiagnostics <- function(connectionDetails, - cdmDatabaseSchema, - cohortDatabaseSchema = cdmDatabaseSchema, - cohortTable = "cohort", - oracleTempSchema = cohortDatabaseSchema, - outputFolder, - databaseId = "Unknown", - databaseName = "Unknown", - databaseDescription = "Unknown", - createCohorts = TRUE, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - runBreakdownIndexEvents = TRUE, - runIncidenceRates = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = TRUE, - runTemporalCohortCharacterization = TRUE, - minCellCount = 5) { - if (!file.exists(outputFolder)) - dir.create(outputFolder, recursive = TRUE) - - ParallelLogger::addDefaultFileLogger(file.path(outputFolder, "log.txt")) - ParallelLogger::addDefaultErrorReportLogger(file.path(outputFolder, "errorReportR.txt")) - on.exit(ParallelLogger::unregisterLogger("DEFAULT_FILE_LOGGER", silent = TRUE)) - on.exit(ParallelLogger::unregisterLogger("DEFAULT_ERRORREPORT_LOGGER", silent = TRUE), add = TRUE) - - if (createCohorts) { - ParallelLogger::logInfo("Creating cohorts") - connection <- DatabaseConnector::connect(connectionDetails) - .createCohorts(connection = connection, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - oracleTempSchema = oracleTempSchema, - outputFolder = outputFolder) - DatabaseConnector::disconnect(connection) - } - - ParallelLogger::logInfo("Running study diagnostics") - CohortDiagnostics::runCohortDiagnostics(packageName = "examplePackage", - connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - inclusionStatisticsFolder = outputFolder, - exportFolder = file.path(outputFolder, "diagnosticsExport"), - databaseId = databaseId, - databaseName = databaseName, - databaseDescription = databaseDescription, - runInclusionStatistics = runInclusionStatistics, - runIncludedSourceConcepts = runIncludedSourceConcepts, - runOrphanConcepts = runOrphanConcepts, - runTimeDistributions = runTimeDistributions, - runBreakdownIndexEvents = runBreakdownIndexEvents, - runIncidenceRate = runIncidenceRates, - runCohortOverlap = runCohortOverlap, - runCohortCharacterization = runCohortCharacterization, - runTemporalCohortCharacterization = runTemporalCohortCharacterization, - minCellCount = minCellCount) -} diff --git a/examplePackage/R/CreateCohorts.R b/examplePackage/R/CreateCohorts.R deleted file mode 100644 index 054df8ee6..000000000 --- a/examplePackage/R/CreateCohorts.R +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics -# -# This file is part of examplePackage -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -.createCohorts <- function(connection, - cdmDatabaseSchema, - vocabularyDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema, - cohortTable, - oracleTempSchema, - outputFolder) { - - # Create study cohort table structure: - sql <- SqlRender::loadRenderTranslateSql(sqlFilename = "CreateCohortTable.sql", - packageName = "examplePackage", - dbms = attr(connection, "dbms"), - oracleTempSchema = oracleTempSchema, - cohort_database_schema = cohortDatabaseSchema, - cohort_table = cohortTable) - DatabaseConnector::executeSql(connection, sql, progressBar = FALSE, reportOverallTime = FALSE) - - - # Insert rule names in cohort_inclusion table: - pathToCsv <- system.file("cohorts", "InclusionRules.csv", package = "examplePackage") - inclusionRules <- readr::read_csv(pathToCsv, col_types = readr::cols()) - inclusionRules <- data.frame(cohort_definition_id = inclusionRules$cohortId, - rule_sequence = inclusionRules$ruleSequence, - name = inclusionRules$ruleName) - DatabaseConnector::insertTable(connection = connection, - tableName = "#cohort_inclusion", - data = inclusionRules, - dropTableIfExists = TRUE, - createTable = TRUE, - tempTable = TRUE, - oracleTempSchema = oracleTempSchema) - - - # Instantiate cohorts: - pathToCsv <- system.file("settings", "CohortsToCreate.csv", package = "examplePackage") - cohortsToCreate <- readr::read_csv(pathToCsv, col_types = readr::cols()) - for (i in 1:nrow(cohortsToCreate)) { - writeLines(paste("Creating cohort:", cohortsToCreate$name[i])) - sql <- SqlRender::loadRenderTranslateSql(sqlFilename = paste0(cohortsToCreate$name[i], ".sql"), - packageName = "examplePackage", - dbms = attr(connection, "dbms"), - oracleTempSchema = oracleTempSchema, - cdm_database_schema = cdmDatabaseSchema, - vocabulary_database_schema = vocabularyDatabaseSchema, - - results_database_schema.cohort_inclusion = "#cohort_inclusion", - results_database_schema.cohort_inclusion_result = "#cohort_inc_result", - results_database_schema.cohort_inclusion_stats = "#cohort_inc_stats", - results_database_schema.cohort_summary_stats = "#cohort_summary_stats", - - target_database_schema = cohortDatabaseSchema, - target_cohort_table = cohortTable, - target_cohort_id = cohortsToCreate$cohortId[i]) - DatabaseConnector::executeSql(connection, sql) - } - - # Fetch cohort counts: - sql <- "SELECT cohort_definition_id, COUNT(*) AS count FROM @cohort_database_schema.@cohort_table GROUP BY cohort_definition_id" - sql <- SqlRender::render(sql, - cohort_database_schema = cohortDatabaseSchema, - cohort_table = cohortTable) - sql <- SqlRender::translate(sql, targetDialect = attr(connection, "dbms")) - counts <- DatabaseConnector::querySql(connection, sql) - names(counts) <- SqlRender::snakeCaseToCamelCase(names(counts)) - counts <- merge(counts, data.frame(cohortDefinitionId = cohortsToCreate$cohortId, - cohortName = cohortsToCreate$name)) - readr::write_csv(x = counts, file = file.path(outputFolder, "CohortCounts.csv")) - - - # Fetch inclusion rule stats and drop tables: - fetchStats <- function(tableName) { - sql <- "SELECT * FROM #@table_name" - sql <- SqlRender::render(sql, table_name = tableName) - sql <- SqlRender::translate(sql = sql, - targetDialect = attr(connection, "dbms"), - oracleTempSchema = oracleTempSchema) - stats <- DatabaseConnector::querySql(connection, sql) - names(stats) <- SqlRender::snakeCaseToCamelCase(names(stats)) - fileName <- file.path(outputFolder, paste0(SqlRender::snakeCaseToCamelCase(tableName), ".csv")) - readr::write_csv(x = stats, file = fileName) - - sql <- "TRUNCATE TABLE #@table_name; DROP TABLE #@table_name;" - sql <- SqlRender::render(sql, table_name = tableName) - sql <- SqlRender::translate(sql = sql, - targetDialect = attr(connection, "dbms"), - oracleTempSchema = oracleTempSchema) - DatabaseConnector::executeSql(connection, sql) - } - fetchStats("cohort_inclusion") - fetchStats("cohort_inc_result") - fetchStats("cohort_inc_stats") - fetchStats("cohort_summary_stats") - -} - diff --git a/examplePackage/examplePackage.Rproj b/examplePackage/examplePackage.Rproj deleted file mode 100644 index eaa6b8186..000000000 --- a/examplePackage/examplePackage.Rproj +++ /dev/null @@ -1,18 +0,0 @@ -Version: 1.0 - -RestoreWorkspace: Default -SaveWorkspace: Default -AlwaysSaveHistory: Default - -EnableCodeIndexing: Yes -UseSpacesForTab: Yes -NumSpacesForTab: 2 -Encoding: UTF-8 - -RnwWeave: Sweave -LaTeX: pdfLaTeX - -BuildType: Package -PackageUseDevtools: Yes -PackageInstallArgs: --no-multiarch --with-keep.source -PackageRoxygenize: rd,collate,namespace diff --git a/examplePackage/extras/CodeToRun.R b/examplePackage/extras/CodeToRun.R deleted file mode 100644 index 315634f4e..000000000 --- a/examplePackage/extras/CodeToRun.R +++ /dev/null @@ -1,83 +0,0 @@ -# Make sure to install all dependencies (not needed if already done): -# install.packages("SqlRender") -# install.packages("DatabaseConnector") -# install.packages("ggplot2") -# install.packages("ParallelLogger") -# install.packages("readr") -# install.packages("tibble") -# install.packages("dplyr") -# install.packages("RJSONIO") -# install.packages("devtools") -# devtools::install_github("FeatureExtraction") -# devtools::install_github("ROhdsiWebApi") -# devtools::install_github("CohortDiagnostics") - - -# Load the package -library(examplePackage) - -path <- 's:/examplePackage' - -# Optional: specify where the temporary files will be created: -options(andromedaTempFolder = file.path(path, "andromedaTemp")) - -# Maximum number of cores to be used: -maxCores <- parallel::detectCores() - - -# Details for connecting to the server: -connectionDetails <- DatabaseConnector::createConnectionDetails(dbms = "pdw", - server = Sys.getenv("PDW_SERVER"), - user = NULL, - password = NULL, - port = Sys.getenv("PDW_PORT")) - -# For Oracle: define a schema that can be used to emulate temp tables: -oracleTempSchema <- NULL - -# Details specific to the database: -outputFolder <- "s:/examplePackage/ccae" -cdmDatabaseSchema <- "CDM_IBM_CCAE_V1247.dbo" -cohortDatabaseSchema <- "scratch.dbo" -cohortTable <- "mschuemi_skeleton_ccae" -databaseId <- "CCAE" -databaseName <- "IBM MarketScan Commercial Claims and Encounters Database" -databaseDescription <- "IBM MarketScan® Commercial Claims and Encounters Database (CCAE) represent data from individuals enrolled in United States employer-sponsored insurance health plans. The data includes adjudicated health insurance claims (e.g. inpatient, outpatient, and outpatient pharmacy) as well as enrollment data from large employers and health plans who provide private healthcare coverage to employees, their spouses, and dependents. Additionally, it captures laboratory tests for a subset of the covered lives. This administrative claims database includes a variety of fee-for-service, preferred provider organizations, and capitated health plans." - -# Use this to run the cohorttDiagnostics. The results will be stored in the diagnosticsExport subfolder of the outputFolder. This can be shared between sites. -examplePackage::runCohortDiagnostics(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - oracleTempSchema = oracleTempSchema, - outputFolder = outputFolder, - databaseId = databaseId, - databaseName = databaseName, - databaseDescription = databaseDescription, - createCohorts = TRUE, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - runBreakdownIndexEvents = TRUE, - runIncidenceRates = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = TRUE, - runTemporalCohortCharacterization = TRUE, - minCellCount = 5) - -# To view the results: -# Optional: if there are results zip files from multiple sites in a folder, this merges them, which will speed up starting the viewer: -CohortDiagnostics::preMergeDiagnosticsFiles(file.path(outputFolder, "diagnosticsExport")) - -# Use this to view the results. Multiple zip files can be in the same folder. If the files were pre-merged, this is automatically detected: -CohortDiagnostics::launchDiagnosticsExplorer(file.path(outputFolder, "diagnosticsExport")) - - -# To explore a specific cohort in the local database, viewing patient profiles: -CohortDiagnostics::launchCohortExplorer(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortId = 123) -# Where 123 is the ID of the cohort you wish to inspect. diff --git a/examplePackage/extras/CodeToRunRedShift.R b/examplePackage/extras/CodeToRunRedShift.R deleted file mode 100644 index 3b7c2ab9d..000000000 --- a/examplePackage/extras/CodeToRunRedShift.R +++ /dev/null @@ -1,83 +0,0 @@ -# Make sure to install all dependencies (not needed if already done): -# install.packages("SqlRender") -# install.packages("DatabaseConnector") -# install.packages("ggplot2") -# install.packages("ParallelLogger") -# install.packages("readr") -# install.packages("tibble") -# install.packages("dplyr") -# install.packages("RJSONIO") -# install.packages("devtools") -# devtools::install_github("FeatureExtraction") -# devtools::install_github("ROhdsiWebApi") -# devtools::install_github("CohortDiagnostics") - - -# Load the package -library(examplePackage) - -path <- 'D:/yourStudyFolderRs' - -# Optional: specify where the temporary files will be created: -options(andromedaTempFolder = file.path(path, "andromedaTemp")) - -# Maximum number of cores to be used: -maxCores <- parallel::detectCores() - - -# Details for connecting to the server: -connectionDetails <- DatabaseConnector::createConnectionDetails(dbms = "redshift", - server = Sys.getenv("REDSHIFT_MDCD_SERVER"), - user = Sys.getenv("userSecureAWS"), - password = Sys.getenv("passwordSecureAWS"), - port = Sys.getenv("REDSHIFT_MDCD_PORT")) - -# For Oracle: define a schema that can be used to emulate temp tables: -oracleTempSchema <- NULL - -# Details specific to the database: -outputFolder <- file.path(path, "output") -cdmDatabaseSchema <- Sys.getenv("REDSHIFT_MDCD_CDM") -cohortDatabaseSchema <- Sys.getenv("REDSHIFT_MDCD_SCRATCH") -cohortTable <- "yourCohortTable" -databaseId <- "MDCD" -databaseName <- "IBM Medicaid database" -databaseDescription <- "IBM Medicaid database." - -# Use this to run the cohorttDiagnostics. The results will be stored in the diagnosticsExport subfolder of the outputFolder. This can be shared between sites. -examplePackage::runCohortDiagnostics(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - oracleTempSchema = oracleTempSchema, - outputFolder = outputFolder, - databaseId = databaseId, - databaseName = databaseName, - databaseDescription = databaseDescription, - createCohorts = TRUE, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - runBreakdownIndexEvents = TRUE, - runIncidenceRates = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = TRUE, - runTemporalCohortCharacterization = TRUE, - minCellCount = 5) - -# To view the results: -# Optional: if there are results zip files from multiple sites in a folder, this merges them, which will speed up starting the viewer: -CohortDiagnostics::preMergeDiagnosticsFiles(file.path(outputFolder, "diagnosticsExport")) - -# Use this to view the results. Multiple zip files can be in the same folder. If the files were pre-merged, this is automatically detected: -CohortDiagnostics::launchDiagnosticsExplorer(file.path(outputFolder, "diagnosticsExport")) - - -# To explore a specific cohort in the local database, viewing patient profiles: -CohortDiagnostics::launchCohortExplorer(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortId = 123) -# Where 123 is the ID of the cohort you wish to inspect. diff --git a/examplePackage/extras/PackageMaintenance.R b/examplePackage/extras/PackageMaintenance.R deleted file mode 100644 index ae364d133..000000000 --- a/examplePackage/extras/PackageMaintenance.R +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics -# -# This file is part of examplePackage -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Format and check code --------------------------------------------------- -OhdsiRTools::formatRFolder() -OhdsiRTools::checkUsagePackage("examplePackage") -OhdsiRTools::updateCopyrightYearFolder() - -# Create manual ----------------------------------------------------------- -shell("rm extras/examplePackage.pdf") -shell("R CMD Rd2pdf ./ --output=extras/examplePackage.pdf") - - -# Insert cohort definitions from ATLAS into package ----------------------- -ROhdsiWebApi::insertCohortDefinitionSetInPackage(fileName = "inst/settings/CohortsToCreate.csv", - baseUrl = Sys.getenv("ohdsiBaseUrl"), - insertTableSql = TRUE, - insertCohortCreationR = TRUE, - generateStats = TRUE, - packageName = "examplePackage") - -# Store environment in which the study was executed ----------------------- -OhdsiRTools::insertEnvironmentSnapshotInPackage("examplePackage") diff --git a/examplePackage/inst/cohorts/Acute_myocardial_infarction_outcome.json b/examplePackage/inst/cohorts/Acute_myocardial_infarction_outcome.json deleted file mode 100644 index 3a92e8357..000000000 --- a/examplePackage/inst/cohorts/Acute_myocardial_infarction_outcome.json +++ /dev/null @@ -1,184 +0,0 @@ -{ - "cdmVersionRange" : ">=5.0.0", - "PrimaryCriteria" : { - "CriteriaList" : [ - { - "ConditionOccurrence" : { - "CodesetId" : 3, - "ConditionTypeExclude" : false - } - } - ], - "ObservationWindow" : { - "PriorDays" : 0, - "PostDays" : 0 - }, - "PrimaryCriteriaLimit" : { - "Type" : "All" - } - }, - "AdditionalCriteria" : { - "Type" : "ANY", - "CriteriaList" : [ - { - "Criteria" : { - "VisitOccurrence" : { - "CodesetId" : 2, - "VisitTypeExclude" : false - } - }, - "StartWindow" : { - "Start" : { - "Coeff" : -1 - }, - "End" : { - "Days" : 0, - "Coeff" : 1 - }, - "UseEventEnd" : false - }, - "EndWindow" : { - "Start" : { - "Days" : 0, - "Coeff" : -1 - }, - "End" : { - "Coeff" : 1 - }, - "UseEventEnd" : true - }, - "RestrictVisit" : false, - "IgnoreObservationPeriod" : false, - "Occurrence" : { - "Type" : 2, - "Count" : 1, - "IsDistinct" : false - } - } - ], - "DemographicCriteriaList" : [], - "Groups" : [] - }, - "ConceptSets" : [ - { - "id" : 2, - "name" : "Inpatient or ER visit", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 262, - "CONCEPT_NAME" : "Emergency Room and Inpatient Visit", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "ERIP", - "DOMAIN_ID" : "Visit", - "VOCABULARY_ID" : "Visit", - "CONCEPT_CLASS_ID" : "Visit" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 9203, - "CONCEPT_NAME" : "Emergency Room Visit", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "ER", - "DOMAIN_ID" : "Visit", - "VOCABULARY_ID" : "Visit", - "CONCEPT_CLASS_ID" : "Visit" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 9201, - "CONCEPT_NAME" : "Inpatient Visit", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "IP", - "DOMAIN_ID" : "Visit", - "VOCABULARY_ID" : "Visit", - "CONCEPT_CLASS_ID" : "Visit" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - }, - { - "id" : 3, - "name" : "Acute myocardial Infarction", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 4329847, - "CONCEPT_NAME" : "Myocardial infarction", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "22298006", - "DOMAIN_ID" : "Condition", - "VOCABULARY_ID" : "SNOMED", - "CONCEPT_CLASS_ID" : "Clinical Finding" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 314666, - "CONCEPT_NAME" : "Old myocardial infarction", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1755008", - "DOMAIN_ID" : "Condition", - "VOCABULARY_ID" : "SNOMED", - "CONCEPT_CLASS_ID" : "Clinical Finding" - }, - "isExcluded" : true, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - } - ], - "QualifiedLimit" : { - "Type" : "All" - }, - "ExpressionLimit" : { - "Type" : "All" - }, - "InclusionRules" : [], - "EndStrategy" : { - "DateOffset" : { - "DateField" : "StartDate", - "Offset" : 7 - } - }, - "CensoringCriteria" : [], - "CollapseSettings" : { - "CollapseType" : "ERA", - "EraPad" : 180 - }, - "CensorWindow" : {} -} \ No newline at end of file diff --git a/examplePackage/inst/cohorts/Angioedema_outcome.json b/examplePackage/inst/cohorts/Angioedema_outcome.json deleted file mode 100644 index 69ba1f19f..000000000 --- a/examplePackage/inst/cohorts/Angioedema_outcome.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "cdmVersionRange" : ">=5.0.0", - "PrimaryCriteria" : { - "CriteriaList" : [ - { - "ConditionOccurrence" : { - "CodesetId" : 6, - "ConditionTypeExclude" : false - } - } - ], - "ObservationWindow" : { - "PriorDays" : 0, - "PostDays" : 0 - }, - "PrimaryCriteriaLimit" : { - "Type" : "All" - } - }, - "AdditionalCriteria" : { - "Type" : "ANY", - "CriteriaList" : [ - { - "Criteria" : { - "VisitOccurrence" : { - "CodesetId" : 2, - "VisitTypeExclude" : false - } - }, - "StartWindow" : { - "Start" : { - "Coeff" : -1 - }, - "End" : { - "Days" : 0, - "Coeff" : 1 - }, - "UseEventEnd" : false - }, - "EndWindow" : { - "Start" : { - "Days" : 0, - "Coeff" : -1 - }, - "End" : { - "Coeff" : 1 - }, - "UseEventEnd" : true - }, - "RestrictVisit" : false, - "IgnoreObservationPeriod" : false, - "Occurrence" : { - "Type" : 2, - "Count" : 1, - "IsDistinct" : false - } - } - ], - "DemographicCriteriaList" : [], - "Groups" : [] - }, - "ConceptSets" : [ - { - "id" : 2, - "name" : "Inpatient or ER visit", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 262, - "CONCEPT_NAME" : "Emergency Room and Inpatient Visit", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "ERIP", - "DOMAIN_ID" : "Visit", - "VOCABULARY_ID" : "Visit", - "CONCEPT_CLASS_ID" : "Visit" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 9203, - "CONCEPT_NAME" : "Emergency Room Visit", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "ER", - "DOMAIN_ID" : "Visit", - "VOCABULARY_ID" : "Visit", - "CONCEPT_CLASS_ID" : "Visit" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 9201, - "CONCEPT_NAME" : "Inpatient Visit", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "IP", - "DOMAIN_ID" : "Visit", - "VOCABULARY_ID" : "Visit", - "CONCEPT_CLASS_ID" : "Visit" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - }, - { - "id" : 6, - "name" : "[LEGEND HTN] Angioedema", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 432791, - "CONCEPT_NAME" : "Angioedema", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "41291007", - "DOMAIN_ID" : "Condition", - "VOCABULARY_ID" : "SNOMED", - "CONCEPT_CLASS_ID" : "Clinical Finding" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - } - ], - "QualifiedLimit" : { - "Type" : "All" - }, - "ExpressionLimit" : { - "Type" : "All" - }, - "InclusionRules" : [], - "EndStrategy" : { - "DateOffset" : { - "DateField" : "StartDate", - "Offset" : 7 - } - }, - "CensoringCriteria" : [], - "CollapseSettings" : { - "CollapseType" : "ERA", - "EraPad" : 30 - }, - "CensorWindow" : {} -} \ No newline at end of file diff --git a/examplePackage/inst/cohorts/InclusionRules.csv b/examplePackage/inst/cohorts/InclusionRules.csv deleted file mode 100644 index 38b4215ee..000000000 --- a/examplePackage/inst/cohorts/InclusionRules.csv +++ /dev/null @@ -1,7 +0,0 @@ -cohortName,ruleSequence,ruleName,cohortId -New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2,0,has hypertension diagnosis in 1 yr prior to treatment,1770710 -New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2,1,Has no prior antihypertensive drug exposures in medical history,1770710 -New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2,2,"Is only taking ACE as monotherapy, with no concomitant combination treatments",1770710 -New_users_of_Thiazidelike_diuretics_as_firstline_monotherapy_for_hypertension_2,0,has hypertension diagnosis in 1 yr prior to treatment,1770711 -New_users_of_Thiazidelike_diuretics_as_firstline_monotherapy_for_hypertension_2,1,Has no prior antihypertensive drug exposures in medical history,1770711 -New_users_of_Thiazidelike_diuretics_as_firstline_monotherapy_for_hypertension_2,2,"Is only taking ACE as monotherapy, with no concomitant combination treatments",1770711 diff --git a/examplePackage/inst/cohorts/New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2.json b/examplePackage/inst/cohorts/New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2.json deleted file mode 100644 index 076cf6f7d..000000000 --- a/examplePackage/inst/cohorts/New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2.json +++ /dev/null @@ -1,1865 +0,0 @@ -{ - "cdmVersionRange" : ">=5.0.0", - "PrimaryCriteria" : { - "CriteriaList" : [ - { - "DrugExposure" : { - "CodesetId" : 3, - "First" : true, - "DrugTypeExclude" : false - } - } - ], - "ObservationWindow" : { - "PriorDays" : 365, - "PostDays" : 0 - }, - "PrimaryCriteriaLimit" : { - "Type" : "First" - } - }, - "ConceptSets" : [ - { - "id" : 0, - "name" : "Hypertensive disorder", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 316866, - "CONCEPT_NAME" : "Hypertensive disorder", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "38341003", - "DOMAIN_ID" : "Condition", - "VOCABULARY_ID" : "SNOMED", - "CONCEPT_CLASS_ID" : "Clinical Finding" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - }, - { - "id" : 1, - "name" : "First-line hypertension drugs", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 1332418, - "CONCEPT_NAME" : "Amlodipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "17767", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 40235485, - "CONCEPT_NAME" : "azilsartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1091643", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1335471, - "CONCEPT_NAME" : "benazepril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "18867", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1351557, - "CONCEPT_NAME" : "candesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "214354", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1340128, - "CONCEPT_NAME" : "Captopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1998", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1395058, - "CONCEPT_NAME" : "Chlorthalidone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "2409", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1328165, - "CONCEPT_NAME" : "Diltiazem", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "3443", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1341927, - "CONCEPT_NAME" : "Enalapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "3827", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1346686, - "CONCEPT_NAME" : "eprosartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "83515", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1353776, - "CONCEPT_NAME" : "Felodipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "4316", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1363749, - "CONCEPT_NAME" : "Fosinopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "50166", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 974166, - "CONCEPT_NAME" : "Hydrochlorothiazide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5487", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 978555, - "CONCEPT_NAME" : "Indapamide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5764", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1347384, - "CONCEPT_NAME" : "irbesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "83818", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1326012, - "CONCEPT_NAME" : "Isradipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "33910", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1308216, - "CONCEPT_NAME" : "Lisinopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "29046", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1367500, - "CONCEPT_NAME" : "Losartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "52175", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 907013, - "CONCEPT_NAME" : "Metolazone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6916", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1310756, - "CONCEPT_NAME" : "moexipril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "30131", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1318137, - "CONCEPT_NAME" : "Nicardipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7396", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1318853, - "CONCEPT_NAME" : "Nifedipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7417", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1319880, - "CONCEPT_NAME" : "Nisoldipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7435", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 40226742, - "CONCEPT_NAME" : "olmesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "321064", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1373225, - "CONCEPT_NAME" : "Perindopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "54552", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1331235, - "CONCEPT_NAME" : "quinapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "35208", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1334456, - "CONCEPT_NAME" : "Ramipril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "35296", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1317640, - "CONCEPT_NAME" : "telmisartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "73494", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1342439, - "CONCEPT_NAME" : "trandolapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "38454", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1308842, - "CONCEPT_NAME" : "valsartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "69749", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1307863, - "CONCEPT_NAME" : "Verapamil", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "11170", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - }, - { - "id" : 2, - "name" : "Hypertension drugs", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 1319998, - "CONCEPT_NAME" : "Acebutolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "149", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1317967, - "CONCEPT_NAME" : "aliskiren", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "325646", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 991382, - "CONCEPT_NAME" : "Amiloride", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "644", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1332418, - "CONCEPT_NAME" : "Amlodipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "17767", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1314002, - "CONCEPT_NAME" : "Atenolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1202", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 40235485, - "CONCEPT_NAME" : "azilsartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1091643", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1335471, - "CONCEPT_NAME" : "benazepril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "18867", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1322081, - "CONCEPT_NAME" : "Betaxolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1520", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1338005, - "CONCEPT_NAME" : "Bisoprolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "19484", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 932745, - "CONCEPT_NAME" : "Bumetanide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1808", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1351557, - "CONCEPT_NAME" : "candesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "214354", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1340128, - "CONCEPT_NAME" : "Captopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1998", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1346823, - "CONCEPT_NAME" : "carvedilol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "20352", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1395058, - "CONCEPT_NAME" : "Chlorthalidone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "2409", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1398937, - "CONCEPT_NAME" : "Clonidine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "2599", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1328165, - "CONCEPT_NAME" : "Diltiazem", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "3443", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1363053, - "CONCEPT_NAME" : "Doxazosin", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "49276", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1341927, - "CONCEPT_NAME" : "Enalapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "3827", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1309799, - "CONCEPT_NAME" : "eplerenone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "298869", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1346686, - "CONCEPT_NAME" : "eprosartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "83515", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1353776, - "CONCEPT_NAME" : "Felodipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "4316", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1363749, - "CONCEPT_NAME" : "Fosinopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "50166", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 956874, - "CONCEPT_NAME" : "Furosemide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "4603", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1344965, - "CONCEPT_NAME" : "Guanfacine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "40114", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1373928, - "CONCEPT_NAME" : "Hydralazine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5470", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 974166, - "CONCEPT_NAME" : "Hydrochlorothiazide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5487", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 978555, - "CONCEPT_NAME" : "Indapamide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5764", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1347384, - "CONCEPT_NAME" : "irbesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "83818", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1326012, - "CONCEPT_NAME" : "Isradipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "33910", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1386957, - "CONCEPT_NAME" : "Labetalol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6185", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1308216, - "CONCEPT_NAME" : "Lisinopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "29046", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1367500, - "CONCEPT_NAME" : "Losartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "52175", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1305447, - "CONCEPT_NAME" : "Methyldopa", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6876", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 907013, - "CONCEPT_NAME" : "Metolazone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6916", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1307046, - "CONCEPT_NAME" : "Metoprolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6918", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1309068, - "CONCEPT_NAME" : "Minoxidil", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6984", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1310756, - "CONCEPT_NAME" : "moexipril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "30131", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1313200, - "CONCEPT_NAME" : "Nadolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7226", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1314577, - "CONCEPT_NAME" : "nebivolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "31555", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1318137, - "CONCEPT_NAME" : "Nicardipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7396", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1318853, - "CONCEPT_NAME" : "Nifedipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7417", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1319880, - "CONCEPT_NAME" : "Nisoldipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7435", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 40226742, - "CONCEPT_NAME" : "olmesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "321064", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1327978, - "CONCEPT_NAME" : "Penbutolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7973", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1373225, - "CONCEPT_NAME" : "Perindopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "54552", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1345858, - "CONCEPT_NAME" : "Pindolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "8332", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1350489, - "CONCEPT_NAME" : "Prazosin", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "8629", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1353766, - "CONCEPT_NAME" : "Propranolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "8787", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1331235, - "CONCEPT_NAME" : "quinapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "35208", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1334456, - "CONCEPT_NAME" : "Ramipril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "35296", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 970250, - "CONCEPT_NAME" : "Spironolactone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "9997", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1317640, - "CONCEPT_NAME" : "telmisartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "73494", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1341238, - "CONCEPT_NAME" : "Terazosin", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "37798", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 942350, - "CONCEPT_NAME" : "torsemide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "38413", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1342439, - "CONCEPT_NAME" : "trandolapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "38454", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 904542, - "CONCEPT_NAME" : "Triamterene", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "10763", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1308842, - "CONCEPT_NAME" : "valsartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "69749", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1307863, - "CONCEPT_NAME" : "Verapamil", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "11170", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - }, - { - "id" : 3, - "name" : "ACE inhibitors", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 1335471, - "CONCEPT_NAME" : "benazepril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "18867", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1340128, - "CONCEPT_NAME" : "Captopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1998", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1341927, - "CONCEPT_NAME" : "Enalapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "3827", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1363749, - "CONCEPT_NAME" : "Fosinopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "50166", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1308216, - "CONCEPT_NAME" : "Lisinopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "29046", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1310756, - "CONCEPT_NAME" : "moexipril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "30131", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1373225, - "CONCEPT_NAME" : "Perindopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "54552", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1331235, - "CONCEPT_NAME" : "quinapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "35208", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1334456, - "CONCEPT_NAME" : "Ramipril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "35296", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1342439, - "CONCEPT_NAME" : "trandolapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "38454", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - } - ], - "QualifiedLimit" : { - "Type" : "First" - }, - "ExpressionLimit" : { - "Type" : "First" - }, - "InclusionRules" : [ - { - "name" : "has hypertension diagnosis in 1 yr prior to treatment", - "expression" : { - "Type" : "ALL", - "CriteriaList" : [ - { - "Criteria" : { - "ConditionOccurrence" : { - "CodesetId" : 0, - "ConditionTypeExclude" : false - } - }, - "StartWindow" : { - "Start" : { - "Days" : 365, - "Coeff" : -1 - }, - "End" : { - "Days" : 0, - "Coeff" : 1 - }, - "UseEventEnd" : false - }, - "RestrictVisit" : false, - "IgnoreObservationPeriod" : false, - "Occurrence" : { - "Type" : 2, - "Count" : 1, - "IsDistinct" : false - } - } - ], - "DemographicCriteriaList" : [], - "Groups" : [] - } - }, - { - "name" : "Has no prior antihypertensive drug exposures in medical history", - "expression" : { - "Type" : "ALL", - "CriteriaList" : [ - { - "Criteria" : { - "DrugExposure" : { - "CodesetId" : 2, - "DrugTypeExclude" : false - } - }, - "StartWindow" : { - "Start" : { - "Coeff" : -1 - }, - "End" : { - "Days" : 1, - "Coeff" : -1 - }, - "UseEventEnd" : false - }, - "RestrictVisit" : false, - "IgnoreObservationPeriod" : false, - "Occurrence" : { - "Type" : 0, - "Count" : 0, - "IsDistinct" : false - } - } - ], - "DemographicCriteriaList" : [], - "Groups" : [] - } - }, - { - "name" : "Is only taking ACE as monotherapy, with no concomitant combination treatments", - "expression" : { - "Type" : "ALL", - "CriteriaList" : [ - { - "Criteria" : { - "DrugEra" : { - "CodesetId" : 2 - } - }, - "StartWindow" : { - "Start" : { - "Days" : 0, - "Coeff" : -1 - }, - "End" : { - "Days" : 7, - "Coeff" : 1 - }, - "UseEventEnd" : false - }, - "RestrictVisit" : false, - "IgnoreObservationPeriod" : false, - "Occurrence" : { - "Type" : 0, - "Count" : 1, - "IsDistinct" : true - } - } - ], - "DemographicCriteriaList" : [], - "Groups" : [] - } - } - ], - "EndStrategy" : { - "CustomEra" : { - "DrugCodesetId" : 3, - "GapDays" : 30, - "Offset" : 0 - } - }, - "CensoringCriteria" : [], - "CollapseSettings" : { - "CollapseType" : "ERA", - "EraPad" : 0 - }, - "CensorWindow" : {} -} \ No newline at end of file diff --git a/examplePackage/inst/cohorts/New_users_of_Thiazidelike_diuretics_as_firstline_monotherapy_for_hypertension_2.json b/examplePackage/inst/cohorts/New_users_of_Thiazidelike_diuretics_as_firstline_monotherapy_for_hypertension_2.json deleted file mode 100644 index fe58c8525..000000000 --- a/examplePackage/inst/cohorts/New_users_of_Thiazidelike_diuretics_as_firstline_monotherapy_for_hypertension_2.json +++ /dev/null @@ -1,1763 +0,0 @@ -{ - "cdmVersionRange" : ">=5.0.0", - "PrimaryCriteria" : { - "CriteriaList" : [ - { - "DrugExposure" : { - "CodesetId" : 4, - "First" : true, - "DrugTypeExclude" : false - } - } - ], - "ObservationWindow" : { - "PriorDays" : 365, - "PostDays" : 0 - }, - "PrimaryCriteriaLimit" : { - "Type" : "First" - } - }, - "ConceptSets" : [ - { - "id" : 0, - "name" : "Hypertensive disorder", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 316866, - "CONCEPT_NAME" : "Hypertensive disorder", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "38341003", - "DOMAIN_ID" : "Condition", - "VOCABULARY_ID" : "SNOMED", - "CONCEPT_CLASS_ID" : "Clinical Finding" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - }, - { - "id" : 1, - "name" : "First-line hypertension drugs", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 1332418, - "CONCEPT_NAME" : "Amlodipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "17767", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 40235485, - "CONCEPT_NAME" : "azilsartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1091643", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1335471, - "CONCEPT_NAME" : "benazepril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "18867", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1351557, - "CONCEPT_NAME" : "candesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "214354", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1340128, - "CONCEPT_NAME" : "Captopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1998", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1395058, - "CONCEPT_NAME" : "Chlorthalidone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "2409", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1328165, - "CONCEPT_NAME" : "Diltiazem", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "3443", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1341927, - "CONCEPT_NAME" : "Enalapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "3827", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1346686, - "CONCEPT_NAME" : "eprosartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "83515", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1353776, - "CONCEPT_NAME" : "Felodipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "4316", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1363749, - "CONCEPT_NAME" : "Fosinopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "50166", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 974166, - "CONCEPT_NAME" : "Hydrochlorothiazide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5487", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 978555, - "CONCEPT_NAME" : "Indapamide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5764", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1347384, - "CONCEPT_NAME" : "irbesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "83818", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1326012, - "CONCEPT_NAME" : "Isradipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "33910", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1308216, - "CONCEPT_NAME" : "Lisinopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "29046", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1367500, - "CONCEPT_NAME" : "Losartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "52175", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 907013, - "CONCEPT_NAME" : "Metolazone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6916", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1310756, - "CONCEPT_NAME" : "moexipril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "30131", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1318137, - "CONCEPT_NAME" : "Nicardipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7396", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1318853, - "CONCEPT_NAME" : "Nifedipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7417", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1319880, - "CONCEPT_NAME" : "Nisoldipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7435", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 40226742, - "CONCEPT_NAME" : "olmesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "321064", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1373225, - "CONCEPT_NAME" : "Perindopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "54552", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1331235, - "CONCEPT_NAME" : "quinapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "35208", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1334456, - "CONCEPT_NAME" : "Ramipril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "35296", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1317640, - "CONCEPT_NAME" : "telmisartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "73494", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1342439, - "CONCEPT_NAME" : "trandolapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "38454", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1308842, - "CONCEPT_NAME" : "valsartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "69749", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1307863, - "CONCEPT_NAME" : "Verapamil", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "11170", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - }, - { - "id" : 2, - "name" : "Hypertension drugs", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 1319998, - "CONCEPT_NAME" : "Acebutolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "149", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1317967, - "CONCEPT_NAME" : "aliskiren", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "325646", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 991382, - "CONCEPT_NAME" : "Amiloride", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "644", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1332418, - "CONCEPT_NAME" : "Amlodipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "17767", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1314002, - "CONCEPT_NAME" : "Atenolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1202", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 40235485, - "CONCEPT_NAME" : "azilsartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1091643", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1335471, - "CONCEPT_NAME" : "benazepril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "18867", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1322081, - "CONCEPT_NAME" : "Betaxolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1520", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1338005, - "CONCEPT_NAME" : "Bisoprolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "19484", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 932745, - "CONCEPT_NAME" : "Bumetanide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1808", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1351557, - "CONCEPT_NAME" : "candesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "214354", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1340128, - "CONCEPT_NAME" : "Captopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "1998", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1346823, - "CONCEPT_NAME" : "carvedilol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "20352", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1395058, - "CONCEPT_NAME" : "Chlorthalidone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "2409", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1398937, - "CONCEPT_NAME" : "Clonidine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "2599", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1328165, - "CONCEPT_NAME" : "Diltiazem", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "3443", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1363053, - "CONCEPT_NAME" : "Doxazosin", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "49276", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1341927, - "CONCEPT_NAME" : "Enalapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "3827", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1309799, - "CONCEPT_NAME" : "eplerenone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "298869", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1346686, - "CONCEPT_NAME" : "eprosartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "83515", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1353776, - "CONCEPT_NAME" : "Felodipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "4316", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1363749, - "CONCEPT_NAME" : "Fosinopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "50166", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 956874, - "CONCEPT_NAME" : "Furosemide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "4603", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1344965, - "CONCEPT_NAME" : "Guanfacine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "40114", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1373928, - "CONCEPT_NAME" : "Hydralazine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5470", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 974166, - "CONCEPT_NAME" : "Hydrochlorothiazide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5487", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 978555, - "CONCEPT_NAME" : "Indapamide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5764", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1347384, - "CONCEPT_NAME" : "irbesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "83818", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1326012, - "CONCEPT_NAME" : "Isradipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "33910", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1386957, - "CONCEPT_NAME" : "Labetalol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6185", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1308216, - "CONCEPT_NAME" : "Lisinopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "29046", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1367500, - "CONCEPT_NAME" : "Losartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "52175", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1305447, - "CONCEPT_NAME" : "Methyldopa", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6876", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 907013, - "CONCEPT_NAME" : "Metolazone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6916", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1307046, - "CONCEPT_NAME" : "Metoprolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6918", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1309068, - "CONCEPT_NAME" : "Minoxidil", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6984", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1310756, - "CONCEPT_NAME" : "moexipril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "30131", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1313200, - "CONCEPT_NAME" : "Nadolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7226", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1314577, - "CONCEPT_NAME" : "nebivolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "31555", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1318137, - "CONCEPT_NAME" : "Nicardipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7396", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1318853, - "CONCEPT_NAME" : "Nifedipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7417", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1319880, - "CONCEPT_NAME" : "Nisoldipine", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7435", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 40226742, - "CONCEPT_NAME" : "olmesartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "321064", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1327978, - "CONCEPT_NAME" : "Penbutolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "7973", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1373225, - "CONCEPT_NAME" : "Perindopril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "54552", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1345858, - "CONCEPT_NAME" : "Pindolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "8332", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1350489, - "CONCEPT_NAME" : "Prazosin", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "8629", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1353766, - "CONCEPT_NAME" : "Propranolol", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "8787", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1331235, - "CONCEPT_NAME" : "quinapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "35208", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1334456, - "CONCEPT_NAME" : "Ramipril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "35296", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 970250, - "CONCEPT_NAME" : "Spironolactone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "9997", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1317640, - "CONCEPT_NAME" : "telmisartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "73494", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1341238, - "CONCEPT_NAME" : "Terazosin", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "37798", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 942350, - "CONCEPT_NAME" : "torsemide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "38413", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1342439, - "CONCEPT_NAME" : "trandolapril", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "38454", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 904542, - "CONCEPT_NAME" : "Triamterene", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "10763", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1308842, - "CONCEPT_NAME" : "valsartan", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "69749", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 1307863, - "CONCEPT_NAME" : "Verapamil", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "11170", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - }, - { - "id" : 4, - "name" : "Thiazide or thiazide-like diuretic", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 1395058, - "CONCEPT_NAME" : "Chlorthalidone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "2409", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 974166, - "CONCEPT_NAME" : "Hydrochlorothiazide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5487", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 978555, - "CONCEPT_NAME" : "Indapamide", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "5764", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - }, - { - "concept" : { - "CONCEPT_ID" : 907013, - "CONCEPT_NAME" : "Metolazone", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "6916", - "DOMAIN_ID" : "Drug", - "VOCABULARY_ID" : "RxNorm", - "CONCEPT_CLASS_ID" : "Ingredient" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - } - ], - "QualifiedLimit" : { - "Type" : "First" - }, - "ExpressionLimit" : { - "Type" : "First" - }, - "InclusionRules" : [ - { - "name" : "has hypertension diagnosis in 1 yr prior to treatment", - "expression" : { - "Type" : "ALL", - "CriteriaList" : [ - { - "Criteria" : { - "ConditionOccurrence" : { - "CodesetId" : 0, - "ConditionTypeExclude" : false - } - }, - "StartWindow" : { - "Start" : { - "Days" : 365, - "Coeff" : -1 - }, - "End" : { - "Days" : 0, - "Coeff" : 1 - }, - "UseEventEnd" : false - }, - "RestrictVisit" : false, - "IgnoreObservationPeriod" : false, - "Occurrence" : { - "Type" : 2, - "Count" : 1, - "IsDistinct" : false - } - } - ], - "DemographicCriteriaList" : [], - "Groups" : [] - } - }, - { - "name" : "Has no prior antihypertensive drug exposures in medical history", - "expression" : { - "Type" : "ALL", - "CriteriaList" : [ - { - "Criteria" : { - "DrugExposure" : { - "CodesetId" : 2, - "DrugTypeExclude" : false - } - }, - "StartWindow" : { - "Start" : { - "Coeff" : -1 - }, - "End" : { - "Days" : 1, - "Coeff" : -1 - }, - "UseEventEnd" : false - }, - "RestrictVisit" : false, - "IgnoreObservationPeriod" : false, - "Occurrence" : { - "Type" : 0, - "Count" : 0, - "IsDistinct" : false - } - } - ], - "DemographicCriteriaList" : [], - "Groups" : [] - } - }, - { - "name" : "Is only taking ACE as monotherapy, with no concomitant combination treatments", - "expression" : { - "Type" : "ALL", - "CriteriaList" : [ - { - "Criteria" : { - "DrugEra" : { - "CodesetId" : 2 - } - }, - "StartWindow" : { - "Start" : { - "Days" : 0, - "Coeff" : -1 - }, - "End" : { - "Days" : 7, - "Coeff" : 1 - }, - "UseEventEnd" : false - }, - "RestrictVisit" : false, - "IgnoreObservationPeriod" : false, - "Occurrence" : { - "Type" : 0, - "Count" : 1, - "IsDistinct" : true - } - } - ], - "DemographicCriteriaList" : [], - "Groups" : [] - } - } - ], - "EndStrategy" : { - "CustomEra" : { - "DrugCodesetId" : 4, - "GapDays" : 30, - "Offset" : 0 - } - }, - "CensoringCriteria" : [], - "CollapseSettings" : { - "CollapseType" : "ERA", - "EraPad" : 0 - }, - "CensorWindow" : {} -} \ No newline at end of file diff --git a/examplePackage/inst/settings/CohortsToCreate.csv b/examplePackage/inst/settings/CohortsToCreate.csv deleted file mode 100644 index abf77548c..000000000 --- a/examplePackage/inst/settings/CohortsToCreate.csv +++ /dev/null @@ -1,5 +0,0 @@ -atlasId,atlasName,cohortId,name -1770710,New users of ACE inhibitors as first-line monotherapy for hypertension (2),1770710,New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2 -1770711,New users of Thiazide-like diuretics as first-line monotherapy for hypertension (2),1770711,New_users_of_Thiazidelike_diuretics_as_firstline_monotherapy_for_hypertension_2 -1770712,Angioedema outcome,1770712,Angioedema_outcome -1770713,Acute myocardial infarction outcome,1770713,Acute_myocardial_infarction_outcome diff --git a/examplePackage/inst/sql/sql_server/CreateCohortTable.sql b/examplePackage/inst/sql/sql_server/CreateCohortTable.sql deleted file mode 100644 index 1bfcbb604..000000000 --- a/examplePackage/inst/sql/sql_server/CreateCohortTable.sql +++ /dev/null @@ -1,41 +0,0 @@ -IF OBJECT_ID('@cohort_database_schema.@cohort_table', 'U') IS NOT NULL - DROP TABLE @cohort_database_schema.@cohort_table; - -CREATE TABLE @cohort_database_schema.@cohort_table ( - cohort_definition_id BIGINT, - subject_id BIGINT, - cohort_start_date DATE, - cohort_end_date DATE - ); - -IF OBJECT_ID('tempdb..#cohort_inc_result', 'U') IS NOT NULL - DROP TABLE #cohort_inc_result; - -IF OBJECT_ID('tempdb..#cohort_inc_stats', 'U') IS NOT NULL - DROP TABLE #cohort_inc_stats; - -IF OBJECT_ID('tempdb..#cohort_summary_stats', 'U') IS NOT NULL - DROP TABLE #cohort_summary_stats; - -CREATE TABLE #cohort_inc_result ( - cohort_definition_id BIGINT NOT NULL, - inclusion_rule_mask BIGINT NOT NULL, - person_count BIGINT NOT NULL, - mode_id INT - ); - -CREATE TABLE #cohort_inc_stats ( - cohort_definition_id BIGINT NOT NULL, - rule_sequence INT NOT NULL, - person_count BIGINT NOT NULL, - gain_count BIGINT NOT NULL, - person_total BIGINT NOT NULL, - mode_id INT - ); - -CREATE TABLE #cohort_summary_stats ( - cohort_definition_id BIGINT NOT NULL, - base_count BIGINT NOT NULL, - final_count BIGINT NOT NULL, - mode_id INT - ); diff --git a/examplePackage/inst/sql/sql_server/GetCounts.sql b/examplePackage/inst/sql/sql_server/GetCounts.sql deleted file mode 100644 index c627768ac..000000000 --- a/examplePackage/inst/sql/sql_server/GetCounts.sql +++ /dev/null @@ -1,26 +0,0 @@ -/************************************************************************ -Copyright 2020 Observational Health Data Sciences and Informatics - -This file is part of exampleStudy - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -************************************************************************/ -{DEFAULT @cdm_database_schema = "cdm"} -{DEFAULT @work_database_schema = "cdm"} -{DEFAULT @study_cohort_table = "cohort"} - -SELECT cohort_definition_id, - COUNT(*) AS cohort_count, - COUNT(DISTINCT subject_id) AS person_count -FROM @work_database_schema.@study_cohort_table -GROUP BY cohort_definition_id; diff --git a/examplePackage/inst/sql/sql_server/New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2.sql b/examplePackage/inst/sql/sql_server/New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2.sql deleted file mode 100644 index 32a481b05..000000000 --- a/examplePackage/inst/sql/sql_server/New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2.sql +++ /dev/null @@ -1,584 +0,0 @@ -CREATE TABLE #Codesets ( - codeset_id int NOT NULL, - concept_id bigint NOT NULL -) -; - -INSERT INTO #Codesets (codeset_id, concept_id) -SELECT 0 as codeset_id, c.concept_id FROM (select distinct I.concept_id FROM -( - select concept_id from @vocabulary_database_schema.CONCEPT where concept_id in (316866) -UNION select c.concept_id - from @vocabulary_database_schema.CONCEPT c - join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (316866) - and c.invalid_reason is null - -) I -) C UNION ALL -SELECT 1 as codeset_id, c.concept_id FROM (select distinct I.concept_id FROM -( - select concept_id from @vocabulary_database_schema.CONCEPT where concept_id in (1332418,40235485,1335471,1351557,1340128,1395058,1328165,1341927,1346686,1353776,1363749,974166,978555,1347384,1326012,1308216,1367500,907013,1310756,1318137,1318853,1319880,40226742,1373225,1331235,1334456,1317640,1342439,1308842,1307863) -UNION select c.concept_id - from @vocabulary_database_schema.CONCEPT c - join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (1332418,40235485,1335471,1351557,1340128,1395058,1328165,1341927,1346686,1353776,1363749,974166,978555,1347384,1326012,1308216,1367500,907013,1310756,1318137,1318853,1319880,40226742,1373225,1331235,1334456,1317640,1342439,1308842,1307863) - and c.invalid_reason is null - -) I -) C UNION ALL -SELECT 2 as codeset_id, c.concept_id FROM (select distinct I.concept_id FROM -( - select concept_id from @vocabulary_database_schema.CONCEPT where concept_id in (1319998,1317967,991382,1332418,1314002,40235485,1335471,1322081,1338005,932745,1351557,1340128,1346823,1395058,1398937,1328165,1363053,1341927,1309799,1346686,1353776,1363749,956874,1344965,1373928,974166,978555,1347384,1326012,1386957,1308216,1367500,1305447,907013,1307046,1309068,1310756,1313200,1314577,1318137,1318853,1319880,40226742,1327978,1373225,1345858,1350489,1353766,1331235,1334456,970250,1317640,1341238,942350,1342439,904542,1308842,1307863) -UNION select c.concept_id - from @vocabulary_database_schema.CONCEPT c - join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (1319998,1317967,991382,1332418,1314002,40235485,1335471,1322081,1338005,932745,1351557,1340128,1346823,1395058,1398937,1328165,1363053,1341927,1309799,1346686,1353776,1363749,956874,1344965,1373928,974166,978555,1347384,1326012,1386957,1308216,1367500,1305447,907013,1307046,1309068,1310756,1313200,1314577,1318137,1318853,1319880,40226742,1327978,1373225,1345858,1350489,1353766,1331235,1334456,970250,1317640,1341238,942350,1342439,904542,1308842,1307863) - and c.invalid_reason is null - -) I -) C UNION ALL -SELECT 3 as codeset_id, c.concept_id FROM (select distinct I.concept_id FROM -( - select concept_id from @vocabulary_database_schema.CONCEPT where concept_id in (1335471,1340128,1341927,1363749,1308216,1310756,1373225,1331235,1334456,1342439) -UNION select c.concept_id - from @vocabulary_database_schema.CONCEPT c - join @vocabulary_database_schema.CONCEPT_ANCESTOR ca on c.concept_id = ca.descendant_concept_id - and ca.ancestor_concept_id in (1335471,1340128,1341927,1363749,1308216,1310756,1373225,1331235,1334456,1342439) - and c.invalid_reason is null - -) I -) C -; - -with primary_events (event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id) as -( --- Begin Primary Events -select P.ordinal as event_id, P.person_id, P.start_date, P.end_date, op_start_date, op_end_date, cast(P.visit_occurrence_id as bigint) as visit_occurrence_id -FROM -( - select E.person_id, E.start_date, E.end_date, - row_number() OVER (PARTITION BY E.person_id ORDER BY E.sort_date ASC) ordinal, - OP.observation_period_start_date as op_start_date, OP.observation_period_end_date as op_end_date, cast(E.visit_occurrence_id as bigint) as visit_occurrence_id - FROM - ( - -- Begin Drug Exposure Criteria -select C.person_id, C.drug_exposure_id as event_id, C.drug_exposure_start_date as start_date, - COALESCE(C.drug_exposure_end_date, DATEADD(day, 1, C.drug_exposure_start_date)) as end_date, C.drug_concept_id as TARGET_CONCEPT_ID, C.visit_occurrence_id, - C.drug_exposure_start_date as sort_date -from -( - select de.* , row_number() over (PARTITION BY de.person_id ORDER BY de.drug_exposure_start_date, de.drug_exposure_id) as ordinal - FROM @cdm_database_schema.DRUG_EXPOSURE de -JOIN #Codesets codesets on ((de.drug_concept_id = codesets.concept_id and codesets.codeset_id = 3)) -) C - -WHERE C.ordinal = 1 --- End Drug Exposure Criteria - - ) E - JOIN @cdm_database_schema.observation_period OP on E.person_id = OP.person_id and E.start_date >= OP.observation_period_start_date and E.start_date <= op.observation_period_end_date - WHERE DATEADD(day,365,OP.OBSERVATION_PERIOD_START_DATE) <= E.START_DATE AND DATEADD(day,0,E.START_DATE) <= OP.OBSERVATION_PERIOD_END_DATE -) P -WHERE P.ordinal = 1 --- End Primary Events - -) -SELECT event_id, person_id, start_date, end_date, op_start_date, op_end_date, visit_occurrence_id -INTO #qualified_events -FROM -( - select pe.event_id, pe.person_id, pe.start_date, pe.end_date, pe.op_start_date, pe.op_end_date, row_number() over (partition by pe.person_id order by pe.start_date ASC) as ordinal, cast(pe.visit_occurrence_id as bigint) as visit_occurrence_id - FROM primary_events pe - -) QE - -; - ---- Inclusion Rule Inserts - -select 0 as inclusion_rule_id, person_id, event_id -INTO #Inclusion_0 -FROM -( - select pe.person_id, pe.event_id - FROM #qualified_events pe - -JOIN ( --- Begin Criteria Group -select 0 as index_id, person_id, event_id -FROM -( - select E.person_id, E.event_id - FROM #qualified_events E - INNER JOIN - ( - -- Begin Correlated Criteria -SELECT 0 as index_id, p.person_id, p.event_id -FROM #qualified_events P -INNER JOIN -( - -- Begin Condition Occurrence Criteria -SELECT C.person_id, C.condition_occurrence_id as event_id, C.condition_start_date as start_date, COALESCE(C.condition_end_date, DATEADD(day,1,C.condition_start_date)) as end_date, - C.CONDITION_CONCEPT_ID as TARGET_CONCEPT_ID, C.visit_occurrence_id, - C.condition_start_date as sort_date -FROM -( - SELECT co.* - FROM @cdm_database_schema.CONDITION_OCCURRENCE co - JOIN #Codesets codesets on ((co.condition_concept_id = codesets.concept_id and codesets.codeset_id = 0)) -) C - - --- End Condition Occurrence Criteria - -) A on A.person_id = P.person_id AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE AND A.START_DATE >= DATEADD(day,-365,P.START_DATE) AND A.START_DATE <= DATEADD(day,0,P.START_DATE) -GROUP BY p.person_id, p.event_id -HAVING COUNT(A.TARGET_CONCEPT_ID) >= 1 --- End Correlated Criteria - - ) CQ on E.person_id = CQ.person_id and E.event_id = CQ.event_id - GROUP BY E.person_id, E.event_id - HAVING COUNT(index_id) = 1 -) G --- End Criteria Group -) AC on AC.person_id = pe.person_id AND AC.event_id = pe.event_id -) Results -; - -select 1 as inclusion_rule_id, person_id, event_id -INTO #Inclusion_1 -FROM -( - select pe.person_id, pe.event_id - FROM #qualified_events pe - -JOIN ( --- Begin Criteria Group -select 0 as index_id, person_id, event_id -FROM -( - select E.person_id, E.event_id - FROM #qualified_events E - INNER JOIN - ( - -- Begin Correlated Criteria -SELECT 0 as index_id, p.person_id, p.event_id -FROM #qualified_events P -LEFT JOIN -( - -- Begin Drug Exposure Criteria -select C.person_id, C.drug_exposure_id as event_id, C.drug_exposure_start_date as start_date, - COALESCE(C.drug_exposure_end_date, DATEADD(day, 1, C.drug_exposure_start_date)) as end_date, C.drug_concept_id as TARGET_CONCEPT_ID, C.visit_occurrence_id, - C.drug_exposure_start_date as sort_date -from -( - select de.* - FROM @cdm_database_schema.DRUG_EXPOSURE de -JOIN #Codesets codesets on ((de.drug_concept_id = codesets.concept_id and codesets.codeset_id = 2)) -) C - - --- End Drug Exposure Criteria - -) A on A.person_id = P.person_id AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= DATEADD(day,-1,P.START_DATE) -GROUP BY p.person_id, p.event_id -HAVING COUNT(A.TARGET_CONCEPT_ID) = 0 --- End Correlated Criteria - - ) CQ on E.person_id = CQ.person_id and E.event_id = CQ.event_id - GROUP BY E.person_id, E.event_id - HAVING COUNT(index_id) = 1 -) G --- End Criteria Group -) AC on AC.person_id = pe.person_id AND AC.event_id = pe.event_id -) Results -; - -select 2 as inclusion_rule_id, person_id, event_id -INTO #Inclusion_2 -FROM -( - select pe.person_id, pe.event_id - FROM #qualified_events pe - -JOIN ( --- Begin Criteria Group -select 0 as index_id, person_id, event_id -FROM -( - select E.person_id, E.event_id - FROM #qualified_events E - INNER JOIN - ( - -- Begin Correlated Criteria -SELECT 0 as index_id, p.person_id, p.event_id -FROM #qualified_events P -INNER JOIN -( - -- Begin Drug Era Criteria -select C.person_id, C.drug_era_id as event_id, C.drug_era_start_date as start_date, C.drug_era_end_date as end_date, - C.drug_concept_id as TARGET_CONCEPT_ID, CAST(NULL as bigint) as visit_occurrence_id, - C.drug_era_start_date as sort_date -from -( - select de.* - FROM @cdm_database_schema.DRUG_ERA de -where de.drug_concept_id in (SELECT concept_id from #Codesets where codeset_id = 2) -) C - - --- End Drug Era Criteria - -) A on A.person_id = P.person_id AND A.START_DATE >= P.OP_START_DATE AND A.START_DATE <= P.OP_END_DATE AND A.START_DATE >= DATEADD(day,0,P.START_DATE) AND A.START_DATE <= DATEADD(day,7,P.START_DATE) -GROUP BY p.person_id, p.event_id -HAVING COUNT(DISTINCT A.TARGET_CONCEPT_ID) = 1 --- End Correlated Criteria - - ) CQ on E.person_id = CQ.person_id and E.event_id = CQ.event_id - GROUP BY E.person_id, E.event_id - HAVING COUNT(index_id) = 1 -) G --- End Criteria Group -) AC on AC.person_id = pe.person_id AND AC.event_id = pe.event_id -) Results -; - -SELECT inclusion_rule_id, person_id, event_id -INTO #inclusion_events -FROM (select inclusion_rule_id, person_id, event_id from #Inclusion_0 -UNION ALL -select inclusion_rule_id, person_id, event_id from #Inclusion_1 -UNION ALL -select inclusion_rule_id, person_id, event_id from #Inclusion_2) I; -TRUNCATE TABLE #Inclusion_0; -DROP TABLE #Inclusion_0; - -TRUNCATE TABLE #Inclusion_1; -DROP TABLE #Inclusion_1; - -TRUNCATE TABLE #Inclusion_2; -DROP TABLE #Inclusion_2; - - -with cteIncludedEvents(event_id, person_id, start_date, end_date, op_start_date, op_end_date, ordinal) as -( - SELECT event_id, person_id, start_date, end_date, op_start_date, op_end_date, row_number() over (partition by person_id order by start_date ASC) as ordinal - from - ( - select Q.event_id, Q.person_id, Q.start_date, Q.end_date, Q.op_start_date, Q.op_end_date, SUM(coalesce(POWER(cast(2 as bigint), I.inclusion_rule_id), 0)) as inclusion_rule_mask - from #qualified_events Q - LEFT JOIN #inclusion_events I on I.person_id = Q.person_id and I.event_id = Q.event_id - GROUP BY Q.event_id, Q.person_id, Q.start_date, Q.end_date, Q.op_start_date, Q.op_end_date - ) MG -- matching groups - - -- the matching group with all bits set ( POWER(2,# of inclusion rules) - 1 = inclusion_rule_mask - WHERE (MG.inclusion_rule_mask = POWER(cast(2 as bigint),3)-1) - -) -select event_id, person_id, start_date, end_date, op_start_date, op_end_date -into #included_events -FROM cteIncludedEvents Results -WHERE Results.ordinal = 1 -; - --- custom era strategy - -with ctePersons(person_id) as ( - select distinct person_id from #included_events -) - -select person_id, drug_exposure_start_date, drug_exposure_end_date -INTO #drugTarget -FROM ( - select de.PERSON_ID, DRUG_EXPOSURE_START_DATE, COALESCE(DRUG_EXPOSURE_END_DATE, DATEADD(day,DAYS_SUPPLY,DRUG_EXPOSURE_START_DATE), DATEADD(day,1,DRUG_EXPOSURE_START_DATE)) as DRUG_EXPOSURE_END_DATE - FROM @cdm_database_schema.DRUG_EXPOSURE de - JOIN ctePersons p on de.person_id = p.person_id - JOIN #Codesets cs on cs.codeset_id = 3 AND de.drug_concept_id = cs.concept_id - - UNION ALL - - select de.PERSON_ID, DRUG_EXPOSURE_START_DATE, COALESCE(DRUG_EXPOSURE_END_DATE, DATEADD(day,DAYS_SUPPLY,DRUG_EXPOSURE_START_DATE), DATEADD(day,1,DRUG_EXPOSURE_START_DATE)) as DRUG_EXPOSURE_END_DATE - FROM @cdm_database_schema.DRUG_EXPOSURE de - JOIN ctePersons p on de.person_id = p.person_id - JOIN #Codesets cs on cs.codeset_id = 3 AND de.drug_source_concept_id = cs.concept_id -) E -; - -select et.event_id, et.person_id, ERAS.era_end_date as end_date -INTO #strategy_ends -from #included_events et -JOIN -( - select ENDS.person_id, min(drug_exposure_start_date) as era_start_date, DATEADD(day,0, ENDS.era_end_date) as era_end_date - from - ( - select de.person_id, de.drug_exposure_start_date, MIN(e.END_DATE) as era_end_date - FROM #drugTarget DE - JOIN - ( - --cteEndDates - select PERSON_ID, DATEADD(day,-1 * 30,EVENT_DATE) as END_DATE -- unpad the end date by 30 - FROM - ( - select PERSON_ID, EVENT_DATE, EVENT_TYPE, - MAX(START_ORDINAL) OVER (PARTITION BY PERSON_ID ORDER BY event_date, event_type ROWS UNBOUNDED PRECEDING) AS start_ordinal, - ROW_NUMBER() OVER (PARTITION BY PERSON_ID ORDER BY EVENT_DATE, EVENT_TYPE) AS OVERALL_ORD -- this re-numbers the inner UNION so all rows are numbered ordered by the event date - from - ( - -- select the start dates, assigning a row number to each - Select PERSON_ID, DRUG_EXPOSURE_START_DATE AS EVENT_DATE, 0 as EVENT_TYPE, ROW_NUMBER() OVER (PARTITION BY PERSON_ID ORDER BY DRUG_EXPOSURE_START_DATE) as START_ORDINAL - from #drugTarget D - - UNION ALL - - -- add the end dates with NULL as the row number, padding the end dates by 30 to allow a grace period for overlapping ranges. - select PERSON_ID, DATEADD(day,30,DRUG_EXPOSURE_END_DATE), 1 as EVENT_TYPE, NULL - FROM #drugTarget D - ) RAWDATA - ) E - WHERE 2 * E.START_ORDINAL - E.OVERALL_ORD = 0 - ) E on DE.PERSON_ID = E.PERSON_ID and E.END_DATE >= DE.DRUG_EXPOSURE_START_DATE - GROUP BY de.person_id, de.drug_exposure_start_date - ) ENDS - GROUP BY ENDS.person_id, ENDS.era_end_date -) ERAS on ERAS.person_id = et.person_id -WHERE et.start_date between ERAS.era_start_date and ERAS.era_end_date; - -TRUNCATE TABLE #drugTarget; -DROP TABLE #drugTarget; - - --- generate cohort periods into #final_cohort -with cohort_ends (event_id, person_id, end_date) as -( - -- cohort exit dates - -- By default, cohort exit at the event's op end date -select event_id, person_id, op_end_date as end_date from #included_events -UNION ALL --- End Date Strategy -SELECT event_id, person_id, end_date from #strategy_ends - -), -first_ends (person_id, start_date, end_date) as -( - select F.person_id, F.start_date, F.end_date - FROM ( - select I.event_id, I.person_id, I.start_date, E.end_date, row_number() over (partition by I.person_id, I.event_id order by E.end_date) as ordinal - from #included_events I - join cohort_ends E on I.event_id = E.event_id and I.person_id = E.person_id and E.end_date >= I.start_date - ) F - WHERE F.ordinal = 1 -) -select person_id, start_date, end_date -INTO #cohort_rows -from first_ends; - -with cteEndDates (person_id, end_date) AS -- the magic -( - SELECT - person_id - , DATEADD(day,-1 * 0, event_date) as end_date - FROM - ( - SELECT - person_id - , event_date - , event_type - , MAX(start_ordinal) OVER (PARTITION BY person_id ORDER BY event_date, event_type ROWS UNBOUNDED PRECEDING) AS start_ordinal - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY event_date, event_type) AS overall_ord - FROM - ( - SELECT - person_id - , start_date AS event_date - , -1 AS event_type - , ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY start_date) AS start_ordinal - FROM #cohort_rows - - UNION ALL - - - SELECT - person_id - , DATEADD(day,0,end_date) as end_date - , 1 AS event_type - , NULL - FROM #cohort_rows - ) RAWDATA - ) e - WHERE (2 * e.start_ordinal) - e.overall_ord = 0 -), -cteEnds (person_id, start_date, end_date) AS -( - SELECT - c.person_id - , c.start_date - , MIN(e.end_date) AS end_date - FROM #cohort_rows c - JOIN cteEndDates e ON c.person_id = e.person_id AND e.end_date >= c.start_date - GROUP BY c.person_id, c.start_date -) -select person_id, min(start_date) as start_date, end_date -into #final_cohort -from cteEnds -group by person_id, end_date -; - -DELETE FROM @target_database_schema.@target_cohort_table where cohort_definition_id = @target_cohort_id; -INSERT INTO @target_database_schema.@target_cohort_table (cohort_definition_id, subject_id, cohort_start_date, cohort_end_date) -select @target_cohort_id as cohort_definition_id, person_id, start_date, end_date -FROM #final_cohort CO -; - - --- Find the event that is the 'best match' per person. --- the 'best match' is defined as the event that satisfies the most inclusion rules. --- ties are solved by choosing the event that matches the earliest inclusion rule, and then earliest. - -select q.person_id, q.event_id -into #best_events -from #qualified_events Q -join ( - SELECT R.person_id, R.event_id, ROW_NUMBER() OVER (PARTITION BY R.person_id ORDER BY R.rule_count DESC,R.min_rule_id ASC, R.start_date ASC) AS rank_value - FROM ( - SELECT Q.person_id, Q.event_id, COALESCE(COUNT(DISTINCT I.inclusion_rule_id), 0) AS rule_count, COALESCE(MIN(I.inclusion_rule_id), 0) AS min_rule_id, Q.start_date - FROM #qualified_events Q - LEFT JOIN #inclusion_events I ON q.person_id = i.person_id AND q.event_id = i.event_id - GROUP BY Q.person_id, Q.event_id, Q.start_date - ) R -) ranked on Q.person_id = ranked.person_id and Q.event_id = ranked.event_id -WHERE ranked.rank_value = 1 -; - --- modes of generation: (the same tables store the results for the different modes, identified by the mode_id column) --- 0: all events --- 1: best event - - --- BEGIN: Inclusion Impact Analysis - event --- calculte matching group counts -delete from @results_database_schema.cohort_inclusion_result where cohort_definition_id = @target_cohort_id and mode_id = 0; -insert into @results_database_schema.cohort_inclusion_result (cohort_definition_id, inclusion_rule_mask, person_count, mode_id) -select @target_cohort_id as cohort_definition_id, inclusion_rule_mask, count_big(*) as person_count, 0 as mode_id -from -( - select Q.person_id, Q.event_id, CAST(SUM(coalesce(POWER(cast(2 as bigint), I.inclusion_rule_id), 0)) AS bigint) as inclusion_rule_mask - from #qualified_events Q - LEFT JOIN #inclusion_events I on q.person_id = i.person_id and q.event_id = i.event_id - GROUP BY Q.person_id, Q.event_id -) MG -- matching groups -group by inclusion_rule_mask -; - --- calculate gain counts -delete from @results_database_schema.cohort_inclusion_stats where cohort_definition_id = @target_cohort_id and mode_id = 0; -insert into @results_database_schema.cohort_inclusion_stats (cohort_definition_id, rule_sequence, person_count, gain_count, person_total, mode_id) -select ir.cohort_definition_id, ir.rule_sequence, coalesce(T.person_count, 0) as person_count, coalesce(SR.person_count, 0) gain_count, EventTotal.total, 0 as mode_id -from @results_database_schema.cohort_inclusion ir -left join -( - select i.inclusion_rule_id, count_big(i.event_id) as person_count - from #qualified_events Q - JOIN #inclusion_events i on Q.person_id = I.person_id and Q.event_id = i.event_id - group by i.inclusion_rule_id -) T on ir.rule_sequence = T.inclusion_rule_id -CROSS JOIN (select count(*) as total_rules from @results_database_schema.cohort_inclusion where cohort_definition_id = @target_cohort_id) RuleTotal -CROSS JOIN (select count_big(event_id) as total from #qualified_events) EventTotal -LEFT JOIN @results_database_schema.cohort_inclusion_result SR on SR.mode_id = 0 AND SR.cohort_definition_id = @target_cohort_id AND (POWER(cast(2 as bigint),RuleTotal.total_rules) - POWER(cast(2 as bigint),ir.rule_sequence) - 1) = SR.inclusion_rule_mask -- POWER(2,rule count) - POWER(2,rule sequence) - 1 is the mask for 'all except this rule' -WHERE ir.cohort_definition_id = @target_cohort_id -; - --- calculate totals -delete from @results_database_schema.cohort_summary_stats where cohort_definition_id = @target_cohort_id and mode_id = 0; -insert into @results_database_schema.cohort_summary_stats (cohort_definition_id, base_count, final_count, mode_id) -select @target_cohort_id as cohort_definition_id, PC.total as person_count, coalesce(FC.total, 0) as final_count, 0 as mode_id -FROM -(select count_big(event_id) as total from #qualified_events) PC, -(select sum(sr.person_count) as total - from @results_database_schema.cohort_inclusion_result sr - CROSS JOIN (select count(*) as total_rules from @results_database_schema.cohort_inclusion where cohort_definition_id = @target_cohort_id) RuleTotal - where sr.mode_id = 0 and sr.cohort_definition_id = @target_cohort_id and sr.inclusion_rule_mask = POWER(cast(2 as bigint),RuleTotal.total_rules)-1 -) FC -; - --- END: Inclusion Impact Analysis - event - --- BEGIN: Inclusion Impact Analysis - person --- calculte matching group counts -delete from @results_database_schema.cohort_inclusion_result where cohort_definition_id = @target_cohort_id and mode_id = 1; -insert into @results_database_schema.cohort_inclusion_result (cohort_definition_id, inclusion_rule_mask, person_count, mode_id) -select @target_cohort_id as cohort_definition_id, inclusion_rule_mask, count_big(*) as person_count, 1 as mode_id -from -( - select Q.person_id, Q.event_id, CAST(SUM(coalesce(POWER(cast(2 as bigint), I.inclusion_rule_id), 0)) AS bigint) as inclusion_rule_mask - from #best_events Q - LEFT JOIN #inclusion_events I on q.person_id = i.person_id and q.event_id = i.event_id - GROUP BY Q.person_id, Q.event_id -) MG -- matching groups -group by inclusion_rule_mask -; - --- calculate gain counts -delete from @results_database_schema.cohort_inclusion_stats where cohort_definition_id = @target_cohort_id and mode_id = 1; -insert into @results_database_schema.cohort_inclusion_stats (cohort_definition_id, rule_sequence, person_count, gain_count, person_total, mode_id) -select ir.cohort_definition_id, ir.rule_sequence, coalesce(T.person_count, 0) as person_count, coalesce(SR.person_count, 0) gain_count, EventTotal.total, 1 as mode_id -from @results_database_schema.cohort_inclusion ir -left join -( - select i.inclusion_rule_id, count_big(i.event_id) as person_count - from #best_events Q - JOIN #inclusion_events i on Q.person_id = I.person_id and Q.event_id = i.event_id - group by i.inclusion_rule_id -) T on ir.rule_sequence = T.inclusion_rule_id -CROSS JOIN (select count(*) as total_rules from @results_database_schema.cohort_inclusion where cohort_definition_id = @target_cohort_id) RuleTotal -CROSS JOIN (select count_big(event_id) as total from #best_events) EventTotal -LEFT JOIN @results_database_schema.cohort_inclusion_result SR on SR.mode_id = 1 AND SR.cohort_definition_id = @target_cohort_id AND (POWER(cast(2 as bigint),RuleTotal.total_rules) - POWER(cast(2 as bigint),ir.rule_sequence) - 1) = SR.inclusion_rule_mask -- POWER(2,rule count) - POWER(2,rule sequence) - 1 is the mask for 'all except this rule' -WHERE ir.cohort_definition_id = @target_cohort_id -; - --- calculate totals -delete from @results_database_schema.cohort_summary_stats where cohort_definition_id = @target_cohort_id and mode_id = 1; -insert into @results_database_schema.cohort_summary_stats (cohort_definition_id, base_count, final_count, mode_id) -select @target_cohort_id as cohort_definition_id, PC.total as person_count, coalesce(FC.total, 0) as final_count, 1 as mode_id -FROM -(select count_big(event_id) as total from #best_events) PC, -(select sum(sr.person_count) as total - from @results_database_schema.cohort_inclusion_result sr - CROSS JOIN (select count(*) as total_rules from @results_database_schema.cohort_inclusion where cohort_definition_id = @target_cohort_id) RuleTotal - where sr.mode_id = 1 and sr.cohort_definition_id = @target_cohort_id and sr.inclusion_rule_mask = POWER(cast(2 as bigint),RuleTotal.total_rules)-1 -) FC -; - --- END: Inclusion Impact Analysis - person - --- BEGIN: Censored Stats - --- END: Censored Stats - -TRUNCATE TABLE #best_events; -DROP TABLE #best_events; - - - -TRUNCATE TABLE #strategy_ends; -DROP TABLE #strategy_ends; - - -TRUNCATE TABLE #cohort_rows; -DROP TABLE #cohort_rows; - -TRUNCATE TABLE #final_cohort; -DROP TABLE #final_cohort; - -TRUNCATE TABLE #inclusion_events; -DROP TABLE #inclusion_events; - -TRUNCATE TABLE #qualified_events; -DROP TABLE #qualified_events; - -TRUNCATE TABLE #included_events; -DROP TABLE #included_events; - -TRUNCATE TABLE #Codesets; -DROP TABLE #Codesets; diff --git a/examplePackage/man/runCohortDiagnostics.Rd b/examplePackage/man/runCohortDiagnostics.Rd deleted file mode 100644 index cd5e493ae..000000000 --- a/examplePackage/man/runCohortDiagnostics.Rd +++ /dev/null @@ -1,87 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/CohortDiagnostics.R -\name{runCohortDiagnostics} -\alias{runCohortDiagnostics} -\title{Execute the cohort diagnostics} -\usage{ -runCohortDiagnostics( - connectionDetails, - cdmDatabaseSchema, - cohortDatabaseSchema = cdmDatabaseSchema, - cohortTable = "cohort", - oracleTempSchema = cohortDatabaseSchema, - outputFolder, - databaseId = "Unknown", - databaseName = "Unknown", - databaseDescription = "Unknown", - createCohorts = TRUE, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - runBreakdownIndexEvents = TRUE, - runIncidenceRates = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = TRUE, - minCellCount = 5 -) -} -\arguments{ -\item{connectionDetails}{An object of type \code{connectionDetails} as created using the -\code{\link[DatabaseConnector]{createConnectionDetails}} function in the -DatabaseConnector package.} - -\item{cdmDatabaseSchema}{Schema name where your patient-level data in OMOP CDM format resides. -Note that for SQL Server, this should include both the database and -schema name, for example 'cdm_data.dbo'.} - -\item{cohortDatabaseSchema}{Schema name where intermediate data can be stored. You will need to have -write priviliges in this schema. Note that for SQL Server, this should -include both the database and schema name, for example 'cdm_data.dbo'.} - -\item{cohortTable}{The name of the table that will be created in the work database schema. -This table will hold the exposure and outcome cohorts used in this -study.} - -\item{oracleTempSchema}{Should be used in Oracle to specify a schema where the user has write -priviliges for storing temporary tables.} - -\item{outputFolder}{Name of local folder to place results; make sure to use forward slashes -(/). Do not use a folder on a network drive since this greatly impacts -performance.} - -\item{databaseId}{A short string for identifying the database (e.g. -'Synpuf').} - -\item{databaseName}{The full name of the database (e.g. 'Medicare Claims -Synthetic Public Use Files (SynPUFs)').} - -\item{databaseDescription}{A short description (several sentences) of the database.} - -\item{createCohorts}{Create the cohortTable table with the exposure and outcome cohorts?} - -\item{runInclusionStatistics}{Generate and export statistic on the cohort incusion rules?} - -\item{runIncludedSourceConcepts}{Generate and export the source concepts included in the cohorts?} - -\item{runOrphanConcepts}{Generate and export potential orphan concepts?} - -\item{runTimeDistributions}{Generate and export cohort time distributions?} - -\item{runBreakdownIndexEvents}{Generate and export the breakdown of index events?} - -\item{runIncidenceRates}{Generate and export the cohort incidence rates?} - -\item{runCohortOverlap}{Generate and export the cohort overlap?} - -\item{runCohortCharacterization}{Generate and export the cohort characterization?} - -\item{minCellCount}{The minimum number of subjects contributing to a count before it can be included -in packaged results.} -} -\description{ -Execute the cohort diagnostics -} -\details{ -This function executes the cohort diagnostics. -} diff --git a/examplePackage/readme.md b/examplePackage/readme.md deleted file mode 100644 index 7ad51f1e3..000000000 --- a/examplePackage/readme.md +++ /dev/null @@ -1,43 +0,0 @@ -Example Package -=============== - -This study package demonstrates how to currently use CohortDiagnostics in a package. The package only contains code to run StudyDiagnostics. - -To modify the package to include the cohorts of interest, take these steps: - -1. Copy/download the *examplePackage* folder. For example, download the Zip file [here](https://github.com/OHDSI/CohortDiagnostics/archive/master.zip), open it, and locate the *examplePackage* folder and extract it. - -2. Change the package name as needed. Most importantly: - - Change the `Package:` field in the *DESCRIPTION* file, - - The `packageName` argument in the *R/CohortDiagnostics* file, and - - The `library()` call at the top of *extras/CodeToRun.R* - - The name of the *.Rproj* file. - -3. Open the R project in R studio (e.g. by double-clicking on the *.Rproj* file). - -4. Modify *inst/settings/CohortsToCreate.csv* to include only those cohorts you are interested in. Fill in each of the four columns: - - - **atlasId**: The cohort ID in ATLAS. - - **atlasName**: The full name of the cohort. This will be shown in the Shiny app. - - **cohortId**: The cohort ID to use in the package. USually the same as the cohort ID in ATLAS. - - **name**: A short name for the cohort, to use to create file names. do not use special characters. - -5. Run this code (note, this can also be found in *extras/PackageMaintenance.R*): - - ```r - # If ROhdsiWebApi is not yet installed: - install.packages("devtools") - devtools::install_github("ROhdsiWebApi") - - ROhdsiWebApi::insertCohortDefinitionSetInPackage(fileName = "inst/settings/CohortsToCreate.csv", - baseUrl = , - insertTableSql = TRUE, - insertCohortCreationR = TRUE, - generateStats = TRUE, - packageName = ) - ``` - - Where `` is the base URL for the WebApi instance, for example: "http://server.org:80/WebAPI", and `` is the name of your new package. - -You can now build your package. See *extras/CodeToRun.R* on how to run the package. - diff --git a/examplePhenotypeLibraryPackage/.Rbuildignore b/examplePhenotypeLibraryPackage/.Rbuildignore deleted file mode 100644 index 01de75db6..000000000 --- a/examplePhenotypeLibraryPackage/.Rbuildignore +++ /dev/null @@ -1,9 +0,0 @@ -^.*\.Rproj$ -^\.Rproj\.user$ -extras -^\.Rprofile$ -documents -readme.md -studyReadme.md -HydraConfig.json - diff --git a/examplePhenotypeLibraryPackage/.Rprofile b/examplePhenotypeLibraryPackage/.Rprofile deleted file mode 100644 index 8b1378917..000000000 --- a/examplePhenotypeLibraryPackage/.Rprofile +++ /dev/null @@ -1 +0,0 @@ - diff --git a/examplePhenotypeLibraryPackage/.gitignore b/examplePhenotypeLibraryPackage/.gitignore deleted file mode 100644 index 116177baf..000000000 --- a/examplePhenotypeLibraryPackage/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.Rproj.user -.Rhistory -.RData -.Ruserdata -*.tmp diff --git a/examplePhenotypeLibraryPackage/DESCRIPTION b/examplePhenotypeLibraryPackage/DESCRIPTION deleted file mode 100644 index c30ea2746..000000000 --- a/examplePhenotypeLibraryPackage/DESCRIPTION +++ /dev/null @@ -1,20 +0,0 @@ -Package: examplePhenotypeLibraryPackage -Type: Package -Title: A Package Skeleton for Cohort Diagnostics -Version: 0.0.1 -Author: Martijn Schuemie [aut, cre] -Maintainer: Martijn J. Schuemie -Description: A skeleton package, to be used as a starting point when you just want to run cohort diagnostics. -Depends: - DatabaseConnector (>= 2.2.0) -Imports: - CohortDiagnostics -Suggests: - knitr, - rmarkdown, - ROhdsiWebApi, - OhdsiRTools -License: Apache License 2.0 -VignetteBuilder: knitr -LazyData: TRUE -RoxygenNote: 7.1.1 diff --git a/examplePhenotypeLibraryPackage/NAMESPACE b/examplePhenotypeLibraryPackage/NAMESPACE deleted file mode 100644 index 3e887cf0e..000000000 --- a/examplePhenotypeLibraryPackage/NAMESPACE +++ /dev/null @@ -1,3 +0,0 @@ -# Generated by roxygen2: do not edit by hand - -export(runPhenotypeLibraryDiagnostics) diff --git a/examplePhenotypeLibraryPackage/R/CohortDiagnostics.R b/examplePhenotypeLibraryPackage/R/CohortDiagnostics.R deleted file mode 100644 index 2d2b03b6b..000000000 --- a/examplePhenotypeLibraryPackage/R/CohortDiagnostics.R +++ /dev/null @@ -1,135 +0,0 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics -# -# This file is part of examplePhenotypeLibraryPackage -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -#' Execute the cohort diagnostics -#' -#' @details -#' This function executes the cohort diagnostics. -#' -#' @param connectionDetails An object of type \code{connectionDetails} as created using the -#' \code{\link[DatabaseConnector]{createConnectionDetails}} function in the -#' DatabaseConnector package. -#' @param cdmDatabaseSchema Schema name where your patient-level data in OMOP CDM format resides. -#' Note that for SQL Server, this should include both the database and -#' schema name, for example 'cdm_data.dbo'. -#' @param cohortDatabaseSchema Schema name where intermediate data can be stored. You will need to have -#' write priviliges in this schema. Note that for SQL Server, this should -#' include both the database and schema name, for example 'cdm_data.dbo'. -#' @param cohortTable The name of the table that will be created in the work database schema. -#' This table will hold the exposure and outcome cohorts used in this -#' study. -#' @param oracleTempSchema Should be used in Oracle to specify a schema where the user has write -#' priviliges for storing temporary tables. -#' @param outputFolder Name of local folder to place results; make sure to use forward slashes -#' (/). Do not use a folder on a network drive since this greatly impacts -#' performance. -#' @param databaseId A short string for identifying the database (e.g. -#' 'Synpuf'). -#' @param databaseName The full name of the database (e.g. 'Medicare Claims -#' Synthetic Public Use Files (SynPUFs)'). -#' @param databaseDescription A short description (several sentences) of the database. -#' @param createCohorts Create the cohortTable table with the exposure and outcome cohorts? -#' @param runInclusionStatistics Generate and export statistic on the cohort incusion rules? -#' @param runIncludedSourceConcepts Generate and export the source concepts included in the cohorts? -#' @param runOrphanConcepts Generate and export potential orphan concepts? -#' @param runTimeDistributions Generate and export cohort time distributions? -#' @param runBreakdownIndexEvents Generate and export the breakdown of index events? -#' @param runIncidenceRates Generate and export the cohort incidence rates? -#' @param runCohortOverlap Generate and export the cohort overlap? -#' @param runCohortCharacterization Generate and export the cohort characterization? -#' @param runTemporalCohortCharacterization Generate and export the temporal cohort characterization? -#' @param runVisitContext Generate and export the visit context? -#' @param minCellCount The minimum number of subjects contributing to a count before it can be included -#' in packaged results. -#' -#' @export -runPhenotypeLibraryDiagnostics <- function(connectionDetails, - cdmDatabaseSchema, - cohortDatabaseSchema = cdmDatabaseSchema, - cohortTable = "cohort", - oracleTempSchema = cohortDatabaseSchema, - outputFolder, - databaseId = "Unknown", - databaseName = "Unknown", - databaseDescription = "Unknown", - createCohorts = TRUE, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - runBreakdownIndexEvents = TRUE, - runIncidenceRates = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = TRUE, - runTemporalCohortCharacterization = TRUE, - runVisitContext = TRUE, - minCellCount = 5) { - if (!file.exists(outputFolder)) - dir.create(outputFolder, recursive = TRUE) - - incrementalFolder <- file.path(outputFolder, "incremental") - if (!file.exists(incrementalFolder)) - dir.create(incrementalFolder, recursive = TRUE) - - ParallelLogger::addDefaultFileLogger(file.path(outputFolder, "log.txt")) - ParallelLogger::addDefaultErrorReportLogger(file.path(outputFolder, "errorReportR.txt")) - on.exit(ParallelLogger::unregisterLogger("DEFAULT_FILE_LOGGER", silent = TRUE)) - on.exit(ParallelLogger::unregisterLogger("DEFAULT_ERRORREPORT_LOGGER", silent = TRUE), add = TRUE) - - if (createCohorts) { - ParallelLogger::logInfo("Creating cohorts") - CohortDiagnostics::instantiateCohortSet(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - oracleTempSchema = oracleTempSchema, - packageName = "examplePhenotypeLibraryPackage", - cohortToCreateFile = "settings/CohortsToCreate.csv", - createCohortTable = TRUE, - generateInclusionStats = TRUE, - inclusionStatisticsFolder = outputFolder, - incremental = TRUE, - incrementalFolder = incrementalFolder) - - } - - ParallelLogger::logInfo("Running study diagnostics") - CohortDiagnostics::runCohortDiagnostics(packageName = "examplePhenotypeLibraryPackage", - phenotypeDescriptionFile = "settings/PhenotypeDescription.csv", - connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - inclusionStatisticsFolder = outputFolder, - exportFolder = file.path(outputFolder, "diagnosticsExport"), - databaseId = databaseId, - databaseName = databaseName, - databaseDescription = databaseDescription, - runInclusionStatistics = runInclusionStatistics, - runIncludedSourceConcepts = runIncludedSourceConcepts, - runOrphanConcepts = runOrphanConcepts, - runTimeDistributions = runTimeDistributions, - runBreakdownIndexEvents = runBreakdownIndexEvents, - runIncidenceRate = runIncidenceRates, - runCohortOverlap = runCohortOverlap, - runCohortCharacterization = runCohortCharacterization, - runTemporalCohortCharacterization = runTemporalCohortCharacterization, - runVisitContext = runVisitContext, - minCellCount = minCellCount, - incremental = TRUE, - incrementalFolder = incrementalFolder) -} diff --git a/examplePhenotypeLibraryPackage/examplePhenotypeLibraryPackage.Rproj b/examplePhenotypeLibraryPackage/examplePhenotypeLibraryPackage.Rproj deleted file mode 100644 index eaa6b8186..000000000 --- a/examplePhenotypeLibraryPackage/examplePhenotypeLibraryPackage.Rproj +++ /dev/null @@ -1,18 +0,0 @@ -Version: 1.0 - -RestoreWorkspace: Default -SaveWorkspace: Default -AlwaysSaveHistory: Default - -EnableCodeIndexing: Yes -UseSpacesForTab: Yes -NumSpacesForTab: 2 -Encoding: UTF-8 - -RnwWeave: Sweave -LaTeX: pdfLaTeX - -BuildType: Package -PackageUseDevtools: Yes -PackageInstallArgs: --no-multiarch --with-keep.source -PackageRoxygenize: rd,collate,namespace diff --git a/examplePhenotypeLibraryPackage/extras/CodeToRun.R b/examplePhenotypeLibraryPackage/extras/CodeToRun.R deleted file mode 100644 index 3424af515..000000000 --- a/examplePhenotypeLibraryPackage/extras/CodeToRun.R +++ /dev/null @@ -1,70 +0,0 @@ -# Make sure to install all dependencies (not needed if already done): -# install.packages("SqlRender") -# install.packages("DatabaseConnector") -# install.packages("ggplot2") -# install.packages("ParallelLogger") -# install.packages("readr") -# install.packages("tibble") -# install.packages("dplyr") -# install.packages("RJSONIO") -# install.packages("devtools") -# devtools::install_github("FeatureExtraction") -# devtools::install_github("ROhdsiWebApi") -# devtools::install_github("CohortDiagnostics") - - -# Load the package -library(examplePhenotypeLibraryPackage) - -# Optional: specify where the temporary files will be created: -options(andromedaTempFolder = "s:/andromedaTemp") - -# Maximum number of cores to be used: -maxCores <- parallel::detectCores() - - -# Details for connecting to the server: -connectionDetails <- DatabaseConnector::createConnectionDetails(dbms = "pdw", - server = Sys.getenv("PDW_SERVER"), - user = NULL, - password = NULL, - port = Sys.getenv("PDW_PORT")) - -# For Oracle: define a schema that can be used to emulate temp tables: -oracleTempSchema <- NULL - -# Provide data-base specific information here -outputFolder <- "s:/examplePhenotypeLibraryPackageOutput/ccae" -cdmDatabaseSchema <- "CDM_IBM_CCAE_V1247.dbo" -cohortDatabaseSchema <- "scratch.dbo" -cohortTable <- "mschuemi_skeleton_ccae" -databaseId <- "CCAE" -databaseName <- "IBM MarketScan Commercial Claims and Encounters Database" -databaseDescription <- "IBM MarketScan® Commercial Claims and Encounters Database (CCAE) represent data from individuals enrolled in United States employer-sponsored insurance health plans. The data includes adjudicated health insurance claims (e.g. inpatient, outpatient, and outpatient pharmacy) as well as enrollment data from large employers and health plans who provide private healthcare coverage to employees, their spouses, and dependents. Additionally, it captures laboratory tests for a subset of the covered lives. This administrative claims database includes a variety of fee-for-service, preferred provider organizations, and capitated health plans." - -# Use this to run the cohortDiagnostics. The results will be stored in the diagnosticsExport subfolder of the outputFolder. This can be shared between sites. -examplePhenotypeLibraryPackage::runCohortDiagnostics(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - oracleTempSchema = oracleTempSchema, - outputFolder = outputFolder, - databaseId = databaseId, - databaseName = databaseName, - databaseDescription = databaseDescription, - createCohorts = TRUE, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - runBreakdownIndexEvents = TRUE, - runIncidenceRates = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = TRUE, - runTemporalCohortCharacterization = TRUE, - minCellCount = 5) - -# To view the results: -CohortDiagnostics::preMergeDiagnosticsFiles(file.path(outputFolder, "diagnosticsExport")) - -CohortDiagnostics::launchDiagnosticsExplorer(file.path(outputFolder, "diagnosticsExport")) diff --git a/examplePhenotypeLibraryPackage/extras/CodeToRunRedShift.R b/examplePhenotypeLibraryPackage/extras/CodeToRunRedShift.R deleted file mode 100644 index d35cc12a3..000000000 --- a/examplePhenotypeLibraryPackage/extras/CodeToRunRedShift.R +++ /dev/null @@ -1,103 +0,0 @@ -# Make sure to install all dependencies (not needed if already done): -# install.packages("SqlRender") -# install.packages("DatabaseConnector") -# install.packages("ggplot2") -# install.packages("ParallelLogger") -# install.packages("readr") -# install.packages("tibble") -# install.packages("dplyr") -# install.packages("RJSONIO") -# install.packages("devtools") -# devtools::install_github("FeatureExtraction") -# devtools::install_github("ROhdsiWebApi") -# devtools::install_github("CohortDiagnostics") - - -# Load the package -library(examplePhenotypeLibraryPackage) - -path <- "s:/examplePhenotypeLibraryPackageOutput" - -# Optional: specify where the temporary files will be created: -options(andromedaTempFolder = file.path(path, "andromedaTemp")) - -# Maximum number of cores to be used: -maxCores <- parallel::detectCores() -oracleTempSchema <- NULL - -# Details for connecting to the server: -connectionDetails <- DatabaseConnector::createConnectionDetails(dbms = "redshift", - connectionString = keyring::key_get("redShiftConnectionStringJmdc"), - user = keyring::key_get("redShiftUserName"), - password = keyring::key_get("redShiftPassword")) - -connectionDetails <- DatabaseConnector::createConnectionDetails(dbms = "redshift", - connectionString = keyring::key_get("redShiftConnectionStringCcae"), - user = keyring::key_get("redShiftUserName"), - password = keyring::key_get("redShiftPassword")) -outputFolder <- "s:/examplePhenotypeLibraryPackage/ccae" -cdmDatabaseSchema <- "cdm" -cohortDatabaseSchema <- "scratch_mschuemi" -cohortTable <- "mschuemi_skeleton_ccae" -databaseId <- "CCAE" -databaseName <- "IBM MarketScan Commercial Claims and Encounters Database" -databaseDescription <- "IBM MarketScan® Commercial Claims and Encounters Database (CCAE) represent data from individuals enrolled in United States employer-sponsored insurance health plans. The data includes adjudicated health insurance claims (e.g. inpatient, outpatient, and outpatient pharmacy) as well as enrollment data from large employers and health plans who provide private healthcare coverage to employees, their spouses, and dependents. Additionally, it captures laboratory tests for a subset of the covered lives. This administrative claims database includes a variety of fee-for-service, preferred provider organizations, and capitated health plans." - - - - -# For Oracle: define a schema that can be used to emulate temp tables: - - -connectionDetails <- DatabaseConnector::createConnectionDetails(dbms = "redshift", - connectionString = keyring::key_get("redShiftConnectionStringJmdc"), - user = keyring::key_get("redShiftUserName"), - password = keyring::key_get("redShiftPassword")) - - -outputFolder <- file.path(path, "output") -cdmDatabaseSchema <- "cdm" -cohortDatabaseSchema <- "scratch_mschuemi" -cohortTable <- "cd_test" -databaseId <- "JMDC" -databaseName <- "Japan Medical Data Center" -databaseDescription <- "Japan Medical Data Center (JDMC) database consists of data from 60 Society-Managed Health Insurance plans covering workers aged 18 to 65 and their dependents (children younger than 18 years old and elderly people older than 65 years old). JMDC data includes membership status of the insured people and claims data provided by insurers under contract (e.g. patient-level demographic information, inpatient and outpatient data inclusive of diagnosis and procedures, and prescriptions as dispensed claims information). Claims data are derived from monthly claims issued by clinics, hospitals and community pharmacies; for claims only the month and year are provided however prescriptions, procedures, admission, discharge, and start of medical care as associated with a full date.\nAll diagnoses are coded using ICD-10. All prescriptions refer to national Japanese drug codes, which have been linked to ATC. Procedures are encoded using local procedure codes, which the vendor has mapped to ICD-9 procedure codes. The annual health checkups report a standard battery of measurements (e.g. BMI), which are not coded but clearly described." - - -# Use this to run the cohorttDiagnostics. The results will be stored in the diagnosticsExport subfolder of the outputFolder. This can be shared between sites. -examplePhenotypeLibraryPackage::runCohortDiagnostics(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - oracleTempSchema = oracleTempSchema, - outputFolder = outputFolder, - databaseId = databaseId, - databaseName = databaseName, - databaseDescription = databaseDescription, - createCohorts = TRUE, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - runBreakdownIndexEvents = TRUE, - runIncidenceRates = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = TRUE, - runTemporalCohortCharacterization = TRUE, - minCellCount = 5) - -# To view the results: -# Optional: if there are results zip files from multiple sites in a folder, this merges them, which will speed up starting the viewer: -CohortDiagnostics::preMergeDiagnosticsFiles(file.path(outputFolder, "diagnosticsExport")) - -# Use this to view the results. Multiple zip files can be in the same folder. If the files were pre-merged, this is automatically detected: -CohortDiagnostics::launchDiagnosticsExplorer(file.path(outputFolder, "diagnosticsExport")) - - -# To explore a specific cohort in the local database, viewing patient profiles: -CohortDiagnostics::launchCohortExplorer(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortId = 123) -# Where 123 is the ID of the cohort you wish to inspect. diff --git a/examplePhenotypeLibraryPackage/extras/PackageMaintenance.R b/examplePhenotypeLibraryPackage/extras/PackageMaintenance.R deleted file mode 100644 index a898b924f..000000000 --- a/examplePhenotypeLibraryPackage/extras/PackageMaintenance.R +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2020 Observational Health Data Sciences and Informatics -# -# This file is part of examplePhenotypeLibraryPackage -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Format and check code --------------------------------------------------- -OhdsiRTools::formatRFolder() -OhdsiRTools::checkUsagePackage("examplePhenotypeLibraryPackage") -OhdsiRTools::updateCopyrightYearFolder() - -# Create manual ----------------------------------------------------------- -shell("rm extras/examplePhenotypeLibraryPackage.pdf") -shell("R CMD Rd2pdf ./ --output=extras/examplePhenotypeLibraryPackage.pdf") - - -# Insert cohort definitions from ATLAS into package ----------------------- -table <- readr::read_csv("inst/settings/CohortsToCreate.csv") -table$name <- table$cohortId -table$atlasId <- table$webApiCohortId -readr::write_csv(table, "inst/settings/CohortsToCreate2.csv") -ROhdsiWebApi::insertCohortDefinitionSetInPackage(fileName = "inst/settings/CohortsToCreate2.csv", - baseUrl = Sys.getenv("baseUrl"), - insertTableSql = FALSE, - insertCohortCreationR = FALSE, - generateStats = TRUE, - packageName = "examplePhenotypeLibraryPackage") -unlink("inst/settings/CohortsToCreate2.csv") diff --git a/examplePhenotypeLibraryPackage/inst/cohorts/27918003.json b/examplePhenotypeLibraryPackage/inst/cohorts/27918003.json deleted file mode 100644 index 9b7e84362..000000000 --- a/examplePhenotypeLibraryPackage/inst/cohorts/27918003.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "cdmVersionRange" : ">=5.0.0", - "PrimaryCriteria" : { - "CriteriaList" : [ - { - "ConditionOccurrence" : { - "CodesetId" : 3, - "First" : true, - "ConditionTypeExclude" : false - } - } - ], - "ObservationWindow" : { - "PriorDays" : 365, - "PostDays" : 0 - }, - "PrimaryCriteriaLimit" : { - "Type" : "First" - } - }, - "ConceptSets" : [ - { - "id" : 3, - "name" : "Eosinophilic esophagitis", - "expression" : { - "items" : [ - { - "concept" : { - "CONCEPT_ID" : 27918, - "CONCEPT_NAME" : "Eosinophilic esophagitis", - "STANDARD_CONCEPT" : "S", - "STANDARD_CONCEPT_CAPTION" : "Standard", - "INVALID_REASON" : "V", - "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "235599003", - "DOMAIN_ID" : "Condition", - "VOCABULARY_ID" : "SNOMED", - "CONCEPT_CLASS_ID" : "Clinical Finding" - }, - "isExcluded" : false, - "includeDescendants" : true, - "includeMapped" : false - } - ] - } - } - ], - "QualifiedLimit" : { - "Type" : "First" - }, - "ExpressionLimit" : { - "Type" : "First" - }, - "InclusionRules" : [], - "CensoringCriteria" : [], - "CollapseSettings" : { - "CollapseType" : "ERA", - "EraPad" : 0 - }, - "CensorWindow" : {} -} \ No newline at end of file diff --git a/examplePhenotypeLibraryPackage/inst/cohorts/InclusionRules.csv b/examplePhenotypeLibraryPackage/inst/cohorts/InclusionRules.csv deleted file mode 100644 index 019e2cbcc..000000000 --- a/examplePhenotypeLibraryPackage/inst/cohorts/InclusionRules.csv +++ /dev/null @@ -1,2 +0,0 @@ -cohortName,ruleSequence,ruleName,cohortId -27918004,0,Second occurrence of Eosinophilic esophagitis,27918004 diff --git a/examplePhenotypeLibraryPackage/inst/settings/CohortsToCreate.csv b/examplePhenotypeLibraryPackage/inst/settings/CohortsToCreate.csv deleted file mode 100644 index f951b8f3d..000000000 --- a/examplePhenotypeLibraryPackage/inst/settings/CohortsToCreate.csv +++ /dev/null @@ -1,7 +0,0 @@ -phenotypeId,cohortId,webApiCohortId,cohortName,logicDescription -27918000,27918001,17477,[PL 27918001] Eosinophilic esophagitis referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,"Persons with condition occurrence of referent concept (27918) or descendants, for the first time in the person's history, with at least 365 days of prior continuous observation. Persons exit cohort at the end of the observation period." -27918000,27918002,17476,[PL 27918002] Eosinophilic esophagitis referent concept prevalent cohort: First occurrence of referent concept + descendants,"Persons with condition occurrence of referent concept (27918) or descendants, for the first time in the person's history. Persons exit cohort at the end of the observation period." -27918000,27918003,11650,[PL 27918003] Eosinophilic esophagitis at first diagnosis,Eosinophilic esophagitis at first diagnosis with 365 days continuous observation. Cohort exit is the end of continuous observable time for the person. -27918000,27918004,16908,[PL 27918004] Eosinophilic esophagitis with another occurrence in two years after - first time in persons history,Eosinophilic esophagitis at first diagnosis with 365 days continuous observation and a second diagnosis within 2 years. Cohort exit is the end of continuous observable time for the person. -80182000,80182001,17465,[PL 80182001] Dermatomyositis referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,"Persons with condition occurrence of referent concept (80182) or descendants, for the first time in the person's history, with at least 365 days of prior continuous observation. Persons exit cohort at the end of the observation period." -80182000,80182002,17464,[PL 80182002] Dermatomyositis referent concept prevalent cohort: First occurrence of referent concept + descendants,"Persons with condition occurrence of referent concept (80182) or descendants, for the first time in the person's history. Persons exit cohort at the end of the observation period." diff --git a/examplePhenotypeLibraryPackage/inst/settings/PhenotypeDescription.csv b/examplePhenotypeLibraryPackage/inst/settings/PhenotypeDescription.csv deleted file mode 100644 index ffb2aba82..000000000 --- a/examplePhenotypeLibraryPackage/inst/settings/PhenotypeDescription.csv +++ /dev/null @@ -1,3 +0,0 @@ -phenotypeId,phenotypeName,referentConceptId,clinicalDescription,literatureReview,phenotypeNotes -80182000,Dermatomyositis,80182,"Overview: Autoimmune condition that causes skin changes and muscle weakness (idiopathic inflammatory myopathy). Unknown cause. Presentation: Red skin rash around the eyelids, red bumps around the joints (Gottron papules), arm and leg muscle weakness, joint pain Assessment: Clinical exam, blood analysis - creatine kinase (CK) and lactic dehydrogenase (LDH), autoantibodies; skin or muscle biopsy, Electromyography (EMG), MRI to scan muscles.Plan: Manage symptoms - corticosteroids, immunosuppressants, physical therapy, and exercise.Prognosis: Symptom improvement. Chronic - can last for years or be lifelong. Muscle weakness gets worse over time and leads to stiff joints and muscle wasting.",, -27918000,Eosinophilic esophagitis,27918,"Overview: This is a chronic, immune/antigen-mediated, esophageal disease characterized clinically by symptoms related to esophageal dysfunction and histologically by eosinophil-predominant inflammationPresentation: Adults and teenagers frequently present with dysphagia and food impactions. Children may have symptoms of feeding difficulties, gastroesophageal reflux symptoms, and abdominal pain. Dysphagia, food impaction, chest pain that is often centrally located and may not respond to antacids, symptoms of gastroesophageal reflux disease-like symptoms/refractory heartburn along with upper abdominal pain.Assessment: This is a diagnosis of exclusion, by excluding other causes of the symptoms along with upper endoscopy with esophageal biopsies showing histological findings of eosinophilia (eosinophil predominant inflammation on biopsy)Plan: Management involves dietary, pharmacologic and endoscopic interventions – using combination of elimination diets, acid suppression, topical steroids in esophageus, and esophageal dilatation in stricture.Prognosis: untreated patients may have progressive lifelong symptoms, that maybe episodic. Long-term natural history of disease is not established.",, diff --git a/examplePhenotypeLibraryPackage/man/runPhenotypeLibraryDiagnostics.Rd b/examplePhenotypeLibraryPackage/man/runPhenotypeLibraryDiagnostics.Rd deleted file mode 100644 index 83fcd0adc..000000000 --- a/examplePhenotypeLibraryPackage/man/runPhenotypeLibraryDiagnostics.Rd +++ /dev/null @@ -1,93 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/CohortDiagnostics.R -\name{runPhenotypeLibraryDiagnostics} -\alias{runPhenotypeLibraryDiagnostics} -\title{Execute the cohort diagnostics} -\usage{ -runPhenotypeLibraryDiagnostics( - connectionDetails, - cdmDatabaseSchema, - cohortDatabaseSchema = cdmDatabaseSchema, - cohortTable = "cohort", - oracleTempSchema = cohortDatabaseSchema, - outputFolder, - databaseId = "Unknown", - databaseName = "Unknown", - databaseDescription = "Unknown", - createCohorts = TRUE, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - runBreakdownIndexEvents = TRUE, - runIncidenceRates = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = TRUE, - runTemporalCohortCharacterization = TRUE, - runVisitContext = TRUE, - minCellCount = 5 -) -} -\arguments{ -\item{connectionDetails}{An object of type \code{connectionDetails} as created using the -\code{\link[DatabaseConnector]{createConnectionDetails}} function in the -DatabaseConnector package.} - -\item{cdmDatabaseSchema}{Schema name where your patient-level data in OMOP CDM format resides. -Note that for SQL Server, this should include both the database and -schema name, for example 'cdm_data.dbo'.} - -\item{cohortDatabaseSchema}{Schema name where intermediate data can be stored. You will need to have -write priviliges in this schema. Note that for SQL Server, this should -include both the database and schema name, for example 'cdm_data.dbo'.} - -\item{cohortTable}{The name of the table that will be created in the work database schema. -This table will hold the exposure and outcome cohorts used in this -study.} - -\item{oracleTempSchema}{Should be used in Oracle to specify a schema where the user has write -priviliges for storing temporary tables.} - -\item{outputFolder}{Name of local folder to place results; make sure to use forward slashes -(/). Do not use a folder on a network drive since this greatly impacts -performance.} - -\item{databaseId}{A short string for identifying the database (e.g. -'Synpuf').} - -\item{databaseName}{The full name of the database (e.g. 'Medicare Claims -Synthetic Public Use Files (SynPUFs)').} - -\item{databaseDescription}{A short description (several sentences) of the database.} - -\item{createCohorts}{Create the cohortTable table with the exposure and outcome cohorts?} - -\item{runInclusionStatistics}{Generate and export statistic on the cohort incusion rules?} - -\item{runIncludedSourceConcepts}{Generate and export the source concepts included in the cohorts?} - -\item{runOrphanConcepts}{Generate and export potential orphan concepts?} - -\item{runTimeDistributions}{Generate and export cohort time distributions?} - -\item{runBreakdownIndexEvents}{Generate and export the breakdown of index events?} - -\item{runIncidenceRates}{Generate and export the cohort incidence rates?} - -\item{runCohortOverlap}{Generate and export the cohort overlap?} - -\item{runCohortCharacterization}{Generate and export the cohort characterization?} - -\item{runTemporalCohortCharacterization}{Generate and export the temporal cohort characterization?} - -\item{runVisitContext}{Generate and export the visit context?} - -\item{minCellCount}{The minimum number of subjects contributing to a count before it can be included -in packaged results.} -} -\description{ -Execute the cohort diagnostics -} -\details{ -This function executes the cohort diagnostics. -} diff --git a/examplePhenotypeLibraryPackage/readme.md b/examplePhenotypeLibraryPackage/readme.md deleted file mode 100644 index 0877131f2..000000000 --- a/examplePhenotypeLibraryPackage/readme.md +++ /dev/null @@ -1,43 +0,0 @@ -Example Package -=============== - -This study package demonstrates how to currently use CohortDiagnostics in a package. The package only contains code to run StudyDiagnostics. - -To modify the package to include the cohorts of interest, take these steps: - -1. Copy/download the *examplePhenotypeLibraryPackage* folder. For example, download the Zip file [here](https://github.com/OHDSI/CohortDiagnostics/archive/master.zip), open it, and locate the *examplePhenotypeLibraryPackage* folder and extract it. - -2. Change the package name as needed. Most importantly: - - Change the `Package:` field in the *DESCRIPTION* file, - - The `packageName` argument in the *R/CohortDiagnostics* file, and - - The `library()` call at the top of *extras/CodeToRun.R* - - The name of the *.Rproj* file. - -3. Open the R project in R studio (e.g. by double-clicking on the *.Rproj* file). - -4. Modify *inst/settings/CohortsToCreate.csv* to include only those cohorts you are interested in. Fill in each of the four columns: - - - **atlasId**: The cohort ID in ATLAS. - - **atlasName**: The full name of the cohort. This will be shown in the Shiny app. - - **cohortId**: The cohort ID to use in the package. USually the same as the cohort ID in ATLAS. - - **name**: A short name for the cohort, to use to create file names. do not use special characters. - -5. Run this code (note, this can also be found in *extras/PackageMaintenance.R*): - - ```r - # If ROhdsiWebApi is not yet installed: - install.packages("devtools") - devtools::install_github("ROhdsiWebApi") - - ROhdsiWebApi::insertCohortDefinitionSetInPackage(fileName = "inst/settings/CohortsToCreate.csv", - baseUrl = , - insertTableSql = TRUE, - insertCohortCreationR = TRUE, - generateStats = TRUE, - packageName = ) - ``` - - Where `` is the base URL for the WebApi instance, for example: "http://server.org:80/WebAPI", and `` is the name of your new package. - -You can now build your package. See *extras/CodeToRun.R* on how to run the package. - diff --git a/extras/CohortDiagnostics.pdf b/extras/CohortDiagnostics.pdf index df62cde96..787d47fe3 100644 Binary files a/extras/CohortDiagnostics.pdf and b/extras/CohortDiagnostics.pdf differ diff --git a/extras/CreateAndLoadDataIntoPostgres.R b/extras/CreateAndLoadDataIntoPostgres.R deleted file mode 100644 index 36d255536..000000000 --- a/extras/CreateAndLoadDataIntoPostgres.R +++ /dev/null @@ -1,95 +0,0 @@ -library(magrittr) -source("extras/PostgresConfigurationVariables.R") - -dbms <- "postgresql" -databaseSchema <- "diagnostics" -pathToSql <- system.file('inst', 'sql', package = 'CohortDiagnostics') -sqlDropTableFile <- "postgresql_ddl_drop.sql" -sqlCreateTableFile <- "postgresql_ddl.sql" -sqlTableConstraintsfile <- "postgresql_ddl_constraints.sql" - -csvLocation = "extras/CSVFiles" - -uploadCsvToDatabase <- function(file, folder, schema) { - tableName <- stringr::str_replace(string = file, - pattern = ".csv$", - replacement = "") - ParallelLogger::logInfo(paste("Uploading", tableName, sep = " ")) - # checking whether the table exists with the CSV file name - if (DatabaseConnector::dbExistsTable(conn = connection, - name = tableName, - schema = databaseSchema)) { - deleteTableContentsSql <- "DELETE from @databaseSchema.@table;" - deleteTableContentsSql <- SqlRender::render(sql = deleteTableContentsSql, - table = tableName, - databaseSchema = databaseSchema) - DatabaseConnector::executeSql(connection = connection, - sql = deleteTableContentsSql) - - loadTableContentsSql <- "copy @databaseSchema.@table FROM '@csvPath' DELIMITER ',' CSV HEADER" - loadTableContentsSql <- SqlRender::render(sql = loadTableContentsSql, - table = tableName, - databaseSchema = databaseSchema, - csvPath = file.path(folder, file)) - DatabaseConnector::executeSql(connection = connection, - sql = loadTableContentsSql) - invisible(NULL) - } -} - -if (file.exists(pathToSql)) { - # 1. Connect to Postgres - connectionDetails <- DatabaseConnector::createConnectionDetails(dbms = dbms, - server = Sys.getenv("server"), - port = Sys.getenv("port"), - user = Sys.getenv("user"), - password = Sys.getenv("password")) - connection <- DatabaseConnector::connect(connectionDetails = connectionDetails) - csvFiles <- list.files(path = csvLocation, pattern = ".csv") - - # 2. Insert new schema if not exists - sql <- "CREATE SCHEMA IF NOT EXISTS @databaseSchema AUTHORIZATION @user;" - sql <- SqlRender::render(sql = sql, - databaseSchema = databaseSchema, - user = Sys.getenv("user")) - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - databaseSchema = databaseSchema, - sql = sql) - - # 4. Executes Drop Table from ddl - if (file.exists(file.path(pathToSql, sqlDropTableFile))) { - ParallelLogger::logInfo("Dropping Old Tables") - sql <- SqlRender::readSql(sourceFile = file.path(pathToSql, sqlDropTableFile)) - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql) - flag <- "dropped" - } - - # 5. Executes Create Table from ddl - if (file.exists(file.path(pathToSql, sqlCreateTableFile)) && flag == "dropped") { - ParallelLogger::logInfo("Creating the New Tables") - sql <- SqlRender::readSql(sourceFile = file.path(pathToSql, sqlCreateTableFile)) - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql) - flag <- "created" - } - - # 6. Upload values from CSV to Database - if (flag == "created") { - lapply(X = csvFiles, - FUN = uploadCsvToDatabase, - folder = csvLocation, - schema = databaseSchema) - invisible(NULL) - flag <- "uploaded" - } - - # 7. Adding constraints to the table comes next - if (file.exists(file.path(pathToSql, sqlTableConstraintsfile)) && flag == "uploaded") { - ParallelLogger::logInfo("Adding constraints Tables") - sql <- SqlRender::readSql(sourceFile = file.path(pathToSql, sqlTableConstraintsfile)) - DatabaseConnector::renderTranslateExecuteSql(connection = connection, - sql = sql) - flag <- "finished" - } -} diff --git a/extras/CreateDdlForResultsDataModel.R b/extras/CreateDdlForResultsDataModel.R deleted file mode 100644 index 6d23bf894..000000000 --- a/extras/CreateDdlForResultsDataModel.R +++ /dev/null @@ -1,77 +0,0 @@ -library(magrittr) -path = file.path("") -packageName <- "CohortDiagnostics" -packageVersion <- "2.0" -modelVersion <- "2.0" -pathToCsvFiles <- tidyr::tibble(fullPath = list.files(path = path, pattern = ".csv", full.names = TRUE)) %>% - dplyr::mutate(baseName = basename(.data$fullPath) %>% stringr::str_remove_all(string = ., pattern = ".csv")) %>% - dplyr::mutate(dontUse = dplyr::case_when(stringr::str_detect(string = baseName, pattern = "_", negate = TRUE) & - baseName != SqlRender::snakeCaseToCamelCase(baseName) - ~ TRUE, - TRUE ~ FALSE)) - -specification <- list() -for (i in (1:nrow(pathToCsvFiles))) { - if (!pathToCsvFiles[i,]$dontUse) { - specification[[i]] <- CohortDiagnostics::guessCsvFileSpecification(pathToCsvFile = pathToCsvFiles[i,]$fullPath) - } -} -specification <- dplyr::bind_rows(specification) - -resultsDataModelDirectory <- file.path(rstudioapi::getActiveProject(), - "inst", - "settings") -readr::write_excel_csv(x = specification, - file = file.path(resultsDataModelDirectory, "resultsDataModelSpecification.csv"), - na = '') - -################# -# Please inspect the resultsDataModelSpecification.csv file and confirm if the guessed data model is accurate. -# Especially the keys. -# The only keys that are valid are concept tables -################# -script <- CohortDiagnostics::createDdl(packageName = packageName, - packageVersion = packageVersion, - modelVersion = modelVersion, - specification = readr::read_csv(file = file.path(resultsDataModelDirectory, "resultsDataModelSpecification.csv"), - col_types = readr::cols(), - guess_max = min(1e7)) %>% - dplyr::filter(!tableName %in% c('concept', 'conceptAncestor', 'conceptRelationship', - 'concept_synonym', 'domain', 'relatioship', 'vocabulary')) - - ) - -pathToDdl <- file.path(rstudioapi::getActiveProject(), "inst", "sql", "sql_server") -dir.create(pathToDdl, showWarnings = FALSE, recursive = TRUE) - -SqlRender::writeSql(sql = script, - targetFile = file.path(pathToDdl, "sql_server_ddl_results_data_model.sql")) - - - - -################ -scriptConstraints <- CohortDiagnostics::createDdlPkConstraints(packageName = packageName, - packageVersion = packageVersion, - modelVersion = modelVersion, - specification = readr::read_csv(file = file.path(resultsDataModelDirectory, - "resultsDataModelSpecification.csv"), - guess_max = min(1e7), - col_types = readr::cols())) - -SqlRender::writeSql(sql = scriptConstraints, - targetFile = file.path(pathToDdl, "sql_server_ddl_results_data_model_constraints.sql")) - -################ - -scriptDropTable <- CohortDiagnostics::dropDdl(packageName = packageName, - packageVersion = packageVersion, - modelVersion = modelVersion, - specification = readr::read_csv(file = file.path(resultsDataModelDirectory, - "resultsDataModelSpecification.csv"), - guess_max = min(1e7), - col_types = readr::cols())) - -SqlRender::writeSql(sql = scriptDropTable, - targetFile = file.path(pathToDdl, "sql_server_ddl_results_data_model_drop.sql")) - diff --git a/extras/EditIncrementalLogDiagnostics.R b/extras/EditIncrementalLogDiagnostics.R index d9a220d78..77748479f 100644 --- a/extras/EditIncrementalLogDiagnostics.R +++ b/extras/EditIncrementalLogDiagnostics.R @@ -1,28 +1,36 @@ -# this script enables to easily remove log entries in incremental mode. +# this script enables to easily remove log entries in incremental mode. # if we want to rerun/overwrite previous data library(magrittr) -logFolder <- "C:\\data" +logFolder <- + "D:\\temp\\outputFolder\\packageMode" diagnosticsFileName <- "CreatedDiagnostics.csv" -# "getCohortCounts", "runInclusionStatistics", "runIncludedSourceConcepts", -# "runBreakdownIndexEvents", "runOrphanConcepts", "runTimeDistributions", -# "runVisitContext", "runIncidenceRate", "runCohortOverlap", +listFiles <- + list.files( + path = logFolder, + pattern = diagnosticsFileName, + full.names = TRUE, + recursive = TRUE + ) + +# "getCohortCounts", "runInclusionStatistics", "runIncludedSourceConcepts", +# "runBreakdownIndexEvents", "runOrphanConcepts", "runTimeDistributions", +# "runVisitContext", "runIncidenceRate", "runCohortOverlap","runCohortAsFeatures", # "runCohortCharacterization", "runTemporalCohortCharacterization" -# tasksToRemove <- c("runTemporalCohortCharacterization", "runCohortCharacterization") +# tasksToRemove <- c("runTimeSeries") -filesWithDiagnosticsLog <- list.files(path = logFolder, - pattern = diagnosticsFileName, - full.names = TRUE, - recursive = TRUE) -for (i in (1:length(filesWithDiagnosticsLog))) { - readr::read_csv(file = filesWithDiagnosticsLog[[i]], - col_types = readr::cols(), - guess_max = min(1e7)) %>% - dplyr::filter(!.data$task %in% tasksToRemove) %>% - readr::write_excel_csv(file = filesWithDiagnosticsLog[[i]]) -} + +for (i in (1:length(listFiles))) { + readr::read_csv( + file = listFiles[[i]], + col_types = readr::cols(), + guess_max = min(1e7) + ) %>% + dplyr::filter(!.data$task %in% tasksToRemove) %>% + readr::write_excel_csv(file = listFiles[[i]]) +} diff --git a/extras/ExampleOfHowToCreateStudyPackageWithHydra.R b/extras/ExampleOfHowToCreateStudyPackageWithHydra.R new file mode 100644 index 000000000..68644da63 --- /dev/null +++ b/extras/ExampleOfHowToCreateStudyPackageWithHydra.R @@ -0,0 +1,127 @@ +#remotes::install_github("OHDSI/Hydra") +outputFolder <- "d:/temp/output" # location where you study package will be created + + +########## Please populate the information below ##################### +version <- "v0.1.0" +name <- "Thrombosis With Thrombocytopenia Syndrome cohorts - an OHDSI network study" +packageName <- "ThrombosisWithThrombocytopeniaSyndrome" +skeletonVersion <- "v0.0.1" +createdBy <- "rao@ohdsi.org" +createdDate <- Sys.Date() # default +modifiedBy <- "rao@ohdsi.org" +modifiedDate <- Sys.Date() +skeletonType <- "CohortDiagnosticsStudy" +organizationName <- "OHDSI" +description <- "Cohort diagnostics on Thrombosis With Thrombocytopenia Syndrome cohorts." + + +library(magrittr) +# Set up +baseUrl <- Sys.getenv("baseUrlUnsecure") +cohortIds <- c(22040, + 22042, + 22041, + 22039, + 22038, + 22037, + 22036, + 22035, + 22034, + 22033, + 22031, + 22032, + 22030, + 22028, + 22029) + + + +################# end of user input ############## +webApiCohorts <- ROhdsiWebApi::getCohortDefinitionsMetaData(baseUrl = baseUrl) +studyCohorts <- webApiCohorts %>% + dplyr::filter(.data$id %in% cohortIds) + +# compile them into a data table +cohortDefinitionsArray <- list() +for (i in (1:nrow(studyCohorts))) { + cohortDefinition <- + ROhdsiWebApi::getCohortDefinition(cohortId = studyCohorts$id[[i]], + baseUrl = baseUrl) + cohortDefinitionsArray[[i]] <- list( + id = studyCohorts$id[[i]], + createdDate = studyCohorts$createdDate[[i]], + modifiedDate = studyCohorts$createdDate[[i]], + logicDescription = studyCohorts$description[[i]], + name = stringr::str_trim(stringr::str_squish(cohortDefinition$name)), + expression = cohortDefinition$expression + ) +} + +tempFolder <- tempdir() +unlink(x = tempFolder, recursive = TRUE, force = TRUE) +dir.create(path = tempFolder, showWarnings = FALSE, recursive = TRUE) + +specifications <- list(id = 1, + version = version, + name = name, + packageName = packageName, + skeletonVersin = skeletonVersion, + createdBy = createdBy, + createdDate = createdDate, + modifiedBy = modifiedBy, + modifiedDate = modifiedDate, + skeletontype = skeletonType, + organizationName = organizationName, + description = description, + cohortDefinitions = cohortDefinitionsArray) + +jsonFileName <- paste0(file.path(tempFolder, "CohortDiagnosticsSpecs.json")) +write(x = specifications %>% RJSONIO::toJSON(pretty = TRUE), file = jsonFileName) + + +############################################################## +############################################################## +####### Get skeleton from github ############ +############################################################## +############################################################## +############################################################## +#### get the skeleton from github +download.file(url = "https://github.com/OHDSI/SkeletonCohortDiagnosticsStudy/archive/refs/heads/main.zip", + destfile = file.path(tempFolder, 'skeleton.zip')) +unzip(zipfile = file.path(tempFolder, 'skeleton.zip'), + overwrite = TRUE, + exdir = file.path(tempFolder, "skeleton") + ) +fileList <- list.files(path = file.path(tempFolder, "skeleton"), full.names = TRUE, recursive = TRUE, all.files = TRUE) +DatabaseConnector::createZipFile(zipFile = file.path(tempFolder, 'skeleton.zip'), + files = fileList, + rootFolder = list.dirs(file.path(tempFolder, 'skeleton'), recursive = FALSE)) + +############################################################## +############################################################## +####### Build package ############# +############################################################## +############################################################## +############################################################## + + +#### Code that uses the ExampleCohortDiagnosticsSpecs in Hydra to build package +hydraSpecificationFromFile <- Hydra::loadSpecifications(fileName = jsonFileName) +unlink(x = outputFolder, recursive = TRUE) +dir.create(path = outputFolder, showWarnings = FALSE, recursive = TRUE) +Hydra::hydrate(specifications = hydraSpecificationFromFile, + outputFolder = outputFolder, + skeletonFileName = file.path(tempFolder, 'skeleton.zip') +) + + +unlink(x = tempFolder, recursive = TRUE, force = TRUE) + + +############################################################## +############################################################## +###### Build, install and execute package ############# +############################################################## +############################################################## +############################################################## diff --git a/extras/PackageMaintenance.R b/extras/PackageMaintenance.R index 08570aff8..38f804610 100644 --- a/extras/PackageMaintenance.R +++ b/extras/PackageMaintenance.R @@ -1,6 +1,6 @@ # @file PackageMaintenance # -# Copyright 2020 Observational Health Data Sciences and Informatics +# Copyright 2021 Observational Health Data Sciences and Informatics # # This file is part of CohortDiagnostics # @@ -17,7 +17,6 @@ # limitations under the License. # Format and check code -# OhdsiRTools::formatRFolder() (note: this function has been impacted by change in formatR) OhdsiRTools::checkUsagePackage("CohortDiagnostics") OhdsiRTools::updateCopyrightYearFolder() devtools::spell_check() @@ -35,15 +34,39 @@ rmarkdown::render("vignettes/CohortDiagnosticsUsingWebApi.Rmd", toc = TRUE, number_sections = TRUE)) +rmarkdown::render("vignettes/CohortDiagnosticsInPackageMode.Rmd", + output_file = "../inst/doc/CohortDiagnosticsInPackageMode.pdf", + rmarkdown::pdf_document(latex_engine = "pdflatex", + toc = TRUE, + number_sections = TRUE)) + +rmarkdown::render("vignettes/ViewingResultsUsingDiagnosticsExplorer.Rmd", + output_file = "../inst/doc/ViewingResultsUsingDiagnosticsExplorer.pdf", + rmarkdown::pdf_document(latex_engine = "pdflatex", + toc = TRUE, + number_sections = TRUE)) + +rmarkdown::render("vignettes/DatabaseModeInDiagnosticsExplorer.Rmd", + output_file = "../inst/doc/DatabaseModeInDiagnosticsExplorer.pdf", + rmarkdown::pdf_document(latex_engine = "pdflatex", + toc = TRUE, + number_sections = TRUE)) + +rmarkdown::render("vignettes/WhatIsCohortDiagnostics.Rmd", + output_file = "../inst/doc/WhatIsCohortDiagnostics.pdf", + rmarkdown::pdf_document(latex_engine = "pdflatex", + toc = TRUE, + number_sections = TRUE)) + +rmarkdown::render("vignettes/RunningCohortDiagnostics.Rmd", + output_file = "../inst/doc/RunningCohortDiagnostics.pdf", + rmarkdown::pdf_document(latex_engine = "pdflatex", + toc = TRUE, + number_sections = TRUE)) + pkgdown::build_site() OhdsiRTools::fixHadesLogo() -# Regenerate DDL -pathToCsv <- file.path("inst", "settings", "resultsDataModelSpecification.csv") -specifications <- readr::read_csv(file = pathToCsv, col_types = readr::cols()) -source("extras/ResultsDataModel.R") -createDdl("inst/sql/postgresql/CreateResultsDataModel.sql", specifications) - # Copy data model specs to Shiny app file.copy(from = "inst/settings/resultsDataModelSpecification.csv", to = "inst/shiny/DiagnosticsExplorer/resultsDataModelSpecification.csv", diff --git a/extras/PostgresConfigurationVariables.R b/extras/PostgresConfigurationVariables.R deleted file mode 100644 index 184752679..000000000 --- a/extras/PostgresConfigurationVariables.R +++ /dev/null @@ -1,7 +0,0 @@ -Sys.setenv(phenotypeLibraryDbServer = "") -Sys.setenv(phenotypeLibraryDbPort = 5432) -Sys.setenv(phenotypeLibraryDbDatabase = "") -Sys.setenv(phenotypeLibraryDbResultsSchema = "") -Sys.setenv(phenotypeLibraryCdmSchema = "") -Sys.setenv(phenotypeLibraryDbUser = "") -Sys.setenv(phenotypeLibraryDbPassword = "") diff --git a/extras/ResultsDataModel.R b/extras/ResultsDataModel.R deleted file mode 100644 index d7350684e..000000000 --- a/extras/ResultsDataModel.R +++ /dev/null @@ -1,186 +0,0 @@ -library(dplyr) - -guessCsvFileSpecification <- function(pathToCsvFile) { - tableToWorkOn <- stringr::str_remove(string = basename(pathToCsvFile), - pattern = ".csv") - - print(paste0("Reading csv files '", tableToWorkOn, "' and guessing data types.")) - - csvFile <- readr::read_csv(file = pathToCsvFile, - col_types = readr::cols(), - guess_max = min(1e7), - locale = readr::locale(encoding = "UTF-8")) - if (any(stringr::str_detect(string = colnames(csvFile), pattern = "_"))) { - colnames(csvFile) <- tolower(colnames(csvFile)) - } - - patternThatIsNotPrimaryKey = c("subjects", "entries", "name", "sql", "json", "description", "atlas_id", "day") - patternThatIsPrimaryKey = c('_id', 'rule_sequence') - describe <- list() - primaryKeyIfOmopVocabularyTable <- getPrimaryKeyForOmopVocabularyTable() %>% - dplyr::filter(.data$vocabularyTableName == tableToWorkOn %>% tolower()) %>% - dplyr::pull(.data$primaryKey) %>% - strsplit(split = ",") %>% - unlist() %>% - tolower() - - for (i in (1:length(colnames(csvFile)))) { - tableName <- tableToWorkOn - fieldName <- colnames(csvFile)[[i]] - fieldData <- csvFile %>% dplyr::select(fieldName) - dataVector <- fieldData %>% dplyr::pull(1) - type <- suppressWarnings(guessDbmsDataTypeFromVector(value = dataVector)) - if (stringr::str_detect(string = fieldName, - pattern = stringr::fixed('_id')) && - type == 'float') { - type = 'bigint' - } - if (stringr::str_detect(string = tolower(fieldName), - pattern = stringr::fixed('description')) && - (stringr::str_detect(string = type, - pattern = 'varchar') || - stringr::str_detect(string = type, - pattern = 'logical') - ) - ) { - type = 'varchar(max)' - } - isRequired <- 'Yes' - if (anyNA(csvFile %>% dplyr::pull(fieldName))) { - isRequired <- 'No' - } - primaryKey <- 'No' - if (tableName %in% getPrimaryKeyForOmopVocabularyTable()$vocabularyTableName && - fieldName %in% primaryKeyIfOmopVocabularyTable) { - primaryKey <- 'Yes' - } else if (isRequired == 'Yes' && - nrow(csvFile) == nrow(csvFile %>% dplyr::select(fieldName) %>% dplyr::distinct()) && - all(stringr::str_detect(string = fieldName, - pattern = patternThatIsNotPrimaryKey, - negate = TRUE))) { - primaryKey <- 'Yes' - } else if (isRequired == 'Yes' && - any(stringr::str_detect(string = fieldName, - pattern = patternThatIsPrimaryKey))) { - primaryKey <- 'Yes' - } - describe[[i]] <- tidyr::tibble(tableName = tableName, - fieldName = fieldName, - type = type, - isRequired = isRequired, - primaryKey = primaryKey) - - if (describe[[i]]$type == 'logical') { - describe[[i]]$type == 'varchar(1)' - } - if (describe[[i]]$tableName == 'cohort' && - describe[[i]]$fieldName == 'cohort_name' && - describe[[i]]$type == 'float') { - describe[[i]]$type = 'varchar(255)' - } - if (describe[[i]]$tableName == 'incidence_rate' && describe[[i]]$fieldName == 'calendar_year') { - describe[[i]]$primaryKey = 'Yes' - } - if (describe[[i]]$tableName %in% c('covariate_value', 'temporal_covariate_value', 'time_distribution') && - describe[[i]]$fieldName %in% c('covariate_id','start_day','end_day')) { - describe[[i]]$primaryKey = 'Yes' - } - if (describe[[i]]$tableName %in% c('included_source_concept','index_event_breakdown', 'orphan_concept')) { - if (describe[[i]]$fieldName %in% c('concept_set_id', 'concept_id', 'source_concept_id')) { - describe[[i]]$primaryKey = 'Yes' - } - } - } - describe <- dplyr::bind_rows(describe) - return(describe) -} - -createDdl <- function(fileName, - specifications = CohortDiagnostics::getResultsDataModelSpecifications()){ - tableNames <- specifications$tableName %>% unique() - script <- c() - script <- c(script, "-- Drop old tables if exist") - script <- c(script, "") - for (tableName in tableNames) { - script <- c(script, paste0("DROP TABLE IF EXISTS ", tableName, ";")) - } - script <- c(script, "") - script <- c(script, "") - script <- c(script, "-- Create tables") - for (tableName in tableNames) { - script <- c(script, "") - script <- c(script, paste("--Table", tableName)) - script <- c(script, "") - table <- specifications %>% - dplyr::filter(.data$tableName == !!tableName) - - script <- c(script, paste0("CREATE TABLE ", tableName, " (")) - fieldSql <- c() - for (fieldName in table$fieldName) { - field <- table %>% - filter(.data$fieldName == !!fieldName) - - if (field$primaryKey == "Yes") { - required <- " PRIMARY KEY" - } - - if (field$isRequired == "Yes") { - required <- " NOT NULL" - } else { - required = "" - } - fieldSql <- c(fieldSql, paste0("\t\t\t", - fieldName, - " ", - toupper(field$type), - required)) - } - primaryKeys <- table %>% - filter(.data$primaryKey == "Yes") %>% - select(.data$fieldName) %>% - pull() - fieldSql <- c(fieldSql, paste0("\t\t\tPRIMARY KEY(", paste(primaryKeys, collapse = ", "), ")")) - script <- c(script, paste(fieldSql, collapse = ",\n")) - script <- c(script, ");") - } - SqlRender::writeSql(paste(script, collapse = "\n"), fileName) -} - -guessDbmsDataTypeFromVector <- function(value) { - class <- value %>% class() %>% max() - type <- value %>% typeof() %>% max() - mode <- value %>% mode() %>% max() - if (type == 'double' && class == 'Date' && mode == 'numeric') { - type = 'Date' - } else if (type == 'double' && (any(class %in% c("POSIXct", "POSIXt"))) && mode == 'numeric') { - type = 'DATETIME2' - } else if (type == 'double' && class == 'numeric' && mode == 'numeric') { #in R double and numeric are same - type = 'float' - } else if (class == 'integer' && type == 'integer' && mode == 'integer') { - type = 'integer' - } else if (type == 'character' && class == 'character' && mode == 'character') { - fieldCharLength <- try(max(stringr::str_length(value)) %>% - as.integer()) - if (is.na(fieldCharLength)) { - fieldCharLength = 9999 - } - if (fieldCharLength <= 1) { - fieldChar = '1' - } else if (fieldCharLength <= 20) { - fieldChar = '20' - } else if (fieldCharLength <= 50) { - fieldChar = '50' - } else if (fieldCharLength <= 255) { - fieldChar = '255' - } else { - fieldChar = 'max' - } - type = paste0('varchar(', fieldChar, ')') - } else if (class == "logical") { - type <- 'varchar(1)' - } else { - type <- 'Unknown' - } - return(type) -} - diff --git a/extras/UploadToDatabase.R b/extras/UploadToDatabase.R index 2ecbfbbdb..0e757df19 100644 --- a/extras/UploadToDatabase.R +++ b/extras/UploadToDatabase.R @@ -1,44 +1,45 @@ # Using the official uploading functions to get data from zip files into the postgres database library(CohortDiagnostics) -# Martijn's local server: -connectionDetails <- createConnectionDetails(dbms = "postgresql", - server = "localhost/ohdsi", - user = "postgres", - password = Sys.getenv("pwPostgres")) -resultsSchema <- "phenotype_library" - # OHDSI's server: -connectionDetails <- createConnectionDetails(dbms = "postgresql", - server = paste(Sys.getenv("phenotypeLibraryDbServer"), - Sys.getenv("phenotypeLibraryDbDatabase"), - sep = "/"), - port = Sys.getenv("phenotypeLibraryDbPort"), - user = Sys.getenv("phenotypeLibraryDbUser"), - password = Sys.getenv("phenotypeLibraryDbPassword")) -resultsSchema <- Sys.getenv("phenotypeLibraryDbResultsSchema") - -createResultsDataModel(connectionDetails = connectionDetails, schema = resultsSchema) - - - -Sys.setenv("POSTGRES_PATH" = "C:/Program Files/PostgreSQL/11/bin") -uploadResults(connectionDetails = connectionDetails, - schema = resultsSchema, - zipFileName = "S:/examplePackageOutput/CCAE/diagnosticsExport/Results_CCAE.zip") +connectionDetails <- createConnectionDetails( + dbms = "postgresql", + server = paste( + Sys.getenv("shinydbServer"), + Sys.getenv("shinydbDatabase"), + sep = "/" + ), + port = Sys.getenv("shinydbPort"), + user = Sys.getenv("shinydbUser"), + password = Sys.getenv("shinydbPW") +) +resultsSchema <- 'thrombosisthrombocytopenia' + +# commenting this function as it maybe accidentally run - loosing data. +# createResultsDataModel(connectionDetails = connectionDetails, schema = resultsSchema) + +Sys.setenv("POSTGRES_PATH" = Sys.getenv('POSTGRES_PATH')) + +folderWithZipFilesToUpload <- "D:\\results\\twt\\withInclusion" +listOfZipFilesToUpload <- + list.files( + path = folderWithZipFilesToUpload, + pattern = ".zip", + full.names = TRUE, + recursive = TRUE + ) + +for (i in (1:length(listOfZipFilesToUpload))) { + CohortDiagnostics::uploadResults( + connectionDetails = connectionDetails, + schema = resultsSchema, + zipFileName = listOfZipFilesToUpload[[i]] + ) +} + +# uploadPrintFriendly was removed in version 2.1 +# uploadPrintFriendly(connectionDetails = connectionDetails, +# schema = resultsSchema) -uploadResults(connectionDetails = connectionDetails, - schema = resultsSchema, - zipFileName = "S:/examplePackageOutput/MDCD/diagnosticsExport/Results_IBM_MDCD.zip") launchDiagnosticsExplorer(connectionDetails = connectionDetails, resultsDatabaseSchema = resultsSchema) - - -uploadResults(connectionDetails = connectionDetails, - schema = resultsSchema, - zipFileName = "s:/immunology/Results_JMDC.zip") - -uploadResults(connectionDetails = connectionDetails, - schema = resultsSchema, - zipFileName = "s:/immunology/Results_OPTUM_PANTHER.zip") - diff --git a/extras/tests/TestCode.R b/extras/tests/TestCode.R deleted file mode 100644 index bc9e71fc0..000000000 --- a/extras/tests/TestCode.R +++ /dev/null @@ -1,300 +0,0 @@ -library(CohortDiagnostics) - -ParallelLogger::addDefaultErrorReportLogger() - -# PDW -------------------------------------------------------- -connectionDetails <- createConnectionDetails(dbms = "pdw", - server = Sys.getenv("PDW_SERVER"), - port = Sys.getenv("PDW_PORT")) -oracleTempSchema <- NULL -workDatabaseSchema <- "scratch.dbo" - - -# Using private cohort table: cdmDatabaseSchema <- 'CDM_IBM_MDCR_V1062.dbo' -cdmDatabaseSchema <- "CDM_jmdc_v1063.dbo" -cohortDatabaseSchema <- workDatabaseSchema -resultsDatabaseSchema <- workDatabaseSchema -cohortTable <- "mschuemi_temp" -databaseId <- "JMDC" - -# Using ATLAS cohort table: -cohortDatabaseSchema <- "CDM_IBM_MDCR_V1062.dbo" -resultsDatabaseSchema <- "CDM_IBM_MDCR_V1062.ohdsi_results" - -# RedShift -------------------------------------------------------- -connectionDetails <- createConnectionDetails(dbms = "redshift", - connectionString = Sys.getenv("jmdcRedShiftConnectionString"), - user = Sys.getenv("redShiftUser"), - password = Sys.getenv("redShiftPassword")) -oracleTempSchema <- NULL -workDatabaseSchema <- "scratch_mschuemi" -cdmDatabaseSchema <- "cdm" -cohortDatabaseSchema <- workDatabaseSchema -resultsDatabaseSchema <- workDatabaseSchema -cohortTable <- "mschuemi_temp" -databaseId <- "JMDC" - -connection <- connect(connectionDetails) -DatabaseConnector::getTableNames(connection, "scratch_mschuemI") -disconnect(connection) - -baseUrl <- Sys.getenv("baseUrl") - -cohortId <- 7399 # LEGEND Cardiac Arrhythmia - -cohortId <- 7362 # LEGEND cardiovascular-related mortality - -cohortId <- 13567 # Test cohort with two initial event criteria - -cohortId <- 5665 # Zoledronic acid new users with prostate cancer (many inclusion rules) - - -# Cohort construction (when not using ATLAS cohorts) ------------------------------------- -createCohortTable(connectionDetails = connectionDetails, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - createInclusionStatsTables = TRUE) - -instantiateCohort(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - baseUrl = baseUrl, - cohortId = cohortId, - generateInclusionStats = TRUE) - -# Launch Diagnostics Explorer app ---------------------------------------------- -preMergeDiagnosticsFiles("C:/temp/exampleStudy") - -launchDiagnosticsExplorer("C:/temp/exampleStudy") - - -# Launch Cohort Explorer app --------------------------------------------------- -launchCohortExplorer(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - cohortId = cohortId) - - - -dbms <- "pdw" -user <- NULL -pw <- NULL -server <- Sys.getenv("PDW_SERVER") -port <- Sys.getenv("PDW_PORT") -oracleTempSchema <- NULL -connectionDetails <- DatabaseConnector::createConnectionDetails(dbms = dbms, - server = server, - user = user, - password = pw, - port = port) - -studyFolder <- "c:/BarcelonaStudyAThon" - -cdmDatabaseSchema <- "cdm_synpuf_v667.dbo" -cohortDatabaseSchema <- "scratch.dbo" -cohortTable <- "barca_synpuf" -databaseId <- "Synpuf" -databaseName <- "Medicare Claims Synthetic Public Use Files (SynPUFs)" -databaseDescription <- "Medicare Claims Synthetic Public Use Files (SynPUFs) were created to allow interested parties to gain familiarity using Medicare claims data while protecting beneficiary privacy. These files are intended to promote development of software and applications that utilize files in this format, train researchers on the use and complexities of Centers for Medicare and Medicaid Services (CMS) claims, and support safe data mining innovations. The SynPUFs were created by combining randomized information from multiple unique beneficiaries and changing variable values. This randomization and combining of beneficiary information ensures privacy of health information." -folder <- file.path(studyFolder, "synpuf") - - -inclusionStatisticsFolder <- folder -cohortId <- 13666 - -packageName <- "BarcelonaStudyAThon" -exportFolder <- file.path(folder, "export") - -library(CohortDiagnostics) - - - -# Using cohort set with WebAPI --------------------------------------------------- -baseUrl <- Sys.getenv("ohdsiBaseUrl") -inclusionStatisticsFolder <- "c:/temp/incStats" -exportFolder <- "s:/noPackage/export" -cohortSetReference <- data.frame(atlasId = c(1770710, 1770713), - atlasName = c("New users of ACE inhibitors as first-line monotherapy for hypertension", "Acute myocardial infarction outcome"), - cohortId = c(1770710, 1770713), - name = c("New_users_of_ACE_inhibitors_as_firstline_monotherapy_for_hypertension_2", "Acute_myocardial_infarction_outcome")) - -createCohortTable(connectionDetails = connectionDetails, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable) - -instantiateCohortSet(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - baseUrl = baseUrl, - cohortSetReference = cohortSetReference, - generateInclusionStats = TRUE, - inclusionStatisticsFolder = inclusionStatisticsFolder) - -runCohortDiagnostics(baseUrl = baseUrl, - cohortSetReference = cohortSetReference, - connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - inclusionStatisticsFolder = inclusionStatisticsFolder, - exportFolder = exportFolder, - databaseId = databaseId, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = FALSE, - runTimeDistributions = FALSE, - runBreakdownIndexEvents = TRUE, - runIncidenceRate = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = FALSE, - minCellCount = 5) - -launchDiagnosticsExplorer(exportFolder) - -# Using 'external' concept counts ------------------------------------------------- -cdmDatabaseSchema <- 'CDM_IBM_MDCR_V1062.dbo' -conceptCountsDatabaseSchema <- "scratch.dbo" -conceptCountsTable <- "mschuemi_concept_counts" -databaseId <- "MDCR" -exportFolder <- "s:/noPackage/export/mdcr" - -createConceptCountsTable(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - conceptCountsDatabaseSchema = conceptCountsDatabaseSchema, - conceptCountsTable = conceptCountsTable) - -runCohortDiagnosticsUsingExternalCounts(baseUrl = baseUrl, - cohortSetReference = cohortSetReference, - connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - conceptCountsDatabaseSchema = conceptCountsDatabaseSchema, - conceptCountsTable = conceptCountsTable, - exportFolder = exportFolder, - databaseId = databaseId, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - minCellCount = 5) -# connection <- DatabaseConnector::connect(connectionDetails) -# DatabaseConnector::querySql(connection, "SELECT * FROM scratch.dbo.mschuemi_concept_counts WHERE concept_id = 35207668;") - - -# As verification: same DB, but not using 'external' concept counts: -runCohortDiagnostics(baseUrl = baseUrl, - cohortSetReference = cohortSetReference, - connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - exportFolder = paste0(exportFolder, "_check"), - databaseId = paste0(databaseId, "_check"), - runBreakdownIndexEvents = FALSE, - runCohortCharacterization = FALSE, - runCohortOverlap = FALSE, - runIncidenceRate = FALSE, - runInclusionStatistics = FALSE, - runTimeDistributions = FALSE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - minCellCount = 5) - -# Test incremental mode ------------------------------------------------------------------------------ - -baseUrl <- Sys.getenv("ohdsiBaseUrl") -cohortSetReferenceFile <- file.path("exampleComparativeCohortStudy", "inst", "settings", "CohortsToCreate.csv") -cohortSetReference <- read.csv(cohortSetReferenceFile) -folder <- "c:/temp/cdTest" -inclusionStatisticsFolder <- file.path(folder, "incStats") -incrementalFolder <- file.path(folder, "incremental") -exportFolder <- file.path(folder, "export") -# unlink(folder, recursive = TRUE) - -# Drop old cohort table: -connection <- DatabaseConnector::connect(connectionDetails) -sql <- "DROP TABLE @cohort_database_schema.@cohort_table;" -DatabaseConnector::renderTranslateExecuteSql(connection, sql, cohort_database_schema = cohortDatabaseSchema, cohort_table = cohortTable) -DatabaseConnector::disconnect(connection) - -# First run subset: -subset <- cohortSetReference[c(1,3), ] -instantiateCohortSet(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - createCohortTable = TRUE, - baseUrl = baseUrl, - cohortSetReference = subset, - generateInclusionStats = TRUE, - inclusionStatisticsFolder = inclusionStatisticsFolder, - incremental = TRUE, - incrementalFolder = incrementalFolder) - -runCohortDiagnostics(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - baseUrl = baseUrl, - cohortSetReference = subset, - exportFolder = exportFolder, - databaseId = databaseId, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - runBreakdownIndexEvents = TRUE, - runIncidenceRate = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = TRUE, - inclusionStatisticsFolder = inclusionStatisticsFolder, - incremental = TRUE, - incrementalFolder = incrementalFolder) - -# Then run all: -instantiateCohortSet(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - createCohortTable = TRUE, - baseUrl = baseUrl, - cohortSetReference = cohortSetReference, - generateInclusionStats = TRUE, - inclusionStatisticsFolder = inclusionStatisticsFolder, - incremental = TRUE, - incrementalFolder = incrementalFolder) - -runCohortDiagnostics(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - baseUrl = baseUrl, - cohortSetReference = cohortSetReference, - exportFolder = exportFolder, - databaseId = databaseId, - runInclusionStatistics = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - runBreakdownIndexEvents = TRUE, - runIncidenceRate = TRUE, - runCohortOverlap = TRUE, - runCohortCharacterization = TRUE, - inclusionStatisticsFolder = inclusionStatisticsFolder, - incremental = TRUE, - incrementalFolder = incrementalFolder) - -preMergeDiagnosticsFiles(exportFolder) - - -launchDiagnosticsExplorer(exportFolder) - diff --git a/extras/tests/TestCodeEunomia.R b/extras/tests/TestCodeEunomia.R deleted file mode 100644 index 5a02ce166..000000000 --- a/extras/tests/TestCodeEunomia.R +++ /dev/null @@ -1,56 +0,0 @@ -library(CohortDiagnostics) -library(Eunomia) - -#baseUrl <- Sys.getenv("OHDSIbaseUrl") - -connectionDetails <- Eunomia::getEunomiaConnectionDetails() -cdmDatabaseSchema <- "main" -cohortDatabaseSchema <- "main" -cohortTable <- "cohort" -oracleTempSchema <- NULL -folder <- "D:\\git\\bitbucket\\cohortDiagnosticsTest\\results\\firstRun\\eunomia" #tempfile() -unlink(x = folder, recursive = TRUE, force = TRUE) -dir.create(folder, recursive = TRUE, showWarnings = FALSE) - - -CohortDiagnostics::instantiateCohortSet(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - packageName = "CohortDiagnostics", - cohortToCreateFile = "settings/CohortsToCreateForTesting.csv", - generateInclusionStats = TRUE, - createCohortTable = TRUE, - # incremental = TRUE, - # incrementalFolder = file.path(folder, "incremental"), - inclusionStatisticsFolder = file.path(folder, "inclusionStatistics")) - -# debug(CohortDiagnostics::runCohortDiagnostics) -# debug(CohortDiagnostics::breakDownIndexEvents) - -CohortDiagnostics::runCohortDiagnostics(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - packageName = "CohortDiagnostics", - cohortToCreateFile = "settings/CohortsToCreateForTesting.csv", - inclusionStatisticsFolder = file.path(folder, "inclusionStatistics"), - exportFolder = file.path(folder, "export"), - databaseId = "Eunomia", - runInclusionStatistics = TRUE, - runBreakdownIndexEvents = TRUE, - runCohortCharacterization = TRUE, - runTemporalCohortCharacterization = TRUE, - runCohortOverlap = TRUE, - runIncidenceRate = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - incremental = TRUE, - minCellCount = 10, - incrementalFolder = file.path(folder, "incremental")) - -CohortDiagnostics::preMergeDiagnosticsFiles(dataFolder = file.path(folder, "export")) - diff --git a/extras/tests/TestCodeEunomiaPackageMode.R b/extras/tests/TestCodeEunomiaPackageMode.R new file mode 100644 index 000000000..9407b8108 --- /dev/null +++ b/extras/tests/TestCodeEunomiaPackageMode.R @@ -0,0 +1,60 @@ +# remotes::install_github('OHDSI/SkeletonCohortDiagnosticsStudy') +# remotes::install_github('OHDSI/Eunomia') + +library(CohortDiagnostics) +library(SkeletonCohortDiagnosticsStudy) + +outputLocation <- "D:\\temp" +outputFolder <- + file.path(outputLocation, "outputFolder", "packageMode", "eunomia") +# Please delete previous content if needed +unlink(x = outputFolder, + recursive = TRUE, + force = TRUE) +dir.create(path = outputFolder, + showWarnings = FALSE, + recursive = TRUE) + +execute( + connectionDetails = Eunomia::getEunomiaConnectionDetails(), + cdmDatabaseSchema = 'main', + vocabularyDatabaseSchema = "main", + cohortDatabaseSchema = "main", + cohortTable = "cohortEunomia", + outputFolder = outputFolder, + databaseId = "Eunomia", + databaseName = "Eunomia Test", + databaseDescription = "This is a test data base called Eunomia" +) + +CohortDiagnostics::preMergeDiagnosticsFiles(dataFolder = outputFolder) + + + +connectionDetailsToUpload <- createConnectionDetails(dbms = "postgresql", + server = paste(Sys.getenv("shinydbServer"), + Sys.getenv("shinydbDatabase"), + sep = "/"), + port = Sys.getenv("shinydbPort"), + user = Sys.getenv("shinyDbUser"), + password = Sys.getenv("shinydbPw")) + + +resultsSchema <- "eunomiaCd" +createResultsDataModel(connectionDetails = connectionDetailsToUpload, schema = resultsSchema) + + +path = outputFolder +zipFilesToUpload <- list.files(path = path, + pattern = ".zip", + recursive = TRUE, + full.names = TRUE) + +for (i in (1:length(zipFilesToUpload))) { + CohortDiagnostics::uploadResults(connectionDetails = connectionDetailsToUpload, + schema = resultsSchema, + zipFileName = zipFilesToUpload[[i]]) +} + + +CohortDiagnostics::launchDiagnosticsExplorer(dataFolder = outputFolder) diff --git a/extras/tests/TestCodeEunomiaWebApiMode.R b/extras/tests/TestCodeEunomiaWebApiMode.R new file mode 100644 index 000000000..5c6e66b3e --- /dev/null +++ b/extras/tests/TestCodeEunomiaWebApiMode.R @@ -0,0 +1,108 @@ +# remotes::install_github('OHDSI/SkeletonCohortDiagnosticsStudy') +# remotes::install_github('OHDSI/Eunomia') + +library(CohortDiagnostics) +library(SkeletonCohortDiagnosticsStudy) + +temporaryLocation <- tempdir() + +connectionDetails <- Eunomia::getEunomiaConnectionDetails() +cdmDatabaseSchema <- "main" +cohortDatabaseSchema <- "main" +cohortTable <- "cohort" +databaseId <- "Eunomia" + +library(magrittr) +# Set up +baseUrl <- Sys.getenv("baseUrl") +# list of cohort ids +cohortIds <- c(18345,18346) + +# get specifications for the cohortIds above +webApiCohorts <- + ROhdsiWebApi::getCohortDefinitionsMetaData(baseUrl = baseUrl) %>% + dplyr::filter(.data$id %in% cohortIds) + +cohortsToCreate <- list() +for (i in (1:nrow(webApiCohorts))) { + cohortId <- webApiCohorts$id[[i]] + cohortDefinition <- + ROhdsiWebApi::getCohortDefinition(cohortId = cohortId, + baseUrl = baseUrl) + cohortsToCreate[[i]] <- tidyr::tibble( + atlasId = webApiCohorts$id[[i]], + atlasName = stringr::str_trim(string = stringr::str_squish(cohortDefinition$name)), + cohortId = webApiCohorts$id[[i]], + name = stringr::str_trim(stringr::str_squish(cohortDefinition$name)) + ) +} +cohortsToCreate <- dplyr::bind_rows(cohortsToCreate) + +readr::write_excel_csv(x = cohortsToCreate, na = "", + file = file.path(temporaryLocation, "CohortsToCreate.csv"), + append = FALSE) + + +outputFolder <- file.path(temporaryLocation, "outputFolder", "webApiMode", "eunomia") +# Please delete previous content if needed +# unlink(x = outputFolder, +# recursive = TRUE, +# force = TRUE) +dir.create(path = outputFolder, showWarnings = FALSE, recursive = TRUE) + +cohortSetReference <- readr::read_csv(file = file.path(temporaryLocation, "CohortsToCreate.csv"), + col_types = readr::cols()) + +CohortDiagnostics::instantiateCohortSet(connectionDetails = connectionDetails, + cdmDatabaseSchema = cdmDatabaseSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + baseUrl = baseUrl, + cohortSetReference = cohortSetReference, + generateInclusionStats = TRUE, + inclusionStatisticsFolder = file.path(outputFolder, + 'inclusionStatisticsFolder')) + +CohortDiagnostics::runCohortDiagnostics(baseUrl = baseUrl, + cohortSetReference = cohortSetReference, + connectionDetails = connectionDetails, + cdmDatabaseSchema = cdmDatabaseSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + inclusionStatisticsFolder = file.path(outputFolder, + 'inclusionStatisticsFolder'), + exportFolder = file.path(outputFolder, + 'exportFolder'), + databaseId = databaseId, + minCellCount = 0) + +CohortDiagnostics::preMergeDiagnosticsFiles(dataFolder = outputFolder) + +CohortDiagnostics::launchDiagnosticsExplorer(dataFolder = outputFolder) + + +# connectionDetailsToUpload <- createConnectionDetails(dbms = "postgresql", +# server = paste(Sys.getenv("shinydbServer"), +# Sys.getenv("shinydbDatabase"), +# sep = "/"), +# port = Sys.getenv("shinydbPort"), +# user = Sys.getenv("shinyDbUser"), +# password = Sys.getenv("shinyDbPassword")) +# +# +# resultsSchema <- "eunomiaCd" +# createResultsDataModel(connectionDetails = connectionDetailsToUpload, schema = resultsSchema) +# +# +# path = outputFolder +# zipFilesToUpload <- list.files(path = path, +# pattern = ".zip", +# recursive = TRUE, +# full.names = TRUE) +# +# for (i in (1:length(zipFilesToUpload))) { +# uploadResults(connectionDetails = connectionDetailsToUpload, +# schema = resultsSchema, +# zipFileName = zipFilesToUpload[[i]]) +# } + diff --git a/extras/tests/TestCodeRealDataPackageMode.R b/extras/tests/TestCodeRealDataPackageMode.R new file mode 100644 index 000000000..8e1c7ba73 --- /dev/null +++ b/extras/tests/TestCodeRealDataPackageMode.R @@ -0,0 +1,97 @@ +# remotes::install_github('OHDSI/SkeletonCohortDiagnosticsStudy') + +library(CohortDiagnostics) +library('SkeletonCohortDiagnosticsStudy') +packageName <- 'SkeletonCohortDiagnosticsStudy' + +outputLocation <- "D:\\temp" + +connectionSpecifications <- cdmSources %>% + dplyr::filter(sequence == 1) %>% + dplyr::filter(database == 'jmdc') + +dbms <- connectionSpecifications$dbms # example: 'redshift' +port <- connectionSpecifications$port # example: 2234 +server <- + connectionSpecifications$server # example: 'fdsfd.yourdatabase.yourserver.com" +cdmDatabaseSchema <- + connectionSpecifications$cdmDatabaseSchema # example: "cdm" +vocabDatabaseSchema <- + connectionSpecifications$vocabDatabaseSchema # example: "vocabulary" +databaseId <- + connectionSpecifications$database # example: "truven_ccae" +userNameService = "OHDSI_USER" # example: "this is key ring service that securely stores credentials" +passwordService = "OHDSI_PASSWORD" # example: "this is key ring service that securely stores credentials" + +cohortDatabaseSchema = paste0('scratch_', keyring::key_get(service = userNameService)) +# cohortDatabaseSchema = paste0('scratch_rao_', databaseId) +# scratch - usually something like 'scratch_grao' + +connectionDetails <- DatabaseConnector::createConnectionDetails( + dbms = dbms, + user = keyring::key_get(service = userNameService), + password = keyring::key_get(service = passwordService), + port = port, + server = server +) + +cohortTable <- # example: 'cohort' + paste0("s", connectionSpecifications$sourceId, "_", packageName) + +outputFolder <- + file.path(outputLocation, "outputFolder", 'packageMode', databaseId) +# Please delete previous content if needed +# unlink(x = outputFolder, +# recursive = TRUE, +# force = TRUE) +dir.create(path = outputFolder, + showWarnings = FALSE, + recursive = TRUE) + +dataSouceInformation <- + getDataSourceInformation( + connectionDetails = connectionDetails, + cdmDatabaseSchema = cdmDatabaseSchema, + vocabDatabaseSchema = vocabDatabaseSchema + ) + +execute( + connectionDetails = connectionDetails, + cdmDatabaseSchema = cdmDatabaseSchema, + vocabularyDatabaseSchema = vocabDatabaseSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + outputFolder = outputFolder, + databaseId = databaseId, + databaseName = dataSouceInformation$cdmSourceName, + databaseDescription = dataSouceInformation$sourceDescription +) + +CohortDiagnostics::preMergeDiagnosticsFiles(dataFolder = outputFolder) + +CohortDiagnostics::launchDiagnosticsExplorer(dataFolder = outputFolder) + +# connectionDetailsToUpload <- createConnectionDetails(dbms = "postgresql", +# server = paste(Sys.getenv("shinydbServer"), +# Sys.getenv("shinydbDatabase"), +# sep = "/"), +# port = Sys.getenv("shinydbPort"), +# user = Sys.getenv("shinyDbUser"), +# password = Sys.getenv("shinyDbPassword")) +# +# +# resultsSchema <- "CdSkeletonCohortDiagnosticsStudy" +# CohortDiagnostics::createResultsDataModel(connectionDetails = connectionDetailsToUpload, schema = resultsSchema) +# +# +# path = outputFolder +# zipFilesToUpload <- list.files(path = path, +# pattern = ".zip", +# recursive = TRUE, +# full.names = TRUE) +# +# for (i in (1:length(zipFilesToUpload))) { +# CohortDiagnostics::uploadResults(connectionDetails = connectionDetailsToUpload, +# schema = resultsSchema, +# zipFileName = zipFilesToUpload[[i]]) +# } diff --git a/extras/tests/TestCodeRealDataWebApiMode.R b/extras/tests/TestCodeRealDataWebApiMode.R new file mode 100644 index 000000000..35c6d13cf --- /dev/null +++ b/extras/tests/TestCodeRealDataWebApiMode.R @@ -0,0 +1,146 @@ +# remotes::install_github('OHDSI/SkeletonCohortDiagnosticsStudy') + +library(CohortDiagnostics) + +temporaryLocation <- rstudioapi::getActiveProject() + +connectionSpecifications <- cdmSources %>% + dplyr::filter(sequence == 1) %>% + dplyr::filter(database == 'truven_ccae') + +dbms <- connectionSpecifications$dbms # example: 'redshift' +port <- connectionSpecifications$port # example: 2234 +server <- + connectionSpecifications$serverRHealth # example: 'fdsfd.yourdatabase.yourserver.com" +cdmDatabaseSchema <- + connectionSpecifications$cdmDatabaseSchemaRhealth # example: "cdm" +vocabDatabaseSchema <- + connectionSpecifications$vocabDatabaseSchemaRhealth # example: "vocabulary" +databaseId <- + connectionSpecifications$database # example: "truven_ccae" +userNameService = "OHDSI_USER" # example: "this is key ring service that securely stores credentials" +passwordService = "OHDSI_PASSWORD" # example: "this is key ring service that securely stores credentials" + +# cohortDatabaseSchema = paste0('scratch_', keyring::key_get(service = userNameService)) +cohortDatabaseSchema = paste0('scratch_rao_', databaseId) +# scratch - usually something like 'scratch_grao' + +connectionDetails <- DatabaseConnector::createConnectionDetails( + dbms = dbms, + user = keyring::key_get(service = userNameService), + password = keyring::key_get(service = passwordService), + port = port, + server = server +) + +cohortTable <- + paste0("s", connectionSpecifications$sourceId, "_webapi") + +library(magrittr) +# Set up +baseUrl <- Sys.getenv("baseUrl") +# list of cohort ids +cohortIds <- c(18345, 18346) + +# get specifications for the cohortIds above +webApiCohorts <- + ROhdsiWebApi::getCohortDefinitionsMetaData(baseUrl = baseUrl) %>% + dplyr::filter(.data$id %in% cohortIds) + +cohortsToCreate <- list() +for (i in (1:nrow(webApiCohorts))) { + cohortId <- webApiCohorts$id[[i]] + cohortDefinition <- + ROhdsiWebApi::getCohortDefinition(cohortId = cohortId, + baseUrl = baseUrl) + cohortsToCreate[[i]] <- tidyr::tibble( + atlasId = webApiCohorts$id[[i]], + atlasName = stringr::str_trim(string = stringr::str_squish(cohortDefinition$name)), + cohortId = webApiCohorts$id[[i]], + name = stringr::str_trim(stringr::str_squish(cohortDefinition$name)) + ) +} +cohortsToCreate <- dplyr::bind_rows(cohortsToCreate) + +readr::write_excel_csv( + x = cohortsToCreate, + na = "", + file = file.path(temporaryLocation, "CohortsToCreate.csv"), + append = FALSE +) + +outputFolder <- + file.path(temporaryLocation, + "outputFolder", + "webApiMode", + databaseId) +# Please delete previous content if needed +# unlink(x = outputFolder, +# recursive = TRUE, +# force = TRUE) +dir.create(path = outputFolder, + showWarnings = FALSE, + recursive = TRUE) + +cohortSetReference <- + readr::read_csv( + file = file.path(temporaryLocation, "CohortsToCreate.csv"), + col_types = readr::cols() + ) + +CohortDiagnostics::instantiateCohortSet( + connectionDetails = connectionDetails, + cdmDatabaseSchema = cdmDatabaseSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + baseUrl = baseUrl, + cohortSetReference = cohortSetReference, + generateInclusionStats = TRUE, + inclusionStatisticsFolder = file.path(outputFolder, + 'inclusionStatisticsFolder') +) + +CohortDiagnostics::runCohortDiagnostics( + baseUrl = baseUrl, + cohortSetReference = cohortSetReference, + connectionDetails = connectionDetails, + cdmDatabaseSchema = cdmDatabaseSchema, + cohortDatabaseSchema = cohortDatabaseSchema, + cohortTable = cohortTable, + inclusionStatisticsFolder = file.path(outputFolder, + 'inclusionStatisticsFolder'), + exportFolder = file.path(outputFolder, + 'exportFolder'), + databaseId = databaseId, + minCellCount = 5 +) + +CohortDiagnostics::preMergeDiagnosticsFiles(dataFolder = outputFolder) + +CohortDiagnostics::launchDiagnosticsExplorer(dataFolder = outputFolder) + +# +# connectionDetailsToUpload <- createConnectionDetails(dbms = "postgresql", +# server = paste(Sys.getenv("shinydbServer"), +# Sys.getenv("shinydbDatabase"), +# sep = "/"), +# port = Sys.getenv("shinydbPort"), +# user = Sys.getenv("shinyDbUserGowtham"), +# password = Sys.getenv("shinyDbPasswordGowtham")) +# +# +# resultsSchema <- "CdSkeletonCohortDiagnosticsStudy" +# CohortDiagnostics::createResultsDataModel(connectionDetails = connectionDetailsToUpload, schema = resultsSchema) +# +# +# path = outputFolder +# zipFilesToUpload <- list.files(path = path, +# pattern = ".zip", +# recursive = TRUE, +# full.names = TRUE) +# +# for (i in (1:length(zipFilesToUpload))) { +# CohortDiagnostics::uploadResults(connectionDetails = connectionDetailsToUpload, +# schema = resultsSchema, +# zipFileName = zipFilesToUpload[[i]]) +# } diff --git a/extras/tests/TestPostgresUpload.R b/extras/tests/TestPostgresUpload.R deleted file mode 100644 index 502bfd4b9..000000000 --- a/extras/tests/TestPostgresUpload.R +++ /dev/null @@ -1,64 +0,0 @@ -connectionDetails <- Eunomia::getEunomiaConnectionDetails() -cdmDatabaseSchema <- "main" -cohortDatabaseSchema <- "main" -cohortTable <- "cohort" -oracleTempSchema <- NULL -folder <- stringi::stri_rand_strings(1, 5) -unlink(x = folder, recursive = TRUE, force = TRUE) -dir.create(folder, recursive = TRUE, showWarnings = FALSE) - - -CohortDiagnostics::instantiateCohortSet(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - packageName = "CohortDiagnostics", - cohortToCreateFile = "settings/CohortsToCreateForTesting.csv", - generateInclusionStats = TRUE, - createCohortTable = TRUE, - # incremental = TRUE, - # incrementalFolder = file.path(folder, "incremental"), - inclusionStatisticsFolder = file.path(folder, "inclusionStatistics")) - -CohortDiagnostics::runCohortDiagnostics(connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - cohortDatabaseSchema = cohortDatabaseSchema, - cohortTable = cohortTable, - packageName = "CohortDiagnostics", - cohortToCreateFile = "settings/CohortsToCreateForTesting.csv", - inclusionStatisticsFolder = file.path(folder, "inclusionStatistics"), - exportFolder = file.path(folder, "export"), - databaseId = "Eunomia", - runInclusionStatistics = TRUE, - runBreakdownIndexEvents = TRUE, - runCohortCharacterization = TRUE, - runTemporalCohortCharacterization = TRUE, - runCohortOverlap = TRUE, - runIncidenceRate = TRUE, - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - runTimeDistributions = TRUE, - incremental = TRUE, - minCellCount = 10, - incrementalFolder = file.path(folder, "incremental")) - -# Enter postgres conneciton details here -connectionDetails <- DatabaseConnector::createConnectionDetails( - dbms = "postgresql", - user = "postgres", - password = "postgres", - server = "localhost/testdb", - port = 5432 -) - -connection <- DatabaseConnector::connect(connectionDetails) -schemaName <- paste0("test_schema_", stringi::stri_rand_strings(1, 5)) - - -CohortDiagnostics::buildPostgresDatabaseSchema(connectionDetails, schemaName, overwrite = TRUE) -CohortDiagnostics::importCsvFilesToPostgres(connectionDetails, schemaName, file.path(folder, "export"), winPsqlPath = "bin/") - -DatabaseConnector::disconnect(connection) -unlink(folder, recursive=TRUE) diff --git a/extras/tests/TestUsingConceptPrevalenceCounts.R b/extras/tests/TestUsingConceptPrevalenceCounts.R deleted file mode 100644 index 5e19a27fc..000000000 --- a/extras/tests/TestUsingConceptPrevalenceCounts.R +++ /dev/null @@ -1,52 +0,0 @@ -library(CohortDiagnostics) -connectionDetails <- createConnectionDetails(dbms = "pdw", - server = Sys.getenv("PDW_SERVER"), - port = Sys.getenv("PDW_PORT")) -oracleTempSchema <- NULL - -cdmDatabaseSchema <- "CDM_jmdc_v1063.dbo" -conceptCountsDatabaseSchema <- "scratch.dbo" -conceptCountsTable <- "concept_prevalence_counts" - -# Upload concept prevalence data to database ------------------------------------- - -conceptCounts <- read.table("c:/temp/conceptPrevalence/cnt_all.tsv", header = TRUE, sep = "\t") -colnames(conceptCounts) <- c("concept_id", "concept_count") -conceptCounts$concept_subjects <- conceptCounts$concept_count -conceptCounts <- conceptCounts[!is.na(conceptCounts$concept_id), ] - -connection <- DatabaseConnector::connect(connectionDetails) -DatabaseConnector::insertTable(connection = connection, - tableName = paste(conceptCountsDatabaseSchema, conceptCountsTable, sep = "."), - data = conceptCounts, - dropTableIfExists = TRUE, - createTable = TRUE, - tempTable = FALSE, - oracleTempSchema = oracleTempSchema, - progressBar = TRUE, - useMppBulkLoad = FALSE) -DatabaseConnector::disconnect(connection) - - -# Run diagnostics ----------------------------------------------- - -baseUrl <- Sys.getenv("ohdsiBaseUrl") -cohortSetReferenceFile <- file.path("exampleComparativeCohortStudy", "inst", "settings", "CohortsToCreate.csv") -cohortSetReference <- read.csv(cohortSetReferenceFile) - -runCohortDiagnosticsUsingExternalCounts(baseUrl = baseUrl, - cohortSetReference = cohortSetReference, - connectionDetails = connectionDetails, - cdmDatabaseSchema = cdmDatabaseSchema, - oracleTempSchema = oracleTempSchema, - conceptCountsDatabaseSchema = conceptCountsDatabaseSchema, - conceptCountsTable = conceptCountsTable, - exportFolder = "c:/exampleStudy/OhdsiConceptPrevalence", - databaseId = "OHDSI Concept Prevalence", - runIncludedSourceConcepts = TRUE, - runOrphanConcepts = TRUE, - minCellCount = 1) - -preMergeDiagnosticsFiles("c:/temp/exampleStudy") - -launchDiagnosticsExplorer("c:/temp/exampleStudy") diff --git a/extras/tests/testResultsDataModel.R b/extras/tests/testResultsDataModel.R deleted file mode 100644 index ad1b8603c..000000000 --- a/extras/tests/testResultsDataModel.R +++ /dev/null @@ -1,102 +0,0 @@ -cohortId <- 141933001 -targetCohortIds <- cohortId -comparatorCohortIds <- 141933003 -cohortIds <- c(targetCohortIds, comparatorCohortIds) -databaseId <- 'OPTUM_EXTENDED_DOD' -databaseIds <- c(databaseId, 'OPTUM_PANTHER') - -connection = NULL -connectionDetails = NULL -resultsDatabaseSchema = NULL -library(magrittr) - - -data <- CohortDiagnostics::getTimeDistributionResult(cohortIds = cohortIds, - databaseIds = databaseIds) -CohortDiagnostics::plotTimeDistribution(data = data, - cohortIds = c(141933001), - databaseIds = databaseIds) - - - -######################## -data <- CohortDiagnostics::getIncidenceRateResult(cohortIds = cohortIds, - stratifyByAgeGroup = FALSE, - stratifyByGender = FALSE, - stratifyByCalendarYear = TRUE, - databaseIds = databaseIds) -CohortDiagnostics::plotIncidenceRate(data = data, - stratifyByAgeGroup = FALSE, - stratifyByGender = FALSE, - stratifyByCalendarYear = TRUE) - -data <- CohortDiagnostics::getIncidenceRateResult(cohortIds = cohortIds, - stratifyByAgeGroup = TRUE, - stratifyByGender = FALSE, - stratifyByCalendarYear = TRUE, - databaseIds = databaseIds) -CohortDiagnostics::plotIncidenceRate(data = data, - stratifyByAgeGroup = TRUE, - stratifyByGender = FALSE, - stratifyByCalendarYear = TRUE) - -################# -data <- CohortDiagnostics::getCohortCountResult(databaseIds = databaseIds) - -######################## -data <- CohortDiagnostics::getCohortOverlapResult(targetCohortIds = targetCohortIds, - comparatorCohortIds = comparatorCohortIds, - databaseIds = databaseIds) -CohortDiagnostics::plotCohortOverlapVennDiagram(data = data, - targetCohortIds = targetCohortIds, - comparatorCohortIds = comparatorCohortIds, - databaseIds = databaseId) -###################### -covariateReference <- CohortDiagnostics::getCovariateReference(isTemporal = FALSE) -cohorts <- CohortDiagnostics::getCohortReference() -temporalCovariateReference <- CohortDiagnostics::getCovariateReference(isTemporal = TRUE) -timeReference <- CohortDiagnostics::getTimeReference() - - -data <- CohortDiagnostics::getCovariateValueResult(cohortIds = cohortIds, - databaseIds = databaseIds, - minProportion = 0.03, - isTemporal = FALSE) - -data <- CohortDiagnostics::compareCovariateValueResult(targetCohortIds = targetCohortIds, - comparatorCohortIds = comparatorCohortIds, - databaseIds = databaseId, - isTemporal = FALSE, - minProportion = 0) - -plot <- CohortDiagnostics::plotCohortComparisonStandardizedDifference(data = data, - targetCohortIds = targetCohortIds, - comparatorCohortIds = comparatorCohortIds, - cohortReference = cohorts, - covariateReference = covariateReference, - concept = NULL, # to subset based on domain, or vocabulary - databaseIds = 'OPTUM_EXTENDED_DOD') -plot - -data <- CohortDiagnostics::getCovariateValueResult(cohortIds = cohortIds, - databaseIds = databaseIds, - minProportion = 0.03, - isTemporal = TRUE) - -data <- CohortDiagnostics::getCovariateValueResult(cohortIds = cohortIds, - databaseIds = databaseIds, - minProportion = 0.03, - isTemporal = TRUE, - timeIds = c(1,2,3)) - - -data <- CohortDiagnostics::getConceptSetDataDiagnostics(cohortIds = cohortId, - databaseIds = databaseId) %>% - dplyr::filter(type == 'included') %>% - dplyr::inner_join(conceptSets) %>% - dplyr::inner_join(concept) %>% - dplyr::inner_join(database) %>% - dplyr::inner_join(cohort) - -View(data) - diff --git a/inst/cohorts/14906.json b/inst/cohorts/14906.json new file mode 100644 index 000000000..032e8e70d --- /dev/null +++ b/inst/cohorts/14906.json @@ -0,0 +1,67 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "DrugExposure" : { + "CodesetId" : 0, + "DrugTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 0, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "All" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "celecoxib", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 1118084, + "CONCEPT_NAME" : "celecoxib", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "140587", + "DOMAIN_ID" : "Drug", + "VOCABULARY_ID" : "RxNorm", + "CONCEPT_CLASS_ID" : "Ingredient" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "All" + }, + "InclusionRules" : [], + "EndStrategy" : { + "CustomEra" : { + "DrugCodesetId" : 0, + "GapDays" : 0, + "Offset" : 0 + } + }, + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/14907.json b/inst/cohorts/14907.json new file mode 100644 index 000000000..d8ca525b9 --- /dev/null +++ b/inst/cohorts/14907.json @@ -0,0 +1,129 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "DrugExposure" : { + "CodesetId" : 0, + "DrugTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 0, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "All" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "diclofenac", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 1124300, + "CONCEPT_NAME" : "diclofenac", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "3355", + "DOMAIN_ID" : "Drug", + "VOCABULARY_ID" : "RxNorm", + "CONCEPT_CLASS_ID" : "Ingredient" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + }, + { + "id" : 1, + "name" : "Gastrointestinal hemorrhage", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 192671, + "CONCEPT_NAME" : "Gastrointestinal hemorrhage", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "74474003", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [ + { + "name" : "With no history of gastrointestinal hemorrhage", + "expression" : { + "Type" : "ALL", + "CriteriaList" : [ + { + "Criteria" : { + "ConditionOccurrence" : { + "CodesetId" : 1, + "ConditionTypeExclude" : false + } + }, + "StartWindow" : { + "Start" : { + "Coeff" : -1 + }, + "End" : { + "Days" : 0, + "Coeff" : -1 + }, + "UseIndexEnd" : false, + "UseEventEnd" : false + }, + "RestrictVisit" : false, + "IgnoreObservationPeriod" : false, + "Occurrence" : { + "Type" : 0, + "Count" : 0, + "IsDistinct" : false + } + } + ], + "DemographicCriteriaList" : [], + "Groups" : [] + } + } + ], + "EndStrategy" : { + "CustomEra" : { + "DrugCodesetId" : 0, + "GapDays" : 30, + "Offset" : 0 + } + }, + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/14909.json b/inst/cohorts/14909.json new file mode 100644 index 000000000..3c054d921 --- /dev/null +++ b/inst/cohorts/14909.json @@ -0,0 +1,60 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "ConditionOccurrence" : { + "CodesetId" : 0, + "ConditionTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 0, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "All" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "Gastrointestinal hemorrhage ConceptSet", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 192671, + "CONCEPT_NAME" : "Gastrointestinal hemorrhage", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "74474003", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "All" + }, + "InclusionRules" : [], + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/17492.json b/inst/cohorts/17492.json new file mode 100644 index 000000000..563d3f288 --- /dev/null +++ b/inst/cohorts/17492.json @@ -0,0 +1,61 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "ConditionOccurrence" : { + "CodesetId" : 0, + "First" : true, + "ConditionTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 0, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "First" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "Gastrointestinal hemorrhage", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 192671, + "CONCEPT_NAME" : "Gastrointestinal hemorrhage", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "74474003", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [], + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/17493.json b/inst/cohorts/17493.json new file mode 100644 index 000000000..a4c1d1118 --- /dev/null +++ b/inst/cohorts/17493.json @@ -0,0 +1,61 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "ConditionOccurrence" : { + "CodesetId" : 0, + "First" : true, + "ConditionTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 365, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "First" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "Gastrointestinal hemorrhage", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 192671, + "CONCEPT_NAME" : "Gastrointestinal hemorrhage", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "74474003", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [], + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/examplePhenotypeLibraryPackage/inst/cohorts/27918002.json b/inst/cohorts/17692.json similarity index 87% rename from examplePhenotypeLibraryPackage/inst/cohorts/27918002.json rename to inst/cohorts/17692.json index 0ad495b1d..278127057 100644 --- a/examplePhenotypeLibraryPackage/inst/cohorts/27918002.json +++ b/inst/cohorts/17692.json @@ -21,18 +21,18 @@ "ConceptSets" : [ { "id" : 0, - "name" : "Eosinophilic esophagitis", + "name" : "Type 1 diabetes mellitus", "expression" : { "items" : [ { "concept" : { - "CONCEPT_ID" : 27918, - "CONCEPT_NAME" : "Eosinophilic esophagitis", + "CONCEPT_ID" : 201254, + "CONCEPT_NAME" : "Type 1 diabetes mellitus", "STANDARD_CONCEPT" : "S", "STANDARD_CONCEPT_CAPTION" : "Standard", "INVALID_REASON" : "V", "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "235599003", + "CONCEPT_CODE" : "46635009", "DOMAIN_ID" : "Condition", "VOCABULARY_ID" : "SNOMED", "CONCEPT_CLASS_ID" : "Clinical Finding" diff --git a/examplePhenotypeLibraryPackage/inst/cohorts/80182001.json b/inst/cohorts/17693.json similarity index 87% rename from examplePhenotypeLibraryPackage/inst/cohorts/80182001.json rename to inst/cohorts/17693.json index 9aadb849a..93a6e2c07 100644 --- a/examplePhenotypeLibraryPackage/inst/cohorts/80182001.json +++ b/inst/cohorts/17693.json @@ -21,18 +21,18 @@ "ConceptSets" : [ { "id" : 0, - "name" : "Dermatomyositis", + "name" : "Type 1 diabetes mellitus", "expression" : { "items" : [ { "concept" : { - "CONCEPT_ID" : 80182, - "CONCEPT_NAME" : "Dermatomyositis", + "CONCEPT_ID" : 201254, + "CONCEPT_NAME" : "Type 1 diabetes mellitus", "STANDARD_CONCEPT" : "S", "STANDARD_CONCEPT_CAPTION" : "Standard", "INVALID_REASON" : "V", "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "396230008", + "CONCEPT_CODE" : "46635009", "DOMAIN_ID" : "Condition", "VOCABULARY_ID" : "SNOMED", "CONCEPT_CLASS_ID" : "Clinical Finding" diff --git a/examplePhenotypeLibraryPackage/inst/cohorts/80182002.json b/inst/cohorts/17694.json similarity index 87% rename from examplePhenotypeLibraryPackage/inst/cohorts/80182002.json rename to inst/cohorts/17694.json index 7f43f3b26..e5aa85c03 100644 --- a/examplePhenotypeLibraryPackage/inst/cohorts/80182002.json +++ b/inst/cohorts/17694.json @@ -21,18 +21,18 @@ "ConceptSets" : [ { "id" : 0, - "name" : "Dermatomyositis", + "name" : "Type 2 diabetes mellitus", "expression" : { "items" : [ { "concept" : { - "CONCEPT_ID" : 80182, - "CONCEPT_NAME" : "Dermatomyositis", + "CONCEPT_ID" : 201826, + "CONCEPT_NAME" : "Type 2 diabetes mellitus", "STANDARD_CONCEPT" : "S", "STANDARD_CONCEPT_CAPTION" : "Standard", "INVALID_REASON" : "V", "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "396230008", + "CONCEPT_CODE" : "44054006", "DOMAIN_ID" : "Condition", "VOCABULARY_ID" : "SNOMED", "CONCEPT_CLASS_ID" : "Clinical Finding" diff --git a/examplePhenotypeLibraryPackage/inst/cohorts/27918001.json b/inst/cohorts/17695.json similarity index 87% rename from examplePhenotypeLibraryPackage/inst/cohorts/27918001.json rename to inst/cohorts/17695.json index 63b7b4bf6..b80824f49 100644 --- a/examplePhenotypeLibraryPackage/inst/cohorts/27918001.json +++ b/inst/cohorts/17695.json @@ -21,18 +21,18 @@ "ConceptSets" : [ { "id" : 0, - "name" : "Eosinophilic esophagitis", + "name" : "Type 2 diabetes mellitus", "expression" : { "items" : [ { "concept" : { - "CONCEPT_ID" : 27918, - "CONCEPT_NAME" : "Eosinophilic esophagitis", + "CONCEPT_ID" : 201826, + "CONCEPT_NAME" : "Type 2 diabetes mellitus", "STANDARD_CONCEPT" : "S", "STANDARD_CONCEPT_CAPTION" : "Standard", "INVALID_REASON" : "V", "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "235599003", + "CONCEPT_CODE" : "44054006", "DOMAIN_ID" : "Condition", "VOCABULARY_ID" : "SNOMED", "CONCEPT_CLASS_ID" : "Clinical Finding" diff --git a/inst/cohorts/17720.json b/inst/cohorts/17720.json new file mode 100644 index 000000000..0e6e6ffc7 --- /dev/null +++ b/inst/cohorts/17720.json @@ -0,0 +1,244 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "ConditionOccurrence" : { + "CodesetId" : 0, + "ConditionTypeExclude" : false + } + }, + { + "Observation" : { + "CodesetId" : 1, + "ObservationTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 0, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "First" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "Type 2 Diabetes Mellitus", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 201820, + "CONCEPT_NAME" : "Diabetes mellitus", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "73211009", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + }, + { + "concept" : { + "CONCEPT_ID" : 442793, + "CONCEPT_NAME" : "Complication due to diabetes mellitus", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "74627003", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + }, + { + "concept" : { + "CONCEPT_ID" : 443238, + "CONCEPT_NAME" : "Diabetic - poor control", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "268519009", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + }, + { + "concept" : { + "CONCEPT_ID" : 201254, + "CONCEPT_NAME" : "Type 1 diabetes mellitus", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "46635009", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : true, + "includeDescendants" : true, + "includeMapped" : false + }, + { + "concept" : { + "CONCEPT_ID" : 4058243, + "CONCEPT_NAME" : "Diabetes mellitus during pregnancy, childbirth and the puerperium", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "199223000", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : true, + "includeDescendants" : true, + "includeMapped" : false + }, + { + "concept" : { + "CONCEPT_ID" : 435216, + "CONCEPT_NAME" : "Disorder due to type 1 diabetes mellitus", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "420868002", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : true, + "includeDescendants" : true, + "includeMapped" : false + }, + { + "concept" : { + "CONCEPT_ID" : 40484648, + "CONCEPT_NAME" : "Type 1 diabetes mellitus uncontrolled", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "444073006", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : true, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + }, + { + "id" : 1, + "name" : "History of diabetes", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 40769338, + "CONCEPT_NAME" : "History of Diabetes (regardless of treatment) [PhenX]", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "66678-4", + "DOMAIN_ID" : "Observation", + "VOCABULARY_ID" : "LOINC", + "CONCEPT_CLASS_ID" : "Clinical Observation" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + }, + { + "concept" : { + "CONCEPT_ID" : 43021173, + "CONCEPT_NAME" : "History of diabetes mellitus type 2", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "472969004", + "DOMAIN_ID" : "Observation", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Context-dependent" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + }, + { + "concept" : { + "CONCEPT_ID" : 42539022, + "CONCEPT_NAME" : "History of diabetes related lower limb amputation", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "735199000", + "DOMAIN_ID" : "Observation", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Context-dependent" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + }, + { + "concept" : { + "CONCEPT_ID" : 46270562, + "CONCEPT_NAME" : "History of small vessel disease due to diabetes mellitus", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "59801000119102", + "DOMAIN_ID" : "Observation", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Context-dependent" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [], + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/18342.json b/inst/cohorts/18342.json new file mode 100644 index 000000000..53e7b8d81 --- /dev/null +++ b/inst/cohorts/18342.json @@ -0,0 +1,61 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "ConditionOccurrence" : { + "CodesetId" : 0, + "First" : true, + "ConditionTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 0, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "First" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "Gastrointestinal hemorrhage ConceptSet", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 192671, + "CONCEPT_NAME" : "Gastrointestinal hemorrhage", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "74474003", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [], + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/18345.json b/inst/cohorts/18345.json new file mode 100644 index 000000000..b28d3ed43 --- /dev/null +++ b/inst/cohorts/18345.json @@ -0,0 +1,68 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "DrugExposure" : { + "CodesetId" : 0, + "First" : true, + "DrugTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 365, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "First" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "celecoxib", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 1118084, + "CONCEPT_NAME" : "celecoxib", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "140587", + "DOMAIN_ID" : "Drug", + "VOCABULARY_ID" : "RxNorm", + "CONCEPT_CLASS_ID" : "Ingredient" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [], + "EndStrategy" : { + "CustomEra" : { + "DrugCodesetId" : 0, + "GapDays" : 0, + "Offset" : 0 + } + }, + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/18346.json b/inst/cohorts/18346.json new file mode 100644 index 000000000..ff47eccf6 --- /dev/null +++ b/inst/cohorts/18346.json @@ -0,0 +1,68 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "DrugExposure" : { + "CodesetId" : 0, + "First" : true, + "DrugTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 0, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "First" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "celecoxib", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 1118084, + "CONCEPT_NAME" : "celecoxib", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "140587", + "DOMAIN_ID" : "Drug", + "VOCABULARY_ID" : "RxNorm", + "CONCEPT_CLASS_ID" : "Ingredient" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [], + "EndStrategy" : { + "CustomEra" : { + "DrugCodesetId" : 0, + "GapDays" : 0, + "Offset" : 0 + } + }, + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/18347.json b/inst/cohorts/18347.json new file mode 100644 index 000000000..ecf1d686f --- /dev/null +++ b/inst/cohorts/18347.json @@ -0,0 +1,68 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "DrugExposure" : { + "CodesetId" : 0, + "First" : true, + "DrugTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 0, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "First" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "diclofenac", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 1124300, + "CONCEPT_NAME" : "diclofenac", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "3355", + "DOMAIN_ID" : "Drug", + "VOCABULARY_ID" : "RxNorm", + "CONCEPT_CLASS_ID" : "Ingredient" + }, + "isExcluded" : false, + "includeDescendants" : false, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [], + "EndStrategy" : { + "CustomEra" : { + "DrugCodesetId" : 0, + "GapDays" : 0, + "Offset" : 0 + } + }, + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/18348.json b/inst/cohorts/18348.json new file mode 100644 index 000000000..251d74913 --- /dev/null +++ b/inst/cohorts/18348.json @@ -0,0 +1,68 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "DrugExposure" : { + "CodesetId" : 0, + "First" : true, + "DrugTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 365, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "First" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "diclofenac", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 1124300, + "CONCEPT_NAME" : "diclofenac", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "3355", + "DOMAIN_ID" : "Drug", + "VOCABULARY_ID" : "RxNorm", + "CONCEPT_CLASS_ID" : "Ingredient" + }, + "isExcluded" : false, + "includeDescendants" : false, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [], + "EndStrategy" : { + "CustomEra" : { + "DrugCodesetId" : 0, + "GapDays" : 0, + "Offset" : 0 + } + }, + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/18349.json b/inst/cohorts/18349.json new file mode 100644 index 000000000..30f1449c2 --- /dev/null +++ b/inst/cohorts/18349.json @@ -0,0 +1,94 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "DrugExposure" : { + "CodesetId" : 0, + "DrugTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 365, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "First" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "diclofenac", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 1124300, + "CONCEPT_NAME" : "diclofenac", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "3355", + "DOMAIN_ID" : "Drug", + "VOCABULARY_ID" : "RxNorm", + "CONCEPT_CLASS_ID" : "Ingredient" + }, + "isExcluded" : false, + "includeDescendants" : false, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [ + { + "name" : "Gender is male", + "expression" : { + "Type" : "ALL", + "CriteriaList" : [], + "DemographicCriteriaList" : [ + { + "Gender" : [ + { + "CONCEPT_ID" : 8507, + "CONCEPT_NAME" : "MALE", + "STANDARD_CONCEPT" : null, + "STANDARD_CONCEPT_CAPTION" : "Unknown", + "INVALID_REASON" : null, + "INVALID_REASON_CAPTION" : "Unknown", + "CONCEPT_CODE" : "M", + "DOMAIN_ID" : "Gender", + "VOCABULARY_ID" : "Gender", + "CONCEPT_CLASS_ID" : null + } + ] + } + ], + "Groups" : [] + } + } + ], + "EndStrategy" : { + "CustomEra" : { + "DrugCodesetId" : 0, + "GapDays" : 0, + "Offset" : 0 + } + }, + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/18350.json b/inst/cohorts/18350.json new file mode 100644 index 000000000..c9c36eed9 --- /dev/null +++ b/inst/cohorts/18350.json @@ -0,0 +1,153 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "DrugExposure" : { + "CodesetId" : 0, + "DrugTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 365, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "First" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "diclofenac", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 1124300, + "CONCEPT_NAME" : "diclofenac", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "3355", + "DOMAIN_ID" : "Drug", + "VOCABULARY_ID" : "RxNorm", + "CONCEPT_CLASS_ID" : "Ingredient" + }, + "isExcluded" : false, + "includeDescendants" : false, + "includeMapped" : false + } + ] + } + }, + { + "id" : 1, + "name" : "Disorder of body system", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 4180628, + "CONCEPT_NAME" : "Disorder of body system", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "362965005", + "DOMAIN_ID" : "Condition", + "VOCABULARY_ID" : "SNOMED", + "CONCEPT_CLASS_ID" : "Clinical Finding" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [ + { + "name" : "Gender is male", + "expression" : { + "Type" : "ALL", + "CriteriaList" : [], + "DemographicCriteriaList" : [ + { + "Gender" : [ + { + "CONCEPT_ID" : 8507, + "CONCEPT_NAME" : "MALE", + "STANDARD_CONCEPT" : null, + "STANDARD_CONCEPT_CAPTION" : "Unknown", + "INVALID_REASON" : null, + "INVALID_REASON_CAPTION" : "Unknown", + "CONCEPT_CODE" : "M", + "DOMAIN_ID" : "Gender", + "VOCABULARY_ID" : "Gender", + "CONCEPT_CLASS_ID" : null + } + ] + } + ], + "Groups" : [] + } + }, + { + "name" : "Metabolic disease at any time", + "expression" : { + "Type" : "ALL", + "CriteriaList" : [ + { + "Criteria" : { + "ConditionOccurrence" : { + "ConditionTypeExclude" : false + } + }, + "StartWindow" : { + "Start" : { + "Coeff" : -1 + }, + "End" : { + "Coeff" : 1 + }, + "UseIndexEnd" : false, + "UseEventEnd" : false + }, + "RestrictVisit" : false, + "IgnoreObservationPeriod" : false, + "Occurrence" : { + "Type" : 2, + "Count" : 1, + "IsDistinct" : false + } + } + ], + "DemographicCriteriaList" : [], + "Groups" : [] + } + } + ], + "EndStrategy" : { + "CustomEra" : { + "DrugCodesetId" : 0, + "GapDays" : 0, + "Offset" : 0 + } + }, + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/18351.json b/inst/cohorts/18351.json new file mode 100644 index 000000000..573249cb7 --- /dev/null +++ b/inst/cohorts/18351.json @@ -0,0 +1,100 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "DrugExposure" : { + "CorrelatedCriteria" : { + "Type" : "ALL", + "CriteriaList" : [ + { + "Criteria" : { + "DrugExposure" : { + "CodesetId" : 0, + "DrugTypeExclude" : false + } + }, + "StartWindow" : { + "Start" : { + "Coeff" : -1 + }, + "End" : { + "Days" : 1, + "Coeff" : -1 + }, + "UseIndexEnd" : false, + "UseEventEnd" : false + }, + "RestrictVisit" : false, + "IgnoreObservationPeriod" : false, + "Occurrence" : { + "Type" : 0, + "Count" : 1, + "IsDistinct" : false + } + } + ], + "DemographicCriteriaList" : [], + "Groups" : [] + }, + "CodesetId" : 0, + "DrugTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 0, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "All" + } + }, + "ConceptSets" : [ + { + "id" : 0, + "name" : "celecoxib", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 1118084, + "CONCEPT_NAME" : "celecoxib", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "140587", + "DOMAIN_ID" : "Drug", + "VOCABULARY_ID" : "RxNorm", + "CONCEPT_CLASS_ID" : "Ingredient" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + } + ], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "All" + }, + "InclusionRules" : [], + "EndStrategy" : { + "CustomEra" : { + "DrugCodesetId" : 0, + "GapDays" : 0, + "Offset" : 0 + } + }, + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/examplePhenotypeLibraryPackage/inst/cohorts/27918004.json b/inst/cohorts/18352.json similarity index 57% rename from examplePhenotypeLibraryPackage/inst/cohorts/27918004.json rename to inst/cohorts/18352.json index 4ed2a62e7..5049a693a 100644 --- a/examplePhenotypeLibraryPackage/inst/cohorts/27918004.json +++ b/inst/cohorts/18352.json @@ -3,36 +3,60 @@ "PrimaryCriteria" : { "CriteriaList" : [ { - "ConditionOccurrence" : { + "DrugExposure" : { "CodesetId" : 0, - "First" : true, - "ConditionTypeExclude" : false + "DrugTypeExclude" : false } } ], "ObservationWindow" : { - "PriorDays" : 365, + "PriorDays" : 0, "PostDays" : 0 }, "PrimaryCriteriaLimit" : { - "Type" : "First" + "Type" : "All" } }, "ConceptSets" : [ { "id" : 0, - "name" : "Eosinophilic esophagitis", + "name" : "diclofenac", "expression" : { "items" : [ { "concept" : { - "CONCEPT_ID" : 27918, - "CONCEPT_NAME" : "Eosinophilic esophagitis", + "CONCEPT_ID" : 1124300, + "CONCEPT_NAME" : "diclofenac", "STANDARD_CONCEPT" : "S", "STANDARD_CONCEPT_CAPTION" : "Standard", "INVALID_REASON" : "V", "INVALID_REASON_CAPTION" : "Valid", - "CONCEPT_CODE" : "235599003", + "CONCEPT_CODE" : "3355", + "DOMAIN_ID" : "Drug", + "VOCABULARY_ID" : "RxNorm", + "CONCEPT_CLASS_ID" : "Ingredient" + }, + "isExcluded" : false, + "includeDescendants" : true, + "includeMapped" : false + } + ] + } + }, + { + "id" : 1, + "name" : "Gastrointestinal hemorrhage", + "expression" : { + "items" : [ + { + "concept" : { + "CONCEPT_ID" : 192671, + "CONCEPT_NAME" : "Gastrointestinal hemorrhage", + "STANDARD_CONCEPT" : "S", + "STANDARD_CONCEPT_CAPTION" : "Standard", + "INVALID_REASON" : "V", + "INVALID_REASON_CAPTION" : "Valid", + "CONCEPT_CODE" : "74474003", "DOMAIN_ID" : "Condition", "VOCABULARY_ID" : "SNOMED", "CONCEPT_CLASS_ID" : "Clinical Finding" @@ -49,29 +73,28 @@ "Type" : "First" }, "ExpressionLimit" : { - "Type" : "First" + "Type" : "All" }, "InclusionRules" : [ { - "name" : "Second occurrence of Eosinophilic esophagitis", + "name" : "With gastrointestinal hemorrhage at some point", "expression" : { "Type" : "ALL", "CriteriaList" : [ { "Criteria" : { "ConditionOccurrence" : { - "CodesetId" : 0, + "CodesetId" : 1, "ConditionTypeExclude" : false } }, "StartWindow" : { "Start" : { - "Days" : 1, - "Coeff" : 1 + "Coeff" : -1 }, "End" : { - "Days" : 730, - "Coeff" : 1 + "Days" : 0, + "Coeff" : -1 }, "UseIndexEnd" : false, "UseEventEnd" : false @@ -90,6 +113,13 @@ } } ], + "EndStrategy" : { + "CustomEra" : { + "DrugCodesetId" : 0, + "GapDays" : 30, + "Offset" : 0 + } + }, "CensoringCriteria" : [], "CollapseSettings" : { "CollapseType" : "ERA", diff --git a/inst/cohorts/21402.json b/inst/cohorts/21402.json new file mode 100644 index 000000000..ef03d4017 --- /dev/null +++ b/inst/cohorts/21402.json @@ -0,0 +1,38 @@ +{ + "cdmVersionRange" : ">=5.0.0", + "PrimaryCriteria" : { + "CriteriaList" : [ + { + "VisitOccurrence" : { + "OccurrenceStartDate" : { + "Value" : "2005-01-01", + "Op" : "bt", + "Extent" : "2020-12-31" + }, + "VisitTypeExclude" : false + } + } + ], + "ObservationWindow" : { + "PriorDays" : 365, + "PostDays" : 0 + }, + "PrimaryCriteriaLimit" : { + "Type" : "All" + } + }, + "ConceptSets" : [], + "QualifiedLimit" : { + "Type" : "First" + }, + "ExpressionLimit" : { + "Type" : "First" + }, + "InclusionRules" : [], + "CensoringCriteria" : [], + "CollapseSettings" : { + "CollapseType" : "ERA", + "EraPad" : 0 + }, + "CensorWindow" : {} +} \ No newline at end of file diff --git a/inst/cohorts/InclusionRules.csv b/inst/cohorts/InclusionRules.csv new file mode 100644 index 000000000..16617a9c2 --- /dev/null +++ b/inst/cohorts/InclusionRules.csv @@ -0,0 +1,6 @@ +cohortName,ruleSequence,ruleName,cohortId +14907,0,With no history of gastrointestinal hemorrhage,14907 +18349,0,Gender is male,18349 +18350,0,Gender is male,18350 +18350,1,Metabolic disease at any time,18350 +18352,0,With gastrointestinal hemorrhage at some point,18352 diff --git a/inst/csv/domains.csv b/inst/csv/domains.csv index e3e7440fa..92042531c 100644 --- a/inst/csv/domains.csv +++ b/inst/csv/domains.csv @@ -1,8 +1,8 @@ domain,domainTable,domainStartDate,domainConceptId,domainSourceValue,domainSourceConceptId DrugExposure,drug_exposure,drug_exposure_start_date,drug_concept_id,drug_source_value,drug_source_concept_id -DrugEra,drug_era,drug_era_start_date,drug_concept_id,drug_source_value,drug_source_concept_id +DrugEra,drug_era,drug_era_start_date,drug_concept_id,, ConditionOccurrence,condition_occurrence,condition_start_date,condition_concept_id,condition_source_value,condition_source_concept_id -ConditionEra,condition_era,condition_era_start_date,condition_concept_id,condition_source_value,condition_source_concept_id +ConditionEra,condition_era,condition_era_start_date,condition_concept_id,, ProcedureOccurrence,procedure_occurrence,procedure_date,procedure_concept_id,procedure_source_value,procedure_source_concept_id DeviceExposure,device_exposure,device_exposure_start_date,device_concept_id,device_source_value,device_source_concept_id Measurement,measurement,measurement_date,measurement_concept_id,measurement_source_value,measurement_source_concept_id diff --git a/inst/doc/CohortDiagnosticsInPackageMode.pdf b/inst/doc/CohortDiagnosticsInPackageMode.pdf new file mode 100644 index 000000000..7b3eaa2b8 Binary files /dev/null and b/inst/doc/CohortDiagnosticsInPackageMode.pdf differ diff --git a/inst/doc/CohortDiagnosticsUsingWebApi.pdf b/inst/doc/CohortDiagnosticsUsingWebApi.pdf index 7d6491014..53bc8d4b7 100644 Binary files a/inst/doc/CohortDiagnosticsUsingWebApi.pdf and b/inst/doc/CohortDiagnosticsUsingWebApi.pdf differ diff --git a/inst/doc/DatabaseModeInDiagnosticsExplorer.pdf b/inst/doc/DatabaseModeInDiagnosticsExplorer.pdf new file mode 100644 index 000000000..1806612b8 Binary files /dev/null and b/inst/doc/DatabaseModeInDiagnosticsExplorer.pdf differ diff --git a/inst/doc/RunningCohortDiagnostics.pdf b/inst/doc/RunningCohortDiagnostics.pdf new file mode 100644 index 000000000..36987150b Binary files /dev/null and b/inst/doc/RunningCohortDiagnostics.pdf differ diff --git a/inst/doc/ViewingResultsUsingDiagnosticsExplorer.pdf b/inst/doc/ViewingResultsUsingDiagnosticsExplorer.pdf new file mode 100644 index 000000000..50636b268 Binary files /dev/null and b/inst/doc/ViewingResultsUsingDiagnosticsExplorer.pdf differ diff --git a/inst/doc/WhatIsCohortDiagnostics.pdf b/inst/doc/WhatIsCohortDiagnostics.pdf new file mode 100644 index 000000000..995bcc339 Binary files /dev/null and b/inst/doc/WhatIsCohortDiagnostics.pdf differ diff --git a/inst/settings/CohortsToCreateForTesting.csv b/inst/settings/CohortsToCreateForTesting.csv index 476bbfc42..b9324ce70 100644 --- a/inst/settings/CohortsToCreateForTesting.csv +++ b/inst/settings/CohortsToCreateForTesting.csv @@ -1,20 +1,21 @@ -referentConceptId,cohortId,webApiCohortId,cohortName,logicDescription, clinicalRationale -1118084,1118084001,18345,Celecoxib referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,"Persons with drug exposure of referent concept (1118084) or descendants, for the first time in the persons history, with at least 365 days of prior continuous observation. Persons exit cohort at the end of continuous drug exposure.",referent cohort (incident) -1118084,1118084002,18346,Celecoxib referent concept prevalent cohort: First occurrence of referent concept + descendants,"Persons with drug exposure of referent concept (1118084) or descendants, for the first time in the persons history. Persons exit cohort at the end of continuous drug exposure.",referent cohort (prevalence) -1118084,1118084003,14906,"Celecoxib, all dispensations",All dispensations of Celecoxib with exit on continuous drug exposure,To help understand the periods of continous use of Celecoxib -1118084,1118084004,18351,"[1118084004] Second dispensation of Celecoxib, till end of drug continuous coverage for second dispensation",Second dispensations of Celecoxib with exit on continuous drug exposure,To study if repeat users of celecoxib have a different pattern of continuous use compared to first time users of Celecoxib -1124300,1124300001,18347,Diclofenac referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,"Persons with drug exposure of referent concept (1124300) or descendants, for the first time in the persons history, with at least 365 days of prior continuous observation. Persons exit cohort at the end of continuous drug exposure.",referent cohort (incident) -1124300,1124300002,18348,Diclofenac referent concept prevalent cohort: First occurrence of referent concept + descendants,"Persons with drug exposure of referent concept (1124300) or descendants, for the first time in the persons history. Persons exit cohort at the end of continuous drug exposure.",referent cohort (prevalence) -1124300,1124300003,14907,Users of diclofenac with no history of gastrointestinal hemorrhage,"All events of diclofenac exposure, with inclusion criteria of no gastrointestinal hemorrhage at any time in past. Cohort exit at continous exposure of diclofenac with 30 days of persistence window",These diclofenac users never had a history of GI hemorrhage -1124300,1124300004,18349,Male Diclofenac,First time new users of Diclofenac who are Male, -1124300,1124300005,18350,Male Diclofenac with body system disorder,First time new users of Diclofenac who are Male with some body system disorder at any time, -1124300,1124300006,18352,Users of diclofenac with history of gastrointestinal hemorrhage,"All events of diclofenac exposure, with inclusion criteria of gastrointestinal hemorrhage at any time in past. Cohort exit at continous exposure of diclofenac with 30 days of persistence window",These diclofenac users had a history of GI hemorrhage -192671,192671001,17493,[PL 192671001] Gastrointestinal hemorrhage referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,"Persons with condition occurrence of referent concept (192671) or descendants, for the first time in the persons history, with at least 365 days of prior continuous observation. Persons exit cohort at the end of the observation period.",referent cohort (incident) -192671,192671002,17492,[PL 192671002] Gastrointestinal hemorrhage referent concept prevalent cohort: First occurrence of referent concept + descendants,"Persons with condition occurrence of referent concept (192671) or descendants, for the first time in the persons history. Persons exit cohort at the end of the observation period.",referent cohort (prevalence) -192671,192671003,14909,All Gastrointestinal hemorrhage,All events of Gastrointestinal hemorrhage, -192671,192671004,18342,First Gastrointestinal hemorrhage,First event of Gastrointestinal hemorrhage, -201254,201254001,17693,Type 1 diabetes mellitus referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,"Persons with condition occurrence of referent concept (201254) or descendants, for the first time in the person's history, with at least 365 days of prior continuous observation. Persons exit cohort at the end of the observation period.", -201254,201254002,17692,Type 1 diabetes mellitus referent concept prevalent cohort: First occurrence of referent concept + descendants,"Persons with condition occurrence of referent concept (201254) or descendants, for the first time in the person's history. Persons exit cohort at the end of the observation period.", -201826,201826001,17695,Type 2 diabetes mellitus referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,"Persons with condition occurrence of referent concept (201826) or descendants, for the first time in the person's history, with at least 365 days of prior continuous observation. Persons exit cohort at the end of the observation period.", -201826,201826002,17694,Type 2 diabetes mellitus referent concept prevalent cohort: First occurrence of referent concept + descendants,"Persons with condition occurrence of referent concept (201826) or descendants, for the first time in the person's history. Persons exit cohort at the end of the observation period.", -201826,201826003,17720,Type 2 diabetes mellitus prevalent cohort: First condition occurrence of 'Type 2 diabetes mellitus' conceptset or observation of 'History of diabetes',Persons with a condition occurrence of 'Type 2 diabetes mellitus' conceptset or an observation of 'History of diabetes' at earliest entry event. Persons exit cohort at end of observation period, +atlasId,referentConceptId,webApiCohortId,cohortId,name,cohortName,logicDescription,phenotypeId +17492,192671,17492,17492,17492,[PL 192671002] Gastrointestinal hemorrhage referent concept prevalent cohort: First occurrence of referent concept + descendants,[PL 192671002] Gastrointestinal hemorrhage referent concept prevalent cohort: First occurrence of referent concept + descendants,192671000 +17493,192671,17493,17493,17493,[PL 192671001] Gastrointestinal hemorrhage referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,[PL 192671001] Gastrointestinal hemorrhage referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,192671000 +17692,201254,17692,17692,17692,[PL 201254002] Type 1 diabetes mellitus referent concept prevalent cohort: First occurrence of referent concept + descendants,[PL 201254002] Type 1 diabetes mellitus referent concept prevalent cohort: First occurrence of referent concept + descendants,201820000 +17693,201254,17693,17693,17693,[PL 201254001] Type 1 diabetes mellitus referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,[PL 201254001] Type 1 diabetes mellitus referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,201820000 +17694,201826,17694,17694,17694,[PL 201826002] Type 2 diabetes mellitus referent concept prevalent cohort: First occurrence of referent concept + descendants,[PL 201826002] Type 2 diabetes mellitus referent concept prevalent cohort: First occurrence of referent concept + descendants,201820000 +17720,201826,17720,17720,17720,[PL 201826003] Type 2 diabetes mellitus prevalent cohort: First condition occurrence of 'Type 2 diabetes mellitus' conceptset or observation of 'History of diabetes',[PL 201826003] Type 2 diabetes mellitus prevalent cohort: First condition occurrence of 'Type 2 diabetes mellitus' conceptset or observation of 'History of diabetes',201820000 +17695,201826,17695,17695,17695,[PL 201826001] Type 2 diabetes mellitus referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,[PL 201826001] Type 2 diabetes mellitus referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,201820000 +14909,192671,14909,14909,14909,[Cohort Diagnostics] Gastrointestinal hemorrhage for Eunomia,[Cohort Diagnostics] Gastrointestinal hemorrhage for Eunomia,192671000 +18342,192671,18342,18342,18342,"[Cohort Diagnostics] Gastrointestinal hemorrhage for Eunomia, first time in persons history","[Cohort Diagnostics] Gastrointestinal hemorrhage for Eunomia, first time in persons history",192671000 +18345,1118084,18345,18345,18345,[1118084001] Celecoxib referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,[1118084001] Celecoxib referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,0 +18346,1118084,18346,18346,18346,[1118084002] Celecoxib referent concept incident cohort: First occurrence of referent concept + descendants,[1118084002] Celecoxib referent concept incident cohort: First occurrence of referent concept + descendants,0 +18347,1124300,18347,18347,18347,[1124300002] Diclofenac referent concept incident cohort: First occurrence of referent concept + descendants,[1124300002] Diclofenac referent concept incident cohort: First occurrence of referent concept + descendants,0 +18348,1124300,18348,18348,18348,[1124300001] Diclofenac referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,[1124300001] Diclofenac referent concept incident cohort: First occurrence of referent concept + descendants with >=365d prior observation,0 +18349,1124300,18349,18349,18349,[1124300004] Male Diclofenac,[1124300004] Male Diclofenac,0 +18350,1124300,18350,18350,18350,[1124300005] Male Diclofenac with some disorder or body system,[1124300005] Male Diclofenac with some disorder or body system,0 +14906,1118084,14906,14906,14906,"[1118084003] All users of Celecoxis, till end of drug continuous coverage","[1118084003] All users of Celecoxis, till end of drug continuous coverage",0 +18351,0,18351,18351,18351,"[1118084004] Second dispensation of Celecoxib, till end of drug continuous coverage for second dispensation","[1118084004] Second dispensation of Celecoxib, till end of drug continuous coverage for second dispensation",0 +14907,0,14907,14907,14907,[1124300003] Users of diclofenac with no history of gastrointestinal hemorrhage,[1124300003] Users of diclofenac with no history of gastrointestinal hemorrhage,0 +18352,0,18352,18352,18352,[1124300006] Users of diclofenac with history of gastrointestinal hemorrhage,[1124300006] Users of diclofenac with history of gastrointestinal hemorrhage,0 +21402,0,21402,21402,21402,Eunomia Persons at risk at first encounter,Eunomia Persons at risk at first encounter,0 diff --git a/inst/settings/CohortsToInstantiate.csv b/inst/settings/CohortsToInstantiate.csv deleted file mode 100644 index f16a6309a..000000000 --- a/inst/settings/CohortsToInstantiate.csv +++ /dev/null @@ -1,20 +0,0 @@ -atlasId,cohortId,name -18345,1118084001,1118084001 -18346,1118084002,1118084002 -14906,1118084003,1118084003 -18351,1118084004,1118084004 -18347,1124300001,1124300001 -18348,1124300002,1124300002 -14907,1124300003,1124300003 -18349,1124300004,1124300004 -18350,1124300005,1124300005 -18352,1124300006,1124300006 -17493,192671001,192671001 -17492,192671002,192671002 -14909,192671003,192671003 -18342,192671004,192671004 -17693,201254001,201254001 -17692,201254002,201254002 -17695,201826001,201826001 -17694,201826002,201826002 -17720,201826003,201826003 diff --git a/inst/settings/phenotypeDescription.csv b/inst/settings/phenotypeDescription.csv new file mode 100644 index 000000000..7a7c0ea00 --- /dev/null +++ b/inst/settings/phenotypeDescription.csv @@ -0,0 +1,59 @@ +phenotypeId,phenotypeName,referentConceptId,clinicalDescription,deprecate,metaDataJson +192671000,Gastrointestinal hemorrhage,192671,"Overview: Bleeding from any part of the gastrointestinal tract, but commonly referring to hematemesis (red or curdled blood) from esophagus or upper gi tract, or melena from lower GI tract. Rectal bleeding or oropharyngeal bleeding are not thought to be GI hemorrhage. This phenotype is divided into either upper GI bleeding or lower GI bleeding. Presentation: Overt - vomiting blood (red or dark brown coffee-ground texture), black, tarry stool/rectal bleeding; Occult - dizzy, abd pain, pale, weakAssessment: CBC, stool test (occult bleeding), NG lavage, upper endoscopy, colonoscopy , sigmoidoscopy, angiography, abd CTPlan: proton pump inhibitor (PPI), procedures to control the bleeding (during an endoscopy...)Prognosis: Can stop on its own, but depends on where the bleed is from and cause (eg., peptic ulcer, esophageal varices, Mallory-Weiss syndrome, colitis, hemorrhoids, etc)",NA,"{ + ""oldPhenotypeId"" : [ + ""192671000"" + ], + ""newPhenotypeId"" : [ + ""192671000"" + ], + ""phenotypeId"" : [ + ""192671000"" + ], + ""phenotypeName"" : [ + ""Gastrointestinal hemorrhage"" + ], + ""referentConceptId"" : [ + ""192671"" + ], + ""clinicalDescription"" : [ + ""Overview: Bleeding from any part of the gastrointestinal tract, but commonly referring to hematemesis (red or curdled blood) from esophagus or upper gi tract, or melena from lower GI tract. Rectal bleeding or oropharyngeal bleeding are not thought to be GI hemorrhage. This phenotype is divided into either upper GI bleeding or lower GI bleeding. Presentation: Overt - vomiting blood (red or dark brown coffee-ground texture), black, tarry stool/rectal bleeding; Occult - dizzy, abd pain, pale, weakAssessment: CBC, stool test (occult bleeding), NG lavage, upper endoscopy, colonoscopy , sigmoidoscopy, angiography, abd CTPlan: proton pump inhibitor (PPI), procedures to control the bleeding (during an endoscopy...)Prognosis: Can stop on its own, but depends on where the bleed is from and cause (eg., peptic ulcer, esophageal varices, Mallory-Weiss syndrome, colitis, hemorrhoids, etc)"" + ], + ""literatureReview"" : [ + """" + ], + ""phenotypeNotes"" : [ + """" + ], + ""deprecate"" : [ + """" + ] +}" +201820000,Diabetes Mellitus,201820,Overview: Presentation: Assessment: Plan: Prognosis:,NA,"{ + ""oldPhenotypeId"" : [ + """" + ], + ""newPhenotypeId"" : [ + ""201820000"" + ], + ""phenotypeId"" : [ + ""201820000"" + ], + ""phenotypeName"" : [ + ""Diabetes Mellitus"" + ], + ""referentConceptId"" : [ + ""201820"" + ], + ""clinicalDescription"" : [ + ""Overview: Presentation: Assessment: Plan: Prognosis:"" + ], + ""literatureReview"" : [ + """" + ], + ""phenotypeNotes"" : [ + ""To do"" + ], + ""deprecate"" : [ + """" + ] +}" diff --git a/inst/settings/resultsDataModelSpecification.csv b/inst/settings/resultsDataModelSpecification.csv index c53146588..927366f06 100644 --- a/inst/settings/resultsDataModelSpecification.csv +++ b/inst/settings/resultsDataModelSpecification.csv @@ -1,6 +1,6 @@ tableName,fieldName,type,isRequired,primaryKey,optional,emptyIsNa analysis_ref,analysis_id,bigint,Yes,Yes,No,Yes -analysis_ref,analysis_name,varchar(50),Yes,No,No,Yes +analysis_ref,analysis_name,varchar,Yes,No,No,Yes analysis_ref,domain_id,varchar(20),No,No,No,Yes analysis_ref,start_day,float,No,No,No,Yes analysis_ref,end_day,float,No,No,No,Yes @@ -8,15 +8,16 @@ analysis_ref,is_binary,varchar(1),Yes,No,No,Yes analysis_ref,missing_means_zero,varchar(1),No,No,No,Yes cohort,phenotype_id,bigint,No,No,Yes,Yes cohort,cohort_id,bigint,Yes,Yes,No,Yes -cohort,web_api_cohort_id,bigint,Yes,No,No,Yes -cohort,cohort_name,varchar(255),Yes,No,No,Yes +cohort,web_api_cohort_id,bigint,Yes,No,Yes,Yes +cohort,cohort_name,varchar,Yes,No,No,Yes cohort,logic_description,varchar,No,No,Yes,Yes +cohort,metadata,varchar,No,No,Yes,Yes cohort,sql,varchar,Yes,No,No,Yes cohort,json,varchar,Yes,No,No,Yes cohort_count,cohort_id,bigint,Yes,Yes,No,Yes cohort_count,cohort_entries,float,Yes,No,No,Yes cohort_count,cohort_subjects,float,Yes,No,No,Yes -cohort_count,database_id,varchar(20),Yes,Yes,No,Yes +cohort_count,database_id,varchar,Yes,Yes,No,Yes cohort_overlap,either_subjects,float,Yes,No,No,Yes cohort_overlap,both_subjects,float,Yes,No,No,Yes cohort_overlap,t_only_subjects,float,Yes,No,No,Yes @@ -28,14 +29,14 @@ cohort_overlap,t_in_c_subjects,float,Yes,No,No,Yes cohort_overlap,c_in_t_subjects,float,Yes,No,No,Yes cohort_overlap,target_cohort_id,bigint,Yes,Yes,No,Yes cohort_overlap,comparator_cohort_id,bigint,Yes,Yes,No,Yes -cohort_overlap,database_id,varchar(20),Yes,Yes,No,Yes +cohort_overlap,database_id,varchar,Yes,Yes,No,Yes concept,concept_id,int,Yes,Yes,No,Yes concept,concept_name,varchar(255),Yes,No,No,Yes -concept,domain_id,varchar(20),Yes,Yes,No,Yes -concept,vocabulary_id,varchar(20),Yes,Yes,No,Yes +concept,domain_id,varchar(20),Yes,No,No,Yes +concept,vocabulary_id,varchar(50),Yes,No,No,Yes concept,concept_class_id,varchar(20),Yes,No,No,Yes concept,standard_concept,varchar(1),No,No,No,Yes -concept,concept_code,varchar(20),Yes,No,No,Yes +concept,concept_code,varchar(50),Yes,No,No,Yes concept,valid_start_date,Date,Yes,No,No,Yes concept,valid_end_date,Date,Yes,No,No,Yes concept,invalid_reason,varchar,No,No,No,Yes @@ -63,13 +64,29 @@ covariate_ref,analysis_id,int,Yes,No,No,Yes covariate_ref,concept_id,int,Yes,No,No,Yes covariate_value,cohort_id,bigint,Yes,Yes,No,Yes covariate_value,covariate_id,bigint,Yes,Yes,No,Yes +covariate_value,sum_value,float,Yes,No,No,Yes covariate_value,mean,float,Yes,No,No,Yes covariate_value,sd,float,No,No,No,Yes -covariate_value,database_id,varchar(20),Yes,Yes,No,Yes -database,database_id,varchar(20),Yes,Yes,No,Yes +covariate_value,database_id,varchar,Yes,Yes,No,Yes +covariate_value_dist,cohort_id,bigint,Yes,Yes,No,Yes +covariate_value_dist,covariate_id,bigint,Yes,Yes,No,Yes +covariate_value_dist,count_value,float,Yes,No,No,Yes +covariate_value_dist,min_value,float,Yes,No,No,Yes +covariate_value_dist,max_value,float,Yes,No,No,Yes +covariate_value_dist,mean,float,Yes,No,No,Yes +covariate_value_dist,sd,float,No,No,No,Yes +covariate_value_dist,median_value,float,Yes,No,No,Yes +covariate_value_dist,p_10_value,float,Yes,No,No,Yes +covariate_value_dist,p_25_value,float,Yes,No,No,Yes +covariate_value_dist,p_75_value,float,Yes,No,No,Yes +covariate_value_dist,p_90_value,float,Yes,No,No,Yes +covariate_value_dist,database_id,varchar,Yes,Yes,No,Yes +database,database_id,varchar,Yes,Yes,No,Yes database,database_name,varchar,No,No,No,Yes database,description,varchar,No,No,No,Yes database,is_meta_analysis,varchar(1),Yes,No,No,Yes +database, vocabulary_version, varchar, No, No, Yes, Yes +database, vocabulary_version_cdm, varchar, No, No, Yes, Yes domain,domain_id,varchar(20),Yes,Yes,No,Yes domain,domain_name,varchar(255),Yes,No,No,Yes domain,domain_concept_id,int,Yes,No,No,Yes @@ -80,46 +97,54 @@ incidence_rate,age_group,varchar,No,Yes,No,No incidence_rate,calendar_year,varchar(4),No,Yes,No,No incidence_rate,incidence_rate,float,Yes,No,No,Yes incidence_rate,cohort_id,bigint,Yes,Yes,No,Yes -incidence_rate,database_id,varchar(20),Yes,Yes,No,Yes -included_source_concept,database_id,varchar(20),Yes,Yes,No,Yes +incidence_rate,database_id,varchar,Yes,Yes,No,Yes +included_source_concept,database_id,varchar,Yes,Yes,No,Yes included_source_concept,cohort_id,bigint,Yes,Yes,No,Yes included_source_concept,concept_set_id,int,Yes,Yes,No,Yes included_source_concept,concept_id,int,Yes,Yes,No,Yes -included_source_concept,source_concept_id,int,Yes,Yes,No,Yes +included_source_concept,source_concept_id,int,No,Yes,Yes,No included_source_concept,concept_subjects,float,Yes,No,No,Yes included_source_concept,concept_count,float,Yes,No,No,Yes inclusion_rule_stats,rule_sequence_id,int,Yes,Yes,No,Yes -inclusion_rule_stats,rule_name,varchar(255),Yes,No,No,Yes +inclusion_rule_stats,rule_name,varchar,Yes,No,No,Yes inclusion_rule_stats,meet_subjects,float,Yes,No,No,Yes inclusion_rule_stats,gain_subjects,float,Yes,No,No,Yes inclusion_rule_stats,total_subjects,float,Yes,No,No,Yes inclusion_rule_stats,remain_subjects,float,Yes,No,No,Yes inclusion_rule_stats,cohort_id,bigint,Yes,Yes,No,Yes -inclusion_rule_stats,database_id,varchar(20),Yes,Yes,No,Yes +inclusion_rule_stats,database_id,varchar,Yes,Yes,No,Yes index_event_breakdown,concept_id,int,Yes,Yes,No,Yes index_event_breakdown,concept_count,float,Yes,No,No,Yes +index_event_breakdown,subject_count,float,Yes,No,No,Yes index_event_breakdown,cohort_id,bigint,Yes,Yes,No,Yes -index_event_breakdown,database_id,varchar(20),Yes,Yes,No,Yes +index_event_breakdown,database_id,varchar,Yes,Yes,No,Yes +index_event_breakdown,domain_field,varchar,Yes,Yes,No,Yes +index_event_breakdown,domain_table,varchar,Yes,Yes,No,Yes +metadata,database_id,varchar,Yes,Yes,No,Yes +metadata,variable_field,varchar,Yes,Yes,No,Yes +metadata,value_field,varchar,Yes,No,No,Yes orphan_concept,cohort_id,bigint,Yes,Yes,No,Yes orphan_concept,concept_set_id,int,Yes,Yes,No,Yes -orphan_concept,database_id,varchar(20),Yes,Yes,No,Yes +orphan_concept,database_id,varchar,Yes,Yes,No,Yes orphan_concept,concept_id,int,Yes,Yes,No,Yes orphan_concept,concept_count,float,Yes,No,No,Yes orphan_concept,concept_subjects,float,Yes,No,No,Yes phenotype_description,phenotype_id,bigint,Yes,Yes,No,Yes -phenotype_description,phenotype_name,varchar(255),Yes,No,No,Yes -phenotype_description,referent_concept_id,int,Yes,No,No,Yes -phenotype_description,clinical_description,varchar,Yes,No,No,Yes -phenotype_description,literature_review,varchar,No,No,No,Yes -phenotype_description,phenotype_notes,varchar,No,No,No,Yes +phenotype_description,phenotype_name,varchar,Yes,No,No,Yes +phenotype_description,clinical_description,varchar,No,No,No,Yes +phenotype_description,metadata,varchar,No,No,No,Yes relationship,relationship_id,varchar(20),Yes,Yes,No,Yes relationship,relationship_name,varchar(255),Yes,No,No,Yes relationship,is_hierarchical,varchar(1),Yes,No,No,Yes relationship,defines_ancestry,varchar(1),Yes,No,No,Yes relationship,reverse_relationship_id,varchar(20),Yes,Yes,No,Yes relationship,relationship_concept_id,int,Yes,Yes,No,Yes +resolved_concepts,cohort_id,bigint,Yes,Yes,No,Yes +resolved_concepts,concept_set_id,int,Yes,Yes,No,Yes +resolved_concepts,concept_id,int,Yes,Yes,No,Yes +resolved_concepts,database_id,varchar,Yes,Yes,No,Yes temporal_analysis_ref,analysis_id,int,Yes,Yes,No,Yes -temporal_analysis_ref,analysis_name,varchar(20),Yes,No,No,Yes +temporal_analysis_ref,analysis_name,varchar,Yes,No,No,Yes temporal_analysis_ref,domain_id,varchar(20),Yes,Yes,No,Yes temporal_analysis_ref,is_binary,varchar(1),Yes,No,No,Yes temporal_analysis_ref,missing_means_zero,varchar(1),No,No,No,Yes @@ -130,9 +155,23 @@ temporal_covariate_ref,concept_id,int,Yes,No,No,Yes temporal_covariate_value,cohort_id,bigint,Yes,Yes,No,Yes temporal_covariate_value,time_id,int,Yes,Yes,No,Yes temporal_covariate_value,covariate_id,bigint,Yes,Yes,No,Yes +temporal_covariate_value,sum_value,float,Yes,No,No,Yes temporal_covariate_value,mean,float,Yes,No,No,Yes temporal_covariate_value,sd,float,No,No,No,Yes -temporal_covariate_value,database_id,varchar(20),Yes,Yes,No,Yes +temporal_covariate_value,database_id,varchar,Yes,Yes,No,Yes +temporal_covariate_value_dist,cohort_id,bigint,Yes,Yes,No,Yes +temporal_covariate_value_dist,time_id,bigint,Yes,Yes,No,Yes +temporal_covariate_value_dist,covariate_id,bigint,Yes,Yes,No,Yes +temporal_covariate_value_dist,count_value,float,Yes,No,No,Yes +temporal_covariate_value_dist,min_value,float,Yes,No,No,Yes +temporal_covariate_value_dist,max_value,float,Yes,No,No,Yes +temporal_covariate_value_dist,mean,float,Yes,No,No,Yes +temporal_covariate_value_dist,sd,float,Yes,No,No,Yes +temporal_covariate_value_dist,median_value,float,Yes,No,No,Yes +temporal_covariate_value_dist,p_10_value,float,Yes,No,No,Yes +temporal_covariate_value_dist,p_25_value,float,Yes,No,No,Yes +temporal_covariate_value_dist,p_75_value,float,Yes,No,No,Yes +temporal_covariate_value_dist,p_90_value,float,Yes,No,No,Yes temporal_time_ref,time_id,int,Yes,Yes,No,Yes temporal_time_ref,start_day,float,Yes,No,No,Yes temporal_time_ref,end_day,float,Yes,No,No,Yes @@ -147,14 +186,23 @@ time_distribution,p_10_value,float,Yes,No,No,Yes time_distribution,p_25_value,float,Yes,No,No,Yes time_distribution,p_75_value,float,Yes,No,No,Yes time_distribution,p_90_value,float,Yes,No,No,Yes -time_distribution,time_metric,varchar(50),Yes,Yes,No,Yes -time_distribution,database_id,varchar(20),Yes,Yes,No,Yes +time_distribution,time_metric,varchar,Yes,Yes,No,Yes +time_distribution,database_id,varchar,Yes,Yes,No,Yes +time_series,cohort_id,bigint,Yes,Yes,No,Yes +time_series,database_id,varchar,Yes,Yes,No,Yes +time_series,period_begin,Date,Yes,Yes,No,Yes +time_series,calendar_interval,varchar(1),Yes,Yes,No,Yes +time_series,records,bigint,Yes,No,No,Yes +time_series,subjects,bigint,Yes,No,No,Yes +time_series,person_days,bigint,Yes,No,No,Yes +time_series,records_incidence,bigint,No,No,No,No +time_series,subjects_incidence,bigint,No,No,No,No visit_context,cohort_id,bigint,Yes,Yes,No,Yes visit_context,visit_concept_id,int,Yes,Yes,No,Yes -visit_context,visit_context,varchar(20),Yes,Yes,No,Yes +visit_context,visit_context,varchar,Yes,Yes,No,Yes visit_context,subjects,float,Yes,No,No,Yes -visit_context,database_id,varchar(20),Yes,Yes,No,Yes -vocabulary,vocabulary_id,varchar(20),Yes,Yes,No,Yes +visit_context,database_id,varchar,Yes,Yes,No,Yes +vocabulary,vocabulary_id,varchar(50),Yes,Yes,No,Yes vocabulary,vocabulary_name,varchar(255),Yes,No,No,Yes vocabulary,vocabulary_reference,varchar,No,No,No,Yes vocabulary,vocabulary_version,varchar,No,No,No,Yes diff --git a/inst/shiny/CohortExplorer/R/widgets.R b/inst/shiny/CohortExplorer/R/widgets.R new file mode 100644 index 000000000..b7a2c0999 --- /dev/null +++ b/inst/shiny/CohortExplorer/R/widgets.R @@ -0,0 +1,53 @@ +menuItemFileInput <- + function(inputId, + text, + icon = shiny::icon("file-text-o")) { + script <- "document.getElementById('%id%').click(); return false;" + script <- gsub("%id%", inputId, script) + list(div(fileInput(inputId, ""), style = "display: none;"), + tags$li(class = "treeview", a( + href = "#", onclick = script, icon, text + ))) + } + +menuItemDownloadLink <- + function(inputId, label, icon = shiny::icon("floppy-o")) { + tags$li( + class = "treeview", + tags$a( + id = inputId, + class = "shiny-download-link", + href = "", + target = "_blank", + download = NA, + icon, + label + ) + ) + } + +menuItemCopyTextAreaToClipboard <- + function(textAreaId, + label, + icon = shiny::icon("clipboard")) { + script <- " + element = $('