I'm working on creating patient trajectories using neo4j. I have been successful with a single patient trajectory and can use the timestamp to create a "NEXT_EVENT" relationship. This works well for a single patient and single encounter (hospital visit), but I'm having some issues when I try to loop through patients, then encounter and create the timestamps relationships. My goal is to identify the encounters and create the relationships via the timestamp, similar to creating a timeseries/timeline for each patient encounter.
This is the example on the single patient:
// Create patient node
CREATE (p:Patient {patientID: "P001", name: "John Doe", birthdate: "1980-01-01"})
// Create encounter node
CREATE (e:Encounter {encounterID: "E001", patientID: "P001", timestamp: "2023-03-01T00:00:00", startTime: "2023-03-01T00:00:00", endTime: "2023-03-10T00:00:00"})
// Create relationships between patient, encounter, and other nodes
MATCH (p:Patient {patientID: "P001"})
MATCH (e:Encounter {encounterID: "E001"})
CREATE (p)-[:HAS_ENCOUNTER]->(e)
// Create nodes for a single patient and their components
CREATE (a:Admission {patientID: "P001", timestamp: "2023-03-01T01:00:00"})
CREATE (d:Discharge {patientID: "P001", timestamp: "2023-03-10T00:00:00"})
CREATE (dx:Diagnosis {patientID: "P001", diagnosis: "Diabetes", timestamp: "2023-03-01T02:00:00"})
CREATE (vs1:VitalSign {vitalSignID: "VS001", testName: "Blood Pressure", timestamp: "2023-03-01T10:00:00", systolic: 120, diastolic: 80})
CREATE (vs2:VitalSign {vitalSignID: "VS002", testName: "Heart Rate", timestamp: "2023-03-01T10:00:00", value: 75})
CREATE (pr1:Procedure {procedureID: "PR001", procedureName: "ECG", timestamp: "2023-03-01T15:00:00"})
CREATE (mo1:MedicationOrder {orderID: "M001", medicationName: "Lisinopril", dosage: "10mg", timestamp: "2023-03-02T08:00:00"})
CREATE (lo1:LabOrder {orderID: "L001", testName: "CBC", timestamp: "2023-03-02T09:00:00"})
CREATE (hgb:Component {componentID: "C001", testName: "Hemoglobin", timestamp: "2023-03-02T12:00:00", value: 12.5})
CREATE (hct:Component {componentID: "C002", testName: "Hematocrit", timestamp: "2023-03-02T12:00:00", value: 36.0})
CREATE (mo2:MedicationOrder {orderID: "M002", medicationName: "Metformin", dosage: "500mg", timestamp: "2023-03-03T10:00:00"})
CREATE (pr2:Procedure {procedureID: "PR002", procedureName: "IV insertion", timestamp: "2023-03-03T10:00:00"})
CREATE (lo2:LabOrder {orderID: "L002", testName: "BMP", timestamp: "2023-03-04T14:00:00"})
CREATE (na:Component {componentID: "C003", testName: "Sodium", timestamp: "2023-03-04T17:00:00", value: 140})
CREATE (k:Component {componentID: "C004", testName: "Potassium", timestamp: "2023-03-04T17:00:00", value: 4.0})
CREATE (cl:Component {componentID: "C005", testName: "Chloride", timestamp: "2023-03-04T17:00:00", value: 100})
MATCH (e:Encounter {encounterID: "E001"})
MATCH (a:Admission)
CREATE (e)-[:HAS_ADMISSION]->(a)
// Create NEXT_EVENT relationships based on timestamps
MATCH (n)
WHERE n:Encounter OR n:Admission OR n:Diagnosis OR n:MedicationOrder OR n:LabOrder OR n:Procedure OR n:VitalSign OR n:Component OR n:Discharge
WITH n.timestamp AS ts, collect(n) AS nodes_at_timestamp
ORDER BY ts
WITH collect({ts: ts, nodes: nodes_at_timestamp}) AS timestamp_groups
UNWIND range(0, size(timestamp_groups) - 2) AS i
WITH timestamp_groups[i] AS group1, timestamp_groups[i + 1] AS group2
UNWIND group1.nodes AS n1
UNWIND group2.nodes AS n2
CREATE (n1)-[:NEXT_EVENT]->(n2)
/////
When I have more than one patient and multiple encounters, I struggle with the loop.
Examples:
// Create patient nodes
CREATE (p1:Patient {patientID: "P001", name: "John Doe", birthdate: "1980-01-01"})
CREATE (p2:Patient {patientID: "P002", name: "Jane Doe", birthdate: "1985-01-01"})
// Create encounter nodes for each patient
CREATE (e1:Encounter {encounterID: "E001", patientID: "P001", timestamp: "2023-03-01T00:00:00", startTime: "2023-03-01T00:00:00", endTime: "2023-03-10T00:00:00"})
CREATE (e2:Encounter {encounterID: "E002", patientID: "P001", timestamp: "2023-04-01T08:00:00", startTime: "2023-04-01T00:00:00", endTime: "2023-04-10T00:00:00"})
CREATE (e3:Encounter {encounterID: "E003", patientID: "P002", timestamp: "2023-02-01T00:00:00", startTime: "2023-02-01T00:00:00", endTime: "2023-02-10T00:00:00"})
CREATE (e4:Encounter {encounterID: "E004", patientID: "P002", timestamp: "2023-03-01T08:00:00", startTime: "2023-03-01T00:00:00", endTime: "2023-03-10T00:00:00"})
//Encounter 1 - Patient 1
// Create nodes for Encounter 1
CREATE (a1:Admission {patientID: "P001", encounterID: "E001", timestamp: "2023-03-01T01:00:00", location: "ICU"})
CREATE (d1:Discharge {patientID: "P001", encounterID: "E001", timestamp: "2023-03-06T00:00:00", disposition: "Home"})
CREATE (dx1:Diagnosis {patientID: "P001", encounterID: "E001", diagnosis: "Diabetes", timestamp: "2023-03-01T02:00:00"})
CREATE (vs1:VitalSign {patientID: "P001", encounterID: "E001", vitalSignID: "VS001", testName: "Blood Pressure", timestamp: "2023-03-01T10:00:00", systolic: 120, diastolic: 80})
CREATE (vs2:VitalSign {patientID: "P001", encounterID: "E001", vitalSignID: "VS002", testName: "Heart Rate", timestamp: "2023-03-01T10:00:00", value: 75})
...
I tried using this code snippet, but only creates the "NEXT_EVENT" relationship on the first encounter.
// Create NEXT_EVENT relationships based on timestamps
MATCH (e:Encounter)
WITH collect(e) AS encounters
UNWIND encounters AS encounter
MATCH (n)
WHERE (n:Encounter OR n:Admission OR n:Diagnosis OR n:MedicationOrder OR n:LabOrder OR n:Procedure OR n:VitalSign OR n:Component OR n:Discharge)
AND n.encounterID = encounter.encounterID
WITH n.encounterID AS eid, n.timestamp AS ts, collect(n) AS nodes_at_timestamp
ORDER BY eid, ts
WITH eid, collect({ts: ts, nodes: nodes_at_timestamp}) AS timestamp_groups
UNWIND range(0, size(timestamp_groups) - 2) AS i
WITH timestamp_groups[i] AS group1, timestamp_groups[i + 1] AS group2
UNWIND group1.nodes AS n1
UNWIND group2.nodes AS n2
CREATE (n1)-[:NEXT_EVENT]->(n2)
Would appreciate any insight on any error you might see.
G