Ot1Xb8It{w_%$kJZTM7
zam=5z=ijZwqYVRWL@^OI$Wxq!9=8XqwE;$$-%VRpb}?30ThXqRV2i9}*>JBN2!N%U
zWU8%IT;^Wyhf*M6=2d+(T0XVUQhZ>HMIg0V6~kL4TnvY8uS31522`vn~QGk}Tv+
z5v}kIQ&275`{)WOF4Th`r-(+xwMU-31B@r5NQ#O%s05E_l3stlGN2h7!V=dhAQ3Xu
zV8H|?0{22;D$+YwNW2DL_3jYud0j+2^o3#~)OIA9vf?JMU4+J2gEB2*W#X1F5zQsq
zu-HLV^$7>0_2dxkfijLj8|SumMArFbBC9l{9DyD)@i?}z%jq9N3ecZDOMavr(RE?4
z5|DzQP&`9Vv>B?JissiE^k#Ks(dYk)otV||kQ%FFC
z2NGY1dg#m&_pM<<=s{A!XXK&bbfAb^<~$v>totO}y?Z(^$L>1DEo8f8oPimWaMi3=
zt8!6|t5A*XaaWxFIz;PBjo0r#@w|%a>zcsf__At*zl%bosib-pDx!`H%RHO5B-3^;oL(Zjx4(WEu_weyZJztdV5Rx%V@`Qc7CcwPh>u7k`pWB
zP%~xMszrIWXnwU<6}qBQtL`9=0~~M_4gEjb`o0xeEugm>P{G5BaYI&n$VF%Q6
z2c}f?10`kyVfG*I50$?HB$A0bGmDjS57c!B^O(BQtp5$}LfISUp6K%S>W
z40XMLFOFa7h2mRZ(eYE^IWM5X#GYAu-=rHQ4o30pRc;E0yhLYNk69@8`vIm?a&Ha4
zybC+l`Myg>q55ckvHSXQ2zqz}Q#d*c7%@X#&i`i${m!8`SO?Zn+y17hUJUEYF9hFC
z*gfx=hM=Dd$Y%S-8x?is17o%IAxkQuUXb63)KyU?16G#(ADK0>#fMDQjPb+=uMi^)
zF^yQvGoNTC6*Q`7`R#FQqTTbL+h_o(=(MTN3VJ%q1Z^0ThiW=xj!!#lE<21^baQoB
z?6>1gF=@U)m3a&r7Eku2Ayx&_HfAw(;R#>hphur@?qt-T=b;H4i`G9od8ZhFOT>Wz
zv%DBCUuk%&91>JRg6xB;r4)cQQotMv{6v#@j~`GM&y;5DhOosC9YdI(OVD*iReXHh
z2}=0`Z9UrbRcRcx&tG_)@$nzH0P0Rcx1tz-B+G=S_#@ea*gnl%bWfD#uzqZr$l=WR
kEJPoq2e|O9KM2tMe|KIM>zXXha)EgPKz%|9JyOp90lf9_h5!Hn
diff --git a/java/main/java/org/ohdsi/cohortincidence/CohortIncidenceQueryBuilder.java b/java/main/java/org/ohdsi/cohortincidence/CohortIncidenceQueryBuilder.java
index 80939c3..620dcfa 100644
--- a/java/main/java/org/ohdsi/cohortincidence/CohortIncidenceQueryBuilder.java
+++ b/java/main/java/org/ohdsi/cohortincidence/CohortIncidenceQueryBuilder.java
@@ -26,6 +26,7 @@ public class CohortIncidenceQueryBuilder {
private static final String COHORT_SUBGROUP_TEMPTABLE_TEMPLATE = ResourceHelper.GetResourceAsString("/resources/cohortincidence/sql/cohortSubgroupTempTable.sql");
private static final String TAR_STRATA_QUERY_TEMPTABLE_TEMPLATE = ResourceHelper.GetResourceAsString("/resources/cohortincidence/sql/tarStrataQueryTemplate.sql");
private static final String OUTCOME_STRATA_QUERY_TEMPTABLE_TEMPLATE = ResourceHelper.GetResourceAsString("/resources/cohortincidence/sql/outcomeStrataQueryTemplate.sql");
+ private static final String AGE_GROUP_JOIN = ResourceHelper.GetResourceAsString("/resources/cohortincidence/sql/ageGroupJoin.sql");
private static final String AGE_GROUP_SELECT_TEMPLATE = "select CAST(%d as int) as age_group_id, '%s' as age_group_name, cast(%s as int) as min_age, cast(%s as int) as max_age";
private static final String NULL_STRATA = "cast(null as int)";
@@ -273,9 +274,11 @@ private String buildStrataQuery(String strataTemplate, String[] selectCols, Stri
private String getStrataQueries(String strataTemplate) {
ArrayList queries = new ArrayList<>();
+ // Note: because age strata can contain overlapping (ie: non-stratified) age breaks, we need to
+ // apply the ageGroupJoin only on the subqueries that involve age group stratification.
// overall strata
queries.add(buildStrataQuery(
- strataTemplate,
+ StringUtils.replace(strataTemplate, "@ageGroupJoin", ""),
new String[] {NULL_STRATA + " as age_group_id", NULL_STRATA + " as gender_id", NULL_STRATA + " as start_year"},
new String[] {}
));
@@ -283,35 +286,35 @@ private String getStrataQueries(String strataTemplate) {
// by age
if (this.design.strataSettings != null && this.design.strataSettings.byAge) {
queries.add(buildStrataQuery(
- strataTemplate,
- new String[] {"t1.age_group_id", NULL_STRATA + " as gender_id", NULL_STRATA + " as start_year"},
- new String[] {"t1.age_group_id"}
+ StringUtils.replace(strataTemplate, "@ageGroupJoin", AGE_GROUP_JOIN),
+ new String[]{"ag.age_group_id", NULL_STRATA + " as gender_id", NULL_STRATA + " as start_year"},
+ new String[]{"ag.age_group_id"}
));
// by age, by gender
if (this.design.strataSettings.byGender) {
queries.add(buildStrataQuery(
- strataTemplate,
- new String[] {"t1.age_group_id", "t1.gender_id", NULL_STRATA + " as start_year"},
- new String[] {"t1.age_group_id", "t1.gender_id"}
+ StringUtils.replace(strataTemplate, "@ageGroupJoin", AGE_GROUP_JOIN),
+ new String[]{"ag.age_group_id", "t1.gender_id", NULL_STRATA + " as start_year"},
+ new String[]{"ag.age_group_id", "t1.gender_id"}
));
}
// by age, by year
if (this.design.strataSettings.byYear) {
queries.add(buildStrataQuery(
- strataTemplate,
- new String[] {"t1.age_group_id", NULL_STRATA + " as gender_id", "t1.start_year"},
- new String[] {"t1.age_group_id", "t1.start_year"}
+ StringUtils.replace(strataTemplate, "@ageGroupJoin", AGE_GROUP_JOIN),
+ new String[] {"ag.age_group_id", NULL_STRATA + " as gender_id", "t1.start_year"},
+ new String[] {"ag.age_group_id", "t1.start_year"}
));
}
// by age, by gender, by year
if (this.design.strataSettings.byGender && this.design.strataSettings.byYear) {
queries.add(buildStrataQuery(
- strataTemplate,
- new String[] {"t1.age_group_id", "t1.gender_id", "t1.start_year"},
- new String[] {"t1.age_group_id", "t1.gender_id", "t1.start_year"}
+ StringUtils.replace(strataTemplate, "@ageGroupJoin", AGE_GROUP_JOIN),
+ new String[] {"ag.age_group_id", "t1.gender_id", "t1.start_year"},
+ new String[] {"ag.age_group_id", "t1.gender_id", "t1.start_year"}
));
}
}
@@ -319,7 +322,7 @@ private String getStrataQueries(String strataTemplate) {
// by gender
if (this.design.strataSettings != null && this.design.strataSettings.byGender) {
queries.add(buildStrataQuery(
- strataTemplate,
+ StringUtils.replace(strataTemplate, "@ageGroupJoin", ""),
new String[]{NULL_STRATA + " as age_group_id", "t1.gender_id", NULL_STRATA + " as start_year"},
new String[]{"t1.gender_id"}
));
@@ -327,7 +330,7 @@ private String getStrataQueries(String strataTemplate) {
// by gender, by year
if (this.design.strataSettings.byYear) {
queries.add(buildStrataQuery(
- strataTemplate,
+ StringUtils.replace(strataTemplate, "@ageGroupJoin", ""),
new String[] {NULL_STRATA + " as age_group_id", "t1.gender_id", "t1.start_year"},
new String[] {"t1.gender_id", "t1.start_year"}
));
@@ -337,7 +340,7 @@ private String getStrataQueries(String strataTemplate) {
// by year
if (this.design.strataSettings != null && this.design.strataSettings.byYear) {
queries.add(buildStrataQuery(
- strataTemplate,
+ StringUtils.replace(strataTemplate, "@ageGroupJoin", ""),
new String[]{NULL_STRATA + " as age_group_id", NULL_STRATA + "as gender_id", "t1.start_year"},
new String[]{"t1.start_year"}
));
@@ -356,18 +359,27 @@ private String getAgeGroupInsert() {
if (this.design.strataSettings == null || this.design.strataSettings.byAge == false)
return "";
- if (this.design.strataSettings.ageBreaks.isEmpty())
- throw new IllegalArgumentException("Invalid strataSettings: ageBreaks can not be empty.");
+ if (this.design.strataSettings.ageBreaks.isEmpty() &&
+ (this.design.strataSettings.ageBreakList.isEmpty() || this.design.strataSettings.ageBreakList.stream().anyMatch(List::isEmpty)))
+ throw new IllegalArgumentException("Invalid strataSettings: ageBreaks and ageBreaksList can not both be empty.");
ArrayList selects = new ArrayList<>();
- List ageBreaks = this.design.strataSettings.ageBreaks;
- selects.add(String.format(AGE_GROUP_SELECT_TEMPLATE, 1, "<" + ageBreaks.get(0),"null", ageBreaks.get(0)));
+ List> ageBreakList = new ArrayList<>(this.design.strataSettings.ageBreakList);
+ if (!this.design.strataSettings.ageBreaks.isEmpty()) {
+ // put the breaks from ageBreaks in the front of the list (for backwards compatability)
+ ageBreakList.add(0,this.design.strataSettings.ageBreaks);
+ }
- for (int i = 0; i < ageBreaks.size() - 1; i++)
- {
- selects.add(String.format(AGE_GROUP_SELECT_TEMPLATE, i+2, "" + ageBreaks.get(i) + " - " + (ageBreaks.get(i+1)-1),ageBreaks.get(i), ageBreaks.get(i+1)));
+ int ageGroupId = 1;
+ for (List ageBreaks : ageBreakList) {
+ selects.add(String.format(AGE_GROUP_SELECT_TEMPLATE, ageGroupId++, "<" + ageBreaks.get(0),"null", ageBreaks.get(0)));
+
+ for (int i = 0; i < ageBreaks.size() - 1; i++)
+ {
+ selects.add(String.format(AGE_GROUP_SELECT_TEMPLATE, ageGroupId++, "" + ageBreaks.get(i) + " - " + (ageBreaks.get(i+1)-1),ageBreaks.get(i), ageBreaks.get(i+1)));
+ }
+ selects.add(String.format(AGE_GROUP_SELECT_TEMPLATE, ageGroupId++, ">=" + ageBreaks.get(ageBreaks.size()-1),ageBreaks.get(ageBreaks.size()-1), "null"));
}
- selects.add(String.format(AGE_GROUP_SELECT_TEMPLATE, ageBreaks.size()+1, ">=" + ageBreaks.get(ageBreaks.size()-1),ageBreaks.get(ageBreaks.size()-1), "null"));
return String.format("insert into @results_database_schema.age_group_def (ref_id, age_group_id, age_group_name, min_age, max_age)\nselect CAST(@ref_id as int) as ref_id, age_group_id, age_group_name, min_age, max_age from (\n%s\n) ag;",
StringUtils.join(selects, "\nUNION ALL\n"));
diff --git a/java/main/resources/resources/cohortincidence/sql/ageGroupJoin.sql b/java/main/resources/resources/cohortincidence/sql/ageGroupJoin.sql
new file mode 100644
index 0000000..31b6401
--- /dev/null
+++ b/java/main/resources/resources/cohortincidence/sql/ageGroupJoin.sql
@@ -0,0 +1,3 @@
+ LEFT JOIN @results_database_schema.age_group_def ag ON ag.ref_id = @ref_id
+ and t1.age >= coalesce(ag.min_age, -999)
+ and t1.age < coalesce(ag.max_age, 999)
\ No newline at end of file
diff --git a/java/main/resources/resources/cohortincidence/sql/incidenceAnalysis.sql b/java/main/resources/resources/cohortincidence/sql/incidenceAnalysis.sql
index ebe4217..0b6c445 100644
--- a/java/main/resources/resources/cohortincidence/sql/incidenceAnalysis.sql
+++ b/java/main/resources/resources/cohortincidence/sql/incidenceAnalysis.sql
@@ -231,7 +231,7 @@ FROM (
/*
5) aggregate tar and excluded+outcome
*/
-WITH tar_overall (target_cohort_definition_id, tar_id, subgroup_id, subject_id, start_date, end_date, age_group_id, gender_id, start_year)
+WITH tar_overall (target_cohort_definition_id, tar_id, subgroup_id, subject_id, start_date, end_date, age, gender_id, start_year)
AS (
SELECT te.cohort_definition_id as target_cohort_definition_id,
te.tar_id,
@@ -239,14 +239,11 @@ AS (
te.subject_id,
te.start_date,
te.end_date,
- ag.age_group_id,
+ YEAR(te.start_date) - p.year_of_birth as age,
p.gender_concept_id as gender_id,
YEAR(te.start_date) as start_year
FROM #TTAR_erafied te
JOIN @cdm_database_schema.person p on te.subject_id = p.person_id
- LEFT JOIN @results_database_schema.age_group_def ag ON YEAR(te.start_date) - p.year_of_birth >= coalesce(ag.min_age, -999)
- and YEAR(te.start_date) - p.year_of_birth < coalesce(ag.max_age, 999)
- and ag.ref_id = @ref_id
)
select target_cohort_definition_id, tar_id, subgroup_id, age_group_id, gender_id, start_year, person_days_pe, persons_at_risk_pe
INTO #tar_agg
@@ -255,7 +252,7 @@ FROM (
) T_OVERALL
;
-WITH outcomes_overall (target_cohort_definition_id, tar_id, subgroup_id, outcome_id, subject_id, age_group_id, gender_id, start_year, excluded_days, tar_days, outcomes_pe, outcomes)
+WITH outcomes_overall (target_cohort_definition_id, tar_id, subgroup_id, outcome_id, subject_id, age, gender_id, start_year, excluded_days, tar_days, outcomes_pe, outcomes)
AS (
SELECT
t1.cohort_definition_id as target_cohort_definition_id,
@@ -263,7 +260,7 @@ WITH outcomes_overall (target_cohort_definition_id, tar_id, subgroup_id, outcome
t1.subgroup_id,
op.outcome_id,
t1.subject_id,
- ag.age_group_id,
+ YEAR(t1.start_date) - p.year_of_birth as age,
p.gender_concept_id as gender_id,
YEAR(t1.start_date) as start_year,
coalesce(e1.person_days, 0) as excluded_days,
@@ -272,9 +269,6 @@ WITH outcomes_overall (target_cohort_definition_id, tar_id, subgroup_id, outcome
coalesce(o1.outcomes, 0) as outcomes
FROM #TTAR_erafied t1
JOIN @cdm_database_schema.person p ON t1.subject_id = p.person_id
- LEFT JOIN @results_database_schema.age_group_def ag ON YEAR(t1.start_date) - p.year_of_birth >= coalesce(ag.min_age, -999)
- AND YEAR(t1.start_date) - p.year_of_birth < coalesce(ag.max_age, 999)
- AND ag.ref_id = @ref_id
JOIN ( -- get the list of TTSO of anyone with excluded time or outcomes to limit result
select target_cohort_definition_id, tar_id, subgroup_id, outcome_id, subject_id, start_date FROM #excluded_person_days
UNION -- will remove dupes
diff --git a/java/main/resources/resources/cohortincidence/sql/outcomeStrataQueryTemplate.sql b/java/main/resources/resources/cohortincidence/sql/outcomeStrataQueryTemplate.sql
index 60a149b..e746d7f 100644
--- a/java/main/resources/resources/cohortincidence/sql/outcomeStrataQueryTemplate.sql
+++ b/java/main/resources/resources/cohortincidence/sql/outcomeStrataQueryTemplate.sql
@@ -12,4 +12,5 @@
SUM(t1.outcomes_pe) as outcomes_pe,
SUM(t1.outcomes) as outcomes
FROM outcomes_overall t1
+@ageGroupJoin
GROUP BY target_cohort_definition_id, tar_id, subgroup_id, outcome_id@groupCols
\ No newline at end of file
diff --git a/java/main/resources/resources/cohortincidence/sql/tarStrataQueryTemplate.sql b/java/main/resources/resources/cohortincidence/sql/tarStrataQueryTemplate.sql
index 850a2fd..7a25dca 100644
--- a/java/main/resources/resources/cohortincidence/sql/tarStrataQueryTemplate.sql
+++ b/java/main/resources/resources/cohortincidence/sql/tarStrataQueryTemplate.sql
@@ -5,4 +5,5 @@
SUM(CAST((DATEDIFF(day,t1.start_date,t1.end_date) + 1) as bigint)) as person_days_pe,
COUNT(distinct t1.subject_id) as persons_at_risk_pe
FROM tar_overall t1
+@ageGroupJoin
GROUP BY t1.target_cohort_definition_id, t1.tar_id, t1.subgroup_id@groupCols
\ No newline at end of file
diff --git a/java/test/java/org/ohdsi/cohortincidence/Incidence_5_0_Test.java b/java/test/java/org/ohdsi/cohortincidence/Incidence_5_0_Test.java
index cb0fd33..214bd9e 100644
--- a/java/test/java/org/ohdsi/cohortincidence/Incidence_5_0_Test.java
+++ b/java/test/java/org/ohdsi/cohortincidence/Incidence_5_0_Test.java
@@ -398,6 +398,35 @@ public void strataByAgeTest() throws Exception {
this.executeTest(params);
}
+ /**
+ * Tests multiple people with different age/gender/year strata, but only requests by-age strata
+ * Person 1: Male, 2 outcomes, 1 excluded, 2 TARs (age 32 and 37).
+ * Person 2: Female, 2 outcomes, 0 excluded, 2 TARs (age 35 and 37)
+ * Special notes: Person 1 will start in 1 year but have the TAR exclusion make followup start in next year
+ * to test that start_year is correct (it should use the erafied-start date)
+ *
+ * @throws Exception
+ */
+ @Test
+ public void strataByAgeBreakListTest() throws Exception {
+ TestParams params = new TestParams();
+
+ params.resultSchema = "strata_age_list"; // this must be all lower case for DBUnit to work
+ params.prepDataSets = new String[]{
+ "/datasets/vocabulary.json",
+ "/cohortincidence/timeAtRisk/strataByAgeBreakList_PREP.json"
+ };
+ params.designJson = ResourceHelper.GetResourceAsString("/cohortincidence/timeAtRisk/strataByAgeBreakListTest.json");
+ params.verifyDataSets = new String[]{"/cohortincidence/timeAtRisk/strataByAgeBreakList_VERIFY.json"};
+ params.verifyCols = Arrays.asList(new String[]{COL_REF_ID, COL_TARGET_COHORT_ID, COL_TAR_ID, COL_SUBGROUP_ID, COL_OUTCOME_ID,
+ COL_AGE_GROUP_ID, COL_GENDER_ID, COL_YEAR_ID,
+ COL_PERSONS_PRE_EXCLUDE, COL_PERSONS_AT_RISK, COL_PERSONS_DAYS_PRE_EXCLUDE, COL_PERSON_DAYS,
+ COL_PERSON_OUTCOMES_PRE_EXCLUDE, COL_PERSON_OUTCOMES, COL_OUTCOMES_PRE_EXCLUDE, COL_OUTCOMES,
+ COL_INCIDENCE_PROPORTION_P100P, COL_INCIDENCE_RATE_P100PY});
+
+ this.executeTest(params);
+ }
+
/**
* Tests multiple people with different age/gender/year strata, but only requests by-age strata
* Person 1: Male, 2 outcomes, 1 excluded, 2 TARs (age 32 and 37).
diff --git a/java/test/resources/cohortincidence/timeAtRisk/strataByAgeBreakListTest.json b/java/test/resources/cohortincidence/timeAtRisk/strataByAgeBreakListTest.json
new file mode 100644
index 0000000..dd5527a
--- /dev/null
+++ b/java/test/resources/cohortincidence/timeAtRisk/strataByAgeBreakListTest.json
@@ -0,0 +1,43 @@
+{
+ "targetDefs": [
+ {
+ "id": 100,
+ "name": "Target Cohort 1"
+ }
+ ],
+ "outcomeDefs": [
+ {
+ "id": 1,
+ "name": "Outcome Cohort 1",
+ "cohortId": 200,
+ "cleanWindow": 30
+ }
+ ],
+ "timeAtRiskDefs": [
+ {
+ "id": 1,
+ "start": {
+ "dateField": "start",
+ "offset": 0
+ },
+ "end": {
+ "dateField": "start",
+ "offset": 90
+ }
+ }
+ ],
+ "strataSettings": {
+ "byAge": true,
+ "byGender": false,
+ "byYear": false,
+ "ageBreaks": [17, 35, 65],
+ "ageBreakList": [[17], [35], [65]]
+ },
+ "analysisList": [
+ {
+ "targets": [100],
+ "outcomes": [1],
+ "tars": [1]
+ }
+ ]
+}
diff --git a/java/test/resources/cohortincidence/timeAtRisk/strataByAgeBreakList_PREP.json b/java/test/resources/cohortincidence/timeAtRisk/strataByAgeBreakList_PREP.json
new file mode 100644
index 0000000..2401c02
--- /dev/null
+++ b/java/test/resources/cohortincidence/timeAtRisk/strataByAgeBreakList_PREP.json
@@ -0,0 +1,95 @@
+{
+ "cdm.person": [
+ {
+ "person_id": 1,
+ "gender_concept_id": 8507,
+ "year_of_birth": 1970,
+ "race_concept_id": 0,
+ "ethnicity_concept_id": 0
+ },
+ {
+ "person_id": 2,
+ "gender_concept_id": 8532,
+ "year_of_birth": 1968,
+ "race_concept_id": 0,
+ "ethnicity_concept_id": 0
+ }
+ ],
+ "cdm.observation_period": [
+ {
+ "observation_period_id": 1,
+ "person_id": 1,
+ "observation_period_start_date": "2000-01-01",
+ "observation_period_end_date": "2010-01-01",
+ "period_type_concept_id": 0
+ },{
+ "observation_period_id": 2,
+ "person_id": 2,
+ "observation_period_start_date": "2000-01-01",
+ "observation_period_end_date": "2010-01-01",
+ "period_type_concept_id": 0
+ }
+ ],
+ "strata_age_list.cohort": [
+ {
+ "cohort_definition_id": 100,
+ "subject_id": 1,
+ "cohort_start_date": "2002-12-25",
+ "cohort_end_date": "2002-12-25"
+ },
+ {
+ "cohort_definition_id": 100,
+ "subject_id": 1,
+ "cohort_start_date": "2007-03-01",
+ "cohort_end_date": "2007-03-01"
+ },
+ {
+ "cohort_definition_id": 200,
+ "subject_id": 1,
+ "cohort_start_date": "2002-12-15",
+ "cohort_end_date": "2002-12-15"
+ },
+ {
+ "cohort_definition_id": 200,
+ "subject_id": 1,
+ "cohort_start_date": "2003-02-15",
+ "cohort_end_date": "2003-02-15"
+ },
+ {
+ "cohort_definition_id": 200,
+ "subject_id": 1,
+ "cohort_start_date": "2007-04-01",
+ "cohort_end_date": "2007-04-01"
+ },
+ {
+ "cohort_definition_id": 200,
+ "subject_id": 1,
+ "cohort_start_date": "2007-04-05",
+ "cohort_end_date": "2007-04-05"
+ },
+ {
+ "cohort_definition_id": 100,
+ "subject_id": 2,
+ "cohort_start_date": "2003-03-01",
+ "cohort_end_date": "2003-03-01"
+ },
+ {
+ "cohort_definition_id": 100,
+ "subject_id": 2,
+ "cohort_start_date": "2005-03-01",
+ "cohort_end_date": "2005-03-01"
+ },
+ {
+ "cohort_definition_id": 200,
+ "subject_id": 2,
+ "cohort_start_date": "2003-02-01",
+ "cohort_end_date": "2003-02-01"
+ },
+ {
+ "cohort_definition_id": 200,
+ "subject_id": 2,
+ "cohort_start_date": "2003-05-01",
+ "cohort_end_date": "2003-05-01"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/java/test/resources/cohortincidence/timeAtRisk/strataByAgeBreakList_VERIFY.json b/java/test/resources/cohortincidence/timeAtRisk/strataByAgeBreakList_VERIFY.json
new file mode 100644
index 0000000..20921a0
--- /dev/null
+++ b/java/test/resources/cohortincidence/timeAtRisk/strataByAgeBreakList_VERIFY.json
@@ -0,0 +1,144 @@
+{
+ "strata_age_list.incidence_summary": [
+ {
+ "ref_id": 1,
+ "target_cohort_definition_id": 100,
+ "tar_id": 1,
+ "subgroup_id": 0,
+ "outcome_id": 1,
+ "age_group_id": 2,
+ "gender_id": null,
+ "start_year": null,
+ "persons_at_risk_pe": 1,
+ "persons_at_risk": 1,
+ "person_days_pe": 91,
+ "person_days": 40,
+ "person_outcomes_pe": 1,
+ "person_outcomes": 1,
+ "outcomes_pe": 1,
+ "outcomes": 1,
+ "incidence_proportion_p100p": 100,
+ "incidence_rate_p100py": 913.125
+ },
+ {
+ "ref_id": 1,
+ "target_cohort_definition_id": 100,
+ "tar_id": 1,
+ "subgroup_id": 0,
+ "outcome_id": 1,
+ "age_group_id": 3,
+ "gender_id": null,
+ "start_year": null,
+ "persons_at_risk_pe": 2,
+ "persons_at_risk": 2,
+ "person_days_pe": 273,
+ "person_days": 207,
+ "person_outcomes_pe": 2,
+ "person_outcomes": 2,
+ "outcomes_pe": 3,
+ "outcomes": 2,
+ "incidence_proportion_p100p": 100,
+ "incidence_rate_p100py": 352.8986
+ },
+ {
+ "ref_id": 1,
+ "target_cohort_definition_id": 100,
+ "tar_id": 1,
+ "subgroup_id": 0,
+ "outcome_id": 1,
+ "age_group_id": 6,
+ "gender_id": null,
+ "start_year": null,
+ "persons_at_risk_pe": 2,
+ "persons_at_risk": 2,
+ "person_days_pe": 364,
+ "person_days": 247,
+ "person_outcomes_pe": 2,
+ "person_outcomes": 2,
+ "outcomes_pe": 4,
+ "outcomes": 3,
+ "incidence_proportion_p100p": 100,
+ "incidence_rate_p100py": 443.6235
+ },
+ {
+ "ref_id": 1,
+ "target_cohort_definition_id": 100,
+ "tar_id": 1,
+ "subgroup_id": 0,
+ "outcome_id": 1,
+ "age_group_id": 7,
+ "gender_id": null,
+ "start_year": null,
+ "persons_at_risk_pe": 1,
+ "persons_at_risk": 1,
+ "person_days_pe": 91,
+ "person_days": 40,
+ "person_outcomes_pe": 1,
+ "person_outcomes": 1,
+ "outcomes_pe": 1,
+ "outcomes": 1,
+ "incidence_proportion_p100p": 100,
+ "incidence_rate_p100py": 913.1250
+ },
+ {
+ "ref_id": 1,
+ "target_cohort_definition_id": 100,
+ "tar_id": 1,
+ "subgroup_id": 0,
+ "outcome_id": 1,
+ "age_group_id": 8,
+ "gender_id": null,
+ "start_year": null,
+ "persons_at_risk_pe": 2,
+ "persons_at_risk": 2,
+ "person_days_pe": 273,
+ "person_days": 207,
+ "person_outcomes_pe": 2,
+ "person_outcomes": 2,
+ "outcomes_pe": 3,
+ "outcomes": 2,
+ "incidence_proportion_p100p": 100,
+ "incidence_rate_p100py": 352.8986
+ },
+ {
+ "ref_id": 1,
+ "target_cohort_definition_id": 100,
+ "tar_id": 1,
+ "subgroup_id": 0,
+ "outcome_id": 1,
+ "age_group_id": 9,
+ "gender_id": null,
+ "start_year": null,
+ "persons_at_risk_pe": 2,
+ "persons_at_risk": 2,
+ "person_days_pe": 364,
+ "person_days": 247,
+ "person_outcomes_pe": 2,
+ "person_outcomes": 2,
+ "outcomes_pe": 4,
+ "outcomes": 3,
+ "incidence_proportion_p100p": 100,
+ "incidence_rate_p100py": 443.6235
+ },
+ {
+ "ref_id": 1,
+ "target_cohort_definition_id": 100,
+ "tar_id": 1,
+ "subgroup_id": 0,
+ "outcome_id": 1,
+ "age_group_id": null,
+ "gender_id": null,
+ "start_year": null,
+ "persons_at_risk_pe": 2,
+ "persons_at_risk": 2,
+ "person_days_pe": 364,
+ "person_days": 247,
+ "person_outcomes_pe": 2,
+ "person_outcomes": 2,
+ "outcomes_pe": 4,
+ "outcomes": 3,
+ "incidence_proportion_p100p": 100,
+ "incidence_rate_p100py": 443.6235
+ }
+ ]
+}
\ No newline at end of file
diff --git a/man/StrataSettings.Rd b/man/StrataSettings.Rd
index e56790f..6021e94 100644
--- a/man/StrataSettings.Rd
+++ b/man/StrataSettings.Rd
@@ -26,6 +26,8 @@ before calling jsonlite::toJSON().
\item{\code{byYear}}{enables stratification by start year of TAR}
\item{\code{ageBreaks}}{a list of age breaks with at least 1 member}
+
+\item{\code{ageBreakList}}{a list of age breaks}
}
\if{html}{\out{}}
}
diff --git a/man/createStrataSettings.Rd b/man/createStrataSettings.Rd
index 31de637..3e868e4 100644
--- a/man/createStrataSettings.Rd
+++ b/man/createStrataSettings.Rd
@@ -4,7 +4,13 @@
\alias{createStrataSettings}
\title{Creates R6 object for StrataSettings}
\usage{
-createStrataSettings(byAge = F, byGender = F, byYear = F, ageBreaks)
+createStrataSettings(
+ byAge = F,
+ byGender = F,
+ byYear = F,
+ ageBreaks,
+ ageBreakList
+)
}
\arguments{
\item{byAge}{a boolean indicating to stratify by age, defaults to F}
diff --git a/pom.xml b/pom.xml
index da490c6..387fa70 100644
--- a/pom.xml
+++ b/pom.xml
@@ -149,7 +149,7 @@
org.ohdsi
standardized-analysis-specs
- 1.5.0
+ 1.6.0-SNAPSHOT
org.springframework.boot
diff --git a/vignettes/using-cohortincidence.Rmd b/vignettes/using-cohortincidence.Rmd
index e4d65fc..cf781f8 100644
--- a/vignettes/using-cohortincidence.Rmd
+++ b/vignettes/using-cohortincidence.Rmd
@@ -119,15 +119,27 @@ The IR design can also include settings to specify if an analysis should be done
To use this function, you create the strata settings with the `CohortIncidence::createStrataSettings)` function:
```{r}
-irDesignWithStrata <- CohortIncidence::createIncidenceDesign(targetDefs = list(t1),
- outcomeDefs = list(o1),
- tars=list(tar1),
- analysisList = list(analysis1),
- subgroups = list(subgroup1),
- #add by age and by gender strata, but don't do by start year.
- strataSettings = CohortIncidence::createStrataSettings(byGender=T, byAge=T, ageBreaks = c(17,34,65)))
+irDesignWithStrata <-
+ CohortIncidence::createIncidenceDesign(
+ targetDefs = list(t1),
+ outcomeDefs = list(o1),
+ tars = list(tar1),
+ analysisList = list(analysis1),
+ subgroups = list(subgroup1),
+ #add by age and by gender strata, but don't do by start year.
+ strataSettings = CohortIncidence::createStrataSettings(
+ byGender = T,
+ byAge = T,
+ ageBreaks = list(17, 34, 65),
+ ageBreakList = list(list(25), list(65))
+ )
+ )
```
+In the above example, thare are 2 ways of specifying the age breaks: ageBreaks and ageBreakList. ageBreaks creates a single age
+break specification, while ageBreakList allows you to specify a list of breaks. All breaks defined in ageBreaks and ageBreakList will be
+used if specified. If byAge is TRUE, you must specify at least one age break specification either in ageBreaks or ageBreakList.
+
## Using executeAnalysis()
If there is no need to see the analysis sql or control the output of the analysis to a permenant table, the `executeAnalysis()` function