knitr::opts_chunk$set(echo = TRUE)
options(kableExtra.latex.load_packages = FALSE)
library(kableExtra)
#knitr::knit_hooks$set(document = function(x) {sub('\\usepackage[]{color}', '\\usepackage[table]{xcolor}', x, fixed = TRUE)})
library(dplyr)
options(knitr.kable.NA = "")
if (!knitr::is_latex_output() && !knitr::is_html_output()) {
  options(knitr.table.format = "simple")
}

pdf2png <- function(path) {
  # only do the conversion for non-LaTeX output
  if (knitr::is_latex_output()) {
    return(path)
  }
  path2 <- xfun::with_ext(path, "png")
  img <- magick::image_read_pdf(path)
  magick::image_write(img, path2, format = "png")
  path2
}


latex_table_font_size <- 8

Introduction

This document describes the data model for storing the output of the EUMAEUS (Evaluating Use of Methods for Adverse Event Under Surveillance (for vaccines)) study.

Fields with minimum values

Some fields contain patient counts or fractions that can easily be converted to patient counts. To prevent identifiability, these fields are subject to a minimum value. When the value falls below this minimum, it is replaced with the negative value of the minimum. For example, if the minimum subject count is 5, and the actual count is 2, the value stored in the data model will be -5, which could be represented as '\<5' to the user. Note that the value 0 is permissible, as it identifies no persons.

Tables

In this section you will find the list of tables. Note that the estimate and estimate_imputed_pcs tables both contain the same negative control estimates, although the calibrated confidence intervals (CI) will differ. In the estimate table, CI calibration was done using the synthetic positive controls, in the estimate_imputed_pcs table the CI calibration was done assuming the systematic error distribution does not change as a function of the true effect size. Positive controls listed in the estimate table can be found in the positive_control_outcome table, whereas positive controls in the estimate_imputed_pcs can be found in the imputed_positive_control_outcome table.

specifications <- readr::read_csv("../inst/settings/resultsModelSpecs.csv")
tables <- split(specifications, specifications$tableName)

for (table in tables) {
  header <- sprintf("## Table %s", table$tableName[1])

  table <- table %>% 
    select(Field = .data$fieldName, Type = .data$type, Key = .data$primaryKey, Description = .data$description) %>%
    kable(linesep = "", booktabs = TRUE, longtable = TRUE)

  if (knitr::is_latex_output()) {    
    writeLines("")
    writeLines(header)

    writeLines(table %>% 
                 kable_styling(latex_options = "striped", font_size = latex_table_font_size) %>%
                 column_spec(1, width = "10em") %>%
                 column_spec(2, width = "5em") %>%
                 column_spec(3, width = "3em") %>%
                 column_spec(4, width = "16em"))
  } else if (knitr::is_html_output()) {
    writeLines("")
    writeLines(header)

    writeLines(table %>% 
                 kable_styling(bootstrap_options = "striped"))
  } 
}

Example code

Contact Martijn Schuemie to obtain the credentials to query the database. Once these are set, you can execute the following code.

First, create a connection to the database:

library(DatabaseConnector)
library(dplyr)
connectionDetails <- createConnectionDetails(dbms = "postgresql",
                                             server = paste(keyring::key_get("eumaeusServer"),
                                                            keyring::key_get("eumaeusDatabase"),
                                                            sep = "/"),
                                             user = keyring::key_get("eumaeusUser"),
                                             password = keyring::key_get("eumaeusPassword"))
connection <- connect(connectionDetails)

Next, we can start querying the database. For example, we could get the list of all negative control outcomes:

sql <- "
SELECT *
FROM eumaeus.negative_control_outcome;
"

ncs <- querySql(connection, sql, snakeCaseToCamelCase = TRUE)
head(ncs)

Similarly, we can a list of analyses that was performed:

sql <- "
SELECT *
FROM eumaeus.analysis;
"

analysis <- querySql(connection, sql, snakeCaseToCamelCase = TRUE)
head(analysis)

Or the exposures:

sql <- "
SELECT *
FROM eumaeus.exposure;
"

exposure <- querySql(connection, sql, snakeCaseToCamelCase = TRUE)
head(exposure)

We may want to retrieve the estimates for the H1N1 vaccination (exposure ID = 21184) with negative control outcome 'Alkalosis' (outcome ID = 438730) in the IBM MDCD database for the unadjusted historical comparator analysis using a time-at-risk of 1-28 days (analysis ID = 1):

sql <- "
SELECT *
FROM eumaeus.estimate
INNER JOIN eumaeus.time_period
  ON estimate.period_id = time_period.period_id
    AND estimate.exposure_id = time_period.exposure_id
WHERE database_id = 'IBM_MDCD'
  AND method = 'HistoricalComparator'
  AND analysis_id = 1
  AND estimate.exposure_id = 21184
  AND outcome_id = 438730;
"

estimate <- querySql(connection, sql, snakeCaseToCamelCase = TRUE)
estimate %>%
  select(label, exposureSubjects, exposureOutcomes, rr, llr, criticalValue)

Note that in many cases the number of exposed subjects within a time period can be 0, and other values such as the relative risk (rr) cannot be computed and are therefore set to NA.

Don't forget to close the connetion when you're done:

disconnect(connection)


ohdsi-studies/Eumaeus documentation built on Feb. 12, 2024, 9:45 p.m.