Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e051e65
Update CreateTargetCohortTable.sql
jreps May 26, 2026
1ba5b75
adding cohort subsetting in package
jreps Jun 1, 2026
d2c78c9
minor fixes
jreps Jun 2, 2026
9d20b38
initial unit test updates
jreps Jun 4, 2026
0e879bd
updating results tables via migrations
jreps Jun 15, 2026
20f1146
fixing tests and example
jreps Jun 16, 2026
dfa8a2d
replacing IFNULL with ISNULL
jreps Jun 16, 2026
c73c9ea
update description
jreps Jun 16, 2026
6015b7f
improving dechal id name consistency
jreps Jun 16, 2026
d774f81
Update TargetCohorts.sql
jreps Jun 16, 2026
b12ed69
fixing division by 0 sqrt
jreps Jun 16, 2026
67fe8ad
Update RiskFactorBinaryExtraction.sql
jreps Jun 16, 2026
95ff267
fixing sqrt 0 division
jreps Jun 16, 2026
2838eb4
manually specifying risk factor columns
jreps Jun 16, 2026
e382295
casting potential floats into bigints
jreps Jun 17, 2026
18e5f4f
Update NonCaseCohorts.sql
jreps Jun 17, 2026
fbcbf8e
bigquery issue
jreps Jun 17, 2026
7f9d96b
Update TargetCohorts.sql
jreps Jun 17, 2026
6151af1
Update TargetCohorts.sql
jreps Jun 17, 2026
6316af4
fixing another bigquery issue
jreps Jun 18, 2026
494a23e
minor fixes
jreps Jun 22, 2026
6d97ab2
minor upload bug fixes
jreps Jun 25, 2026
23e842b
adding option to washout using outcomes outside observation period
jreps Jul 9, 2026
338de6c
Update NonCaseCohorts.sql
jreps Jul 10, 2026
027f788
noncase edits
jreps Jul 10, 2026
7cf32ff
Update NonCaseCohorts.sql
jreps Jul 10, 2026
62a62a9
Update NonCaseCohorts.sql
jreps Jul 10, 2026
26ea8ed
fixing target/case code for situation where cohorts are not nicely or…
jreps Jul 10, 2026
397837b
fixing shiny
jreps Jul 10, 2026
5104fda
Update shinyConfigUpdate.json
jreps Jul 10, 2026
18118e0
Update shinyConfigUpdate.json
jreps Jul 10, 2026
d8c5831
Update ViewShiny.R
jreps Jul 10, 2026
df3412e
outcome eras and shiny app fix
jreps Jul 10, 2026
ea5cd70
moving outcome era to before non case
jreps Jul 13, 2026
c8ef4ed
editing when minCharacterizationMean is called
jreps Jul 28, 2026
b6fa20a
preparing to merge into develop
jreps Jul 31, 2026
3dea59a
Merge branch 'develop' into subset_creation
jreps Jul 31, 2026
0a62bf7
removing restrictWashoutToObs
jreps Jul 31, 2026
71cd59e
shiny updates
jreps Jul 31, 2026
226b942
Merge pull request #96 from OHDSI/subset_creation
jreps Jul 31, 2026
8aa53f9
fixing pkdown
jreps Jul 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: Characterization
Type: Package
Title: Implement Descriptive Studies Using the Common Data Model
Version: 3.0.1
Date: 2026-4-15
Version: 4.0.0
Date: 2026-7-15
Authors@R: c(
person("Jenna", "Reps", , "jreps@its.jnj.com", role = c("aut", "cre")),
person("Patrick", "Ryan", , "ryan@ohdsi.org", role = c("aut")),
Expand Down Expand Up @@ -39,6 +39,6 @@ Suggests:
shiny,
withr
NeedsCompilation: no
RoxygenNote: 7.3.2
Encoding: UTF-8
VignetteBuilder: knitr
Config/roxygen2/version: 8.0.0
4 changes: 1 addition & 3 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@

export(cleanIncremental)
export(cleanNonIncremental)
export(computeDechallengeRechallengeAnalyses)
export(computeRechallengeFailCaseSeriesAnalyses)
export(computeTimeToEventAnalyses)
export(createCaseSeriesSettings)
export(createCharacterizationSettings)
export(createCharacterizationTables)
export(createDechallengeRechallengeSettings)
export(createDuringCovariateSettings)
export(createRiskFactorSettings)
export(createSqliteDatabase)
export(createStudyPopulationSettings)
export(createTargetBaselineSettings)
export(createTimeToEventSettings)
export(exampleOmopConnectionDetails)
Expand Down
15 changes: 15 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
Characterization 4.0.0
======================
- [enhancement] replaced targetId inputs to the settings with studyPopulationSettings that lets you specify
min prior observation, first in n days, age, date, gender and nesting cohort restrictions.
- [enhancement] outcome washout in risk factor is now used to combine outcome cohort entries that are within outcome washout days
- [enhancement] improved attrition capture: can now see fill attrition for study population
- [enhancement] changed csv file output to split up attrition into case_attrition and target_attrition, added
case_counts and target_counts and added time_to_event_settings/dechallenge_rechallenge_settings that
let user quickly see what study population and outcome pairs were included.
- [bug fix] fixed issues when dividing by zero in SMD calculation

Characterization 3.0.2
======================
- Replacing IFNULL with ISNULL as SQL server errors with IFNULL

Characterization 3.0.1
======================
- Fix issue with uploading results into database for shiny viewer (spacing was added to csv and causing issues and continuous covariates that are floats were incorrectly bigints)
Expand Down
105 changes: 51 additions & 54 deletions R/CaseSeries.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,26 @@

#' Create aggregate covariate study settings
#'
#' @param targetIds A list of cohortIds for the target cohorts
#' @param studyPopulationSettings A List of object created using \code{createStudyPopulationSettings} that specifies target cohorts and inclusion criteria
#' @param outcomeIds A list of cohortIds for the outcome cohorts
#' @param limitToFirstInNDays whether to limit each target cohort to the first entry into the cohort per N days per subject
#' @param minPriorObservation The minimum time (in days) in the database a patient in the target cohorts must be observed prior to index
#' @param outcomeWashoutDays Patients with the outcome within outcomeWashout days prior to index are excluded from the risk factor analysis
#' @param outcomeWashoutDays A single integer value. Patients with the outcome within outcomeWashout days prior to index are excluded from the risk factor analysis
#' @template timeAtRisk
#' @param caseCovariateSettings An object created using \code{createDuringCovariateSettings}
#' @param casePreTargetDuration The number of days prior to case index we use for FeatureExtraction
#' @param casePostOutcomeDuration The number of days prior to case index we use for FeatureExtraction
#' @param casePreTargetDuration A single integer value. The number of days prior to case index we use for FeatureExtraction
#' @param casePostOutcomeDuration A single integer value. The number of days prior to case index we use for FeatureExtraction
#' @family Aggregate
#' @return
#' A list with the settings
#'
#' @examples
#'
#' caseSeriesSetting <- createCaseSeriesSettings(
#' targetIds = c(1,2),
#' studyPopulationSettings = createStudyPopulationSettings(
#' targetIds = c(1,2),
#' minPriorObservation = 365,
#' limitToFirstInNDays = 365
#' ),
#' outcomeIds = c(3),
#' limitToFirstInNDays = 365,
#' minPriorObservation = 365,
#' outcomeWashoutDays = 90,
#' riskWindowStart = 1,
#' startAnchor = "cohort start",
Expand All @@ -47,10 +47,8 @@
#'
#' @export
createCaseSeriesSettings <- function(
targetIds,
studyPopulationSettings,
outcomeIds,
limitToFirstInNDays = 99999,
minPriorObservation = 0,
outcomeWashoutDays = 0,
riskWindowStart = 1,
startAnchor = "cohort start",
Expand All @@ -70,18 +68,23 @@ createCaseSeriesSettings <- function(
) {
errorMessages <- checkmate::makeAssertCollection()
# check targetIds is a vector of int/double
.checkCohortIds(
cohortIds = targetIds,
type = "target",
errorMessages = errorMessages
)
#.checkCohortIds(
# cohortIds = targetIds,
# type = "target",
# errorMessages = errorMessages
#)
# check outcomeIds is a vector of int/double
.checkCohortIds(
cohortIds = outcomeIds,
type = "outcome",
errorMessages = errorMessages
)

# check outcomeWashoutDays is length 1
if (length(outcomeWashoutDays) > 1) {
stop("Please add one outcomeWashoutDays per setting")
}

# check TAR - EFF edit
if (length(riskWindowStart) > 1) {
stop("Please add one time-at-risk per setting")
Expand All @@ -95,10 +98,10 @@ createCaseSeriesSettings <- function(
)

# check minPriorObservation
.checkMinPriorObservation(
minPriorObservation = minPriorObservation,
errorMessages = errorMessages
)
#.checkMinPriorObservation(
# minPriorObservation = minPriorObservation,
# errorMessages = errorMessages
#)

# add check for outcomeWashoutDays and nlimitToFirstInNDays

Expand All @@ -125,10 +128,10 @@ createCaseSeriesSettings <- function(
checkmate::reportAssertions(errorMessages)

# check unique Ts and Os
if (length(targetIds) != length(unique(targetIds))) {
message("targetIds have duplicates - making unique")
targetIds <- unique(targetIds)
}
#if (length(targetIds) != length(unique(targetIds))) {
# message("targetIds have duplicates - making unique")
# targetIds <- unique(targetIds)
#}
if (length(outcomeIds) != length(unique(outcomeIds))) {
message("outcomeIds have duplicates - making unique")
outcomeIds <- unique(outcomeIds)
Expand All @@ -137,9 +140,7 @@ createCaseSeriesSettings <- function(

# create list
result <- list(
targetIds = targetIds,
limitToFirstInNDays = limitToFirstInNDays,
minPriorObservation = minPriorObservation,
studyPopulationSettings = combineStudyPopulationSettings(studyPopulationSettings),
outcomeIds = outcomeIds,
outcomeWashoutDays = outcomeWashoutDays,
riskWindowStart = riskWindowStart,
Expand Down Expand Up @@ -168,8 +169,8 @@ computeCaseSeriesAnalyses <- function(

characterizationDatabaseSchema,
characterizationTable, # contains char cohorts
targetSettingsTable, # contains map between settings and char cohort id
caseSettingsTable, # contains map between settings and case id
caseCountTable, # new

tempEmulationSchema = getOption("sqlRenderTempEmulationSchema"),
settings,
Expand All @@ -180,6 +181,7 @@ computeCaseSeriesAnalyses <- function(
minCellCount = 0,
progressBar = interactive(),
executionId,
minCaseSize = minCaseSize,
...) {

if(missing(outputFolder)){
Expand All @@ -199,34 +201,32 @@ computeCaseSeriesAnalyses <- function(
start <- Sys.time()
message("Case series analysis: Finding temp Ids")

targetIds <- lookupTargets(
connection = connection,
lookupDatabaseSchema = characterizationDatabaseSchema,
lookupTableName = targetSettingsTable,
tempEmulationSchema = tempEmulationSchema,
targetIds = paste0(unique(settings$targetIds), collapse = ','),
limitToFirstInNDays = settings$limitToFirstInNDays,
minPriorObservation = settings$minPriorObservation
)

caseIds <- lookupCases(
connection = connection,
lookupDatabaseSchema = characterizationDatabaseSchema,
lookupTableName = caseSettingsTable,
countTable = caseCountTable,
tempEmulationSchema = tempEmulationSchema,
characterizationTargetIds = paste0(unique(targetIds$characterizationTargetId), collapse = ','),
characterizationTargetIds = paste0(unique(settings$characterizationTargetId), collapse = ','),
outcomeIds = paste0(unique(settings$outcomeIds), collapse = ','),
outcomeWashoutDays = settings$outcomeWashoutDays,
startAnchor = settings$startAnchor,
riskWindowStart = settings$riskWindowStart,
endAnchor = settings$endAnchor,
riskWindowEnd = settings$riskWindowEnd
riskWindowEnd = settings$riskWindowEnd,
minCaseSize = minCaseSize,
applyMinSizeToNonCases = FALSE
)

completionTime <- Sys.time() - start
message(paste0("Case series analysis: Finding temp Ids took ", round(completionTime, digits = 1), " ", units(completionTime)))


if(nrow(caseIds) == 0){
message('No case cohorts of minCaseSize')
return(invisible(TRUE))
}

## 4) run FE with all the cohorts of interest - ideally inserting the aggregate features into a new table
start <- Sys.time()
message("Case series analysis: Running FeatureExtraction")
Expand All @@ -239,10 +239,10 @@ computeCaseSeriesAnalyses <- function(
cohortIds = c(caseIds$characterizationCaseId*10+3,
caseIds$characterizationCaseId*10+4,
caseIds$characterizationCaseId*10+5),
rowIdField = 'row_number',
rowIdField = 'row_id',
covariateSettings = ParallelLogger::convertJsonToSettings(settings$covariateSettings),
aggregated = TRUE,
minCharacterizationMean = minCharacterizationMean,
minCharacterizationMean = 0, #minCharacterizationMean,

exportToTable = TRUE,
targetDatabaseSchema = NULL,
Expand Down Expand Up @@ -275,7 +275,8 @@ computeCaseSeriesAnalyses <- function(
caseIds$characterizationCaseId*10+4,
caseIds$characterizationCaseId*10+5),
collapse = ','),
min_count = minCovariateCount
min_count = minCovariateCount,
min_characterization_mean = minCharacterizationMean
)

tryCatch(
Expand Down Expand Up @@ -342,8 +343,9 @@ computeCaseSeriesAnalyses <- function(
snakeCaseToCamelCase = TRUE
)

result$targetSettings <- targetIds
result$caseSettings <- caseIds
# TODO Removed
##result$targetSettings <- targetIds
##result$caseSettings <- caseIds

completionTime <- Sys.time() - start
message(paste0("Case series analysis: Downloading took ", round(completionTime, digits = 1), " ", units(completionTime)))
Expand Down Expand Up @@ -403,9 +405,7 @@ getCaseSeriesJobs <- function(
FUN = function(outcomeId){

data.frame(
targetId = unique(characterizationSettings[[i]]$targetIds),
limitToFirstInNDays = characterizationSettings[[i]]$limitToFirstInNDays,
minPriorObservation = characterizationSettings[[i]]$minPriorObservation,
characterizationTargetId = unique(characterizationSettings[[i]]$characterizationTargetIds),

outcomeId = outcomeId,
outcomeWashoutDays = unique(characterizationSettings[[i]]$outcomeWashoutDays),
Expand All @@ -428,10 +428,9 @@ getCaseSeriesJobs <- function(

settings <- c()
if(nrow(caseSeriesCombinations) > 0 ){
jobCols <- c("targetId")
jobCols <- c("characterizationTargetId")

settingCols <- c(
"limitToFirstInNDays", "minPriorObservation",
"outcomeWashoutDays",
"riskWindowStart", "startAnchor",
"riskWindowEnd", "endAnchor",
Expand Down Expand Up @@ -469,10 +468,8 @@ getCaseSeriesJobs <- function(
functionName = "computeCaseSeriesAnalyses",
settings = as.character(ParallelLogger::convertSettingsToJson(
list(
targetIds = unique(restrictedData$targetId[ind]),
characterizationTargetIds = unique(restrictedData$characterizationTargetId[ind]),
outcomeIds = unique(restrictedData$outcomeId[ind]),
minPriorObservation = unique(restrictedData$minPriorObservation[ind]),
limitToFirstInNDays = unique(restrictedData$limitToFirstInNDays[ind]),

outcomeWashoutDays = unique(restrictedData$outcomeWashoutDays[ind]),
riskWindowStart = unique(restrictedData$riskWindowStart[ind]),
Expand Down
Loading
Loading