Feature Definition Templates

This section includes description and usage guides for Definition templates. A Definiton is a function that returns a Feature.

buildNofXBase: Basis for N of X pattern

Use this function template to:

  • write another function that answers a question about some count N of events that satisfy a predicate X.

The buildNofXBase template is used a basis for creating new templates with the following pattern:

  1. Filter events to those satisfying two conditions:

    • an interval relation with an AssessmentInterval

    • a provided Predicate (such as containing certain concepts)

  2. Preprocess these events.

  3. Process the events.

  4. Postprocess the events, optionally in conjunction with the AssessmentInterval.

Usage and Examples

example = buildNofXBase combineIntervals (1)
                        (fmap end) (2)
                        (fmap . diff . begin) (3)

The example function above returns another definiton builder that performs this logic:

1 combine the intervals of the input events (collapsing concurring and meeting intervals);
2 get the end of each interval;
3 computes the difference from each end to the begin of the assessment interval.

To then be fully specified as a Definition and used in a project, the example function needs 3 additional inputs:

  1. a function mapping the index interval to an assessment interval.

  2. a predicate function comparing events to the assessment interval.

  3. another predicate function on the events.

For example, the defBaseline180Enrollment below is a Definition that performs the logic of example.

defBaseline180Enrollment = example (makeBaselineMeetsIndex 180) (1)
                                   concur (2)
                                   (containsConcepts ["enrollment"]) (3)
1 Create a baseline interval from the index to 180 units (e.g. days) back in time.
2 Filter to events that concur with the baseline interval and
3 contains the concept "enrollment".
This example assumes the Concept type is Text.

Source code

View source code
buildNofXBase
  :: ( Intervallic i0 a
     , Intervallic i1 a
     , Witherable container0
     , Witherable container1
     )
  => (container0 (Event c m a) -> container1 (i1 a)) -- ^ function mapping a container of events to a container of intervallic intervals (which could be events!)
  -> (container1 (i1 a) -> t) -- ^ function mapping the processed events to an intermediate type
  -> (AssessmentInterval a -> t -> outputType) -- ^ function casting intermediate type to output type with the option to use the assessment interval
  -> (i0 a -> AssessmentInterval a) -- ^ function which maps index interval to interval in which to assess the feature
  -> ComparativePredicateOf2 (AssessmentInterval a) (Event c m a) -- ^ the interval relation of the input events to the assessment interval
  -> Predicate (Event c m a) -- ^ The predicate to filter to Enrollment events (e.g. 'FeatureEvents.isEnrollment')
  -> Definition
       (  Feature indexName (i0 a)
       -> Feature eventsName (container0 (Event c m a))
       -> Feature varName outputType
       )
buildNofXBase runPreProcess runProcess runPostProcess makeAssessmentInterval relation predicate
  = define
    (\index ->
      -- filter events to those satisfying both
      -- the given relation to the assessment interval
      -- AND the given predicate
      filterEvents
          (Predicate (relation (makeAssessmentInterval index)) &&& predicate)
      -- run the preprocessing function
        .> runPreProcess
      -- run the processing function
        .> runProcess
      -- run the postprocessing function
        .> runPostProcess (makeAssessmentInterval index)
    )

buildNofX: Do N events satisfy a predicate X?

Use this template to create a Definition for a Feature that answers the following question:

  • Do N events relating to the assessment interval in some way satisfy the given predicate?

Usage and Examples

TODO

Specialized Versions

buildNofXBool

specialized to return Bool.

buildNofXBinary

specialized to return a stype Binary value.

buildNofXBinaryConcurBaseline

specialized to filter to events that concur with an assessment interval. created by makeBaselineMeetsIndex of a specified duration and a provided predicate.

buildNofConceptsBinaryConcurBaseline

specialized to filter to events that concur with an assessment interval created by makeBaselineMeetsIndex of a specified duration and that have a given set of concepts.

Source code

View source code
buildNofX
  :: (Intervallic i a, Witherable container)
  => (Bool -> outputType) -- ^ casting function
  -> Natural -- ^ minimum number of cases
  -> (i a -> AssessmentInterval a) -- ^ function to transform a 'Cohort.Index' to an 'Cohort.AssessmentInterval'
  -> ComparativePredicateOf2 (AssessmentInterval a) (Event c m a) -- ^ interval predicate
  -> Predicate (Event c m a) -- ^ a predicate on events
  -> Definition
       (  Feature indexName (i a)
       -> Feature eventsName (container (Event c m a))
       -> Feature varName outputType
       )
buildNofX f n = buildNofXBase id (\x -> length x >= naturalToInt n) (const f)

buildNofUniqueBegins: Find the begin of all unique N events

Use this template to create a Definition for a Feature that:

  • filters a list of events to those satisfying both a given predicate and a relate to the assessment interval in the given way;

  • returns the a list of pairs (b, i) where

    • b is the difference between the begin of each unique event and the given assessment interval

    • i is a counter starting from 1

Usage and Examples

TODO

Source code

View source code
buildNofUniqueBegins
  :: (Intervallic i a, IntervalSizeable a b, Witherable container)
  => (i a -> AssessmentInterval a) -- ^ function to transform a 'Cohort.Index' to an 'Cohort.AssessmentInterval'
  -> ComparativePredicateOf2 (AssessmentInterval a) (Event c m a) -- ^ interval predicate
  -> Predicate (Event c m a) -- ^ a predicate on events
  -> Definition
       (  Feature indexName (i a)
       -> Feature eventsName (container (Event c m a))
       -> Feature varName [(b, Natural)]
       )
buildNofUniqueBegins = buildNofXBase
  (fmap (momentize . getInterval))
  (fmap (, 1 :: Natural) .> F.toList .> M.fromList .> M.toList .> \x ->
    uncurry zip (fmap (scanl1 (+)) (unzip x))
  )
  (\window -> fmap (\i -> (diff (begin (fst i)) (begin window), snd i)))

buildNofXWithGap: Do events have a certain gap between them?

Use this template to create a Definition for a Feature that answers:

  • Are there N gaps of at least the given duration between any pair of events that relate to the assessment interval by the given relation and the satisfy the given predicate?

Find two outpatient events separated by at least 7 days is an example.

Usage and Examples

TODO

Source code

View source code
buildNofXWithGap
  :: ( Intervallic i a
     , IntervalSizeable a b
     , IntervalCombinable i a
     , Witherable container
     )
  => (Bool -> outputType)
  -> Natural -- ^ the minimum number of gaps
  -> b -- ^ the minimum duration of a gap
  -> (i a -> AssessmentInterval a)
  -> ComparativePredicateOf2 (AssessmentInterval a) (Event c m a)
  -> Predicate (Event c m a)
  -> Definition
       (  Feature indexName (i a)
       -> Feature eventsName (container (Event c m a))
       -> Feature varName outputType
       )
buildNofXWithGap cast nGaps allowableGap = buildNofXBase
  (-- just need the intervals  
   fmap getInterval
   -- pairGaps needs List input as the container type
                    .> toList)
  (-- get (Maybe) durations of interval gaps between all pairs
     pairGaps
   -- throw away any non-gaps
  .> catMaybes
   -- keep only those gap durations at least the allowableGap
  .> F.filter (>= allowableGap)
   -- are there at least as many events as desired?
  .> \x -> length x >= naturalToInt nGaps
  )
  (const cast)

buildNofXOrNofYWithGap: Is either buildNofX or buildNofXWithGap satisfied?

Use this template to create a Definition for a Feature that answers:

  • Do N events satisfy predicate X?

  • OR are there M gaps of at least the given duration between any pair of events that relate to the assessment interval by the given relation and the satisfy the given predicate Y?

Find two outpatient events separated by at least 7 days or one inpatient event is an example.

Usage and Examples

TODO

Specialized Versions

TODO

Source code

View source code
buildNofXOrMofYWithGap
  :: ( Intervallic i a
     , IntervalSizeable a b
     , IntervalCombinable i a
     , Witherable container
     )
  => (outputType -> outputType -> outputType)
  -> (Bool -> outputType)
  -> Natural -- ^ count passed to 'buildNofX'
  -> Predicate (Event c m a) -- ^ predicate for 'buildNofX' 
  -> Natural -- ^ the minimum number of gaps passed to 'buildNofXWithGap'
  -> b -- ^ the minimum duration of a gap passed to 'buildNofXWithGap'
  -> Predicate (Event c m a) -- ^ predicate for 'buildNofXWithGap' 
  -> ComparativePredicateOf2
       (AssessmentInterval a)
       (Event c m a)
  -> (i a -> AssessmentInterval a)
  -> Definition
       (  Feature indexName (i a)
       -> Feature
            eventsName
            (container (Event c m a))
       -> Feature varName outputType
       )
buildNofXOrMofYWithGap f cast xCount xPred gapCount gapDuration yPred intervalPred assess
  = D2C f
        (buildNofX cast xCount assess intervalPred xPred)
        (buildNofXWithGap cast gapCount gapDuration assess intervalPred yPred)

buildIsEnrolled: Does an enrollment event concur with index?

Use this template to create a Definition of a Feature for a Status where:

  • you have a predicate for identifying enrollment events;

  • you want to know whether a subject was enrolled (in a health plan, e.g.) at an index time;

  • the result will be used as inclusion/exclusion status.

Usage and Examples

TODO

Source code

View source code
buildIsEnrolled
  :: ( Intervallic i0 a
     , Monoid (container (Interval a))
     , Applicative container
     , Witherable container
     )
  => Predicate (Event c m a) -- ^ The predicate to filter to Enrollment events (e.g. 'FeatureEvents.isEnrollment')
  -> Definition
       (  Feature indexName (i0 a)
       -> Feature eventsName (container (Event c m a))
       -> Feature varName Status
       )
buildIsEnrolled predicate = define
  (\index ->
    F.filterEvents predicate
      .> combineIntervals
      .> any (concur index)
      .> includeIf
  )

buildContinuousEnrollment: Does a sequence of enrollment events continuously occur?

Use this template to create a Definition of a Feature for a "continuous enrollment" Status where:

  • you have a predicate for identifying enrollment events;

  • you want to know whether a subject was enrolled (in a health plan, e.g.) during some assessment interval with the possibility for an allowable gap in enrollment;

  • the result will be used as inclusion/exclusion status.

Usage and Examples

TODO

Source code

View source code
buildContinuousEnrollment
  :: ( Monoid (container (Interval a))
     , Monoid (container (Maybe (Interval a)))
     , Applicative container
     , Witherable container
     , IntervalSizeable a b
     )
  => (i0 a -> AssessmentInterval a) -- ^ function which maps index interval to interval in which to assess enrollment
  -> Predicate (Event c m a)  -- ^ The predicate to filter to events (e.g. 'FeatureEvents.isEnrollment')
  -> b  -- ^ duration of allowable gap between intervals
  ->
    {- tag::templateDefSig0 [] -}
     Definition
       (  Feature indexName (i0 a)
       -> Feature eventsName (container (Event c m a))
       -> Feature prevName Status
       -> Feature varName Status
       )
    {- end::templateDefSig0 [] -}
buildContinuousEnrollment makeAssessmentInterval predicate allowableGap =
  define
    (\index events prevStatus -> case prevStatus of
      Exclude -> Exclude
      Include -> includeIf
        (makeGapsWithinPredicate
          all
          (<)
          allowableGap
          (makeAssessmentInterval index)
          (combineIntervals $ F.filterEvents predicate events)
        )
    )