refactor: ♻️ update shared primary keys#106
Conversation
| description="The unique identifier of the participant.", | ||
| constraints=sp.ConstraintsProperties(required=True), | ||
| ) | ||
| event_field = sp.FieldProperties( |
There was a problem hiding this comment.
This is still the unique name of the event that we get from the raw data. There is also a numeric event ID, but we would need to look that up separately using another API request.
As for the relationship between events and visits, my understanding is that some events belong to a visit and some don't. So I don't know if adding a visit_id field to all resources makes sense because sometimes this will be empty. There are also forms with consult or week in the name, so that could be equivalent to visit. Maybe event is a broader category (any interaction with the participant) and visit is a particular type of interaction.
There was a problem hiding this comment.
A visit ID should never be empty tho 🤔 Or at least in very few exceptions, like things collected between visits like the adverse events, but that will still have date fields that can line up with the visits. At the least, there should be a visit date.
There was a problem hiding this comment.
What field does this relate to? Would we rename from another field? If so, would be good to put as a comment above the field variable.
There was a problem hiding this comment.
This is from the raw redcap_event_name field, which is given for each row of the raw data. Event is the concept REDCap forms are organised around, visit is one kind of event in this study.
Visit ID can be missing if the row doesn't come from an instrument/form that is associated with a visit. I found about 24 forms like this. I looked at the fields for each to see if there is a date. There are date fields in each (e.g., contact_date, date_dietary_deviation_1, date_diet_consult_1), and some are also clearly associated with a study week or with another type of event (e.g., a consultation or a group meeting).
So we could pull out a date from each form, but it could be a bit faffy because we would need to check which field has the date in each. And then for forms that are associated with a visit, we would need to find the correct visit (based on the form name, event name, or field names) and then find the date for that visit. What do you think?
There was a problem hiding this comment.
I suspect it will be easier to add a 'completed date' field to those that have a missing obvious value. I'd be happy to sit down and go through all the ones that are falling outside the norm.
For some forms a visit or date doesn't make a lot of sense, adverse events for instance, it doesn't really matter when the information was recorded, what everyone will be interested in is when the participant experienced the discomfort. But we can add an internal date to the form so that it captures when the information was recorded.
With the exception of the repeated instruments (like Adverse Events) all data in REDCap will be uniquely identifiable based on the record_id (which here is the participant ID) and the field name. If you have those two things you will be able to say exactly where that piece of information belongs.
| ) | ||
| default_fields = [event_field, center_field] | ||
| primary_key = ["event"] | ||
| submission_field = sp.FieldProperties( |
There was a problem hiding this comment.
This is renamed from redcap_repeat_instance. Not all forms can repeat (= be submitted multiple times for the same participant and the same event), but when they do repeat, this number tells apart the submissions. I put it as a string to match the other IDs.
We can either add this everywhere and set it to 1 where the form doesn't repeat, or add it only for forms that can repeat.
There was a problem hiding this comment.
Yea, I think only for forms that repeat.
There was a problem hiding this comment.
Okay, I made it like that!
I included downloading the list of repeating instruments in the metadata download, so I can check which ones repeat.
| @@ -234,8 +241,15 @@ def _form_to_resource( | |||
| enum=["Copenhagen", "Aarhus", "Odense"], | |||
| ), | |||
| ) | |||
There was a problem hiding this comment.
This field still needs to be more clear what it actually is. How does it relate to visit? Could you try to expand the description to make it clearer what it means? Maybe we can also rename it something clearer 🤔
There was a problem hiding this comment.
My understanding is that an event is a collection of forms/instruments filled in at the same time. I think an event usually corresponds to a patient interaction (e.g., visit, consultation, group meeting, phone call), but it can also be more abstract (e.g., randomisation). So all visits are events but not all events are visits. I think this is why we initially decided not to rename event to visit, but there may be a better name.
@K-Beicher, is this correct?
There was a problem hiding this comment.
Having looked at events in more detail, we have 21 with the following rough breakdown:
- prescreening on the phone
- 10 visits, each tied to a date
- planned and ad-hoc HbA1c measurements
- Stamdata collection (adverse events link here)
- 3 phases that seem to span multiple weeks, each with group meetings and consultations in different weeks
- info from unplanned “extra” contact
- medicine changes
- randomisation
So it looks like an event sometimes has a concrete date (like visits) and sometimes it doesn't (like phases). But individual forms usually have a date field (date of adverse event, date of group meeting, date of medicine change, etc.). However, it's not always obvious which field should be used as the "real" date field because they all have different names and some forms have multiple date fields.
We were also wondering which events have forms that contain medical/useful info (not just admin). Having looked at the fields, I'd say that all of them contain medical data (usually mixed with admin), except for randomisation.
| description="The unique identifier of the participant.", | ||
| constraints=sp.ConstraintsProperties(required=True), | ||
| ) | ||
| event_field = sp.FieldProperties( |
There was a problem hiding this comment.
A visit ID should never be empty tho 🤔 Or at least in very few exceptions, like things collected between visits like the adverse events, but that will still have date fields that can line up with the visits. At the least, there should be a visit date.
| ) | ||
| default_fields = [event_field, center_field] | ||
| primary_key = ["event"] | ||
| submission_field = sp.FieldProperties( |
There was a problem hiding this comment.
Yea, I think only for forms that repeat.
| description="The unique identifier of the participant.", | ||
| constraints=sp.ConstraintsProperties(required=True), | ||
| ) | ||
| event_field = sp.FieldProperties( |
There was a problem hiding this comment.
What field does this relate to? Would we rename from another field? If so, would be good to put as a comment above the field variable.
There was a problem hiding this comment.
Updated all metadata when I downloaded the list of repeating instruments
There was a problem hiding this comment.
If we add more requests, it will probably be worth generalising some logic here.
|
I undid updating the data dict in this PR because it should go in a separate one together with updating the data. |
lwjohnst86
left a comment
There was a problem hiding this comment.
I think we should go with @joelostblom suggestion and wrangle the data first and then extract the metadata and connect what we can with the data dictionary from REDCap. The primary key and connected foreign key aren't well established enough for us to effectively take the REDCap data and get it into the correct resources and format.
I think that we should also be creating some doc to describe how the flow is exactly working between REDCap and the data package, because right now it isn't clear and we're having to do a lot back and forth discussions and clarifications. Those back and forths should be handled in docs. I'll make an issue about that.
For now, I'll convert this into a draft and move into in-progress.
Description
This PR updates the primary keys common to all resources.
Based on my understanding of the situation and our discussions, but very open to comments.
I tried to include all my assumptions.
Closes #95
This PR needs an in-depth review.
Checklist
just run-all