clinicedc 2.0.11__py3-none-any.whl → 2.0.13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of clinicedc might be problematic. Click here for more details.
- {clinicedc-2.0.11.dist-info → clinicedc-2.0.13.dist-info}/METADATA +2 -1
- {clinicedc-2.0.11.dist-info → clinicedc-2.0.13.dist-info}/RECORD +137 -24
- edc_action_item/migrations/0017_auto_20190305_0123.py +1 -1
- edc_action_item/migrations/0030_edcpermissions.py +1 -1
- edc_action_item/migrations/0041_alter_actionitem_revision_alter_actiontype_revision_and_more.py +86 -0
- edc_adverse_event/migrations/0001_initial.py +1 -1
- edc_adverse_event/migrations/0002_auto_20190802_0059.py +1 -1
- edc_adverse_event/migrations/0008_auto_20220825_0451.py +1 -1
- edc_adverse_event/migrations/0009_auto_20220907_0157.py +1 -1
- edc_adverse_event/migrations/0017_alter_aeactionclassification_revision_and_more.py +77 -0
- edc_adverse_event/model_mixins/hospitaization/hospitalization_model_mixin.py +1 -3
- edc_analytics/__init__.py +3 -0
- edc_analytics/apps.py +8 -0
- edc_analytics/constants.py +26 -0
- edc_analytics/custom_tables/__init__.py +11 -0
- edc_analytics/custom_tables/age.py +72 -0
- edc_analytics/custom_tables/art.py +88 -0
- edc_analytics/custom_tables/bmi.py +125 -0
- edc_analytics/custom_tables/bp.py +103 -0
- edc_analytics/custom_tables/fasting.py +126 -0
- edc_analytics/custom_tables/fbg.py +98 -0
- edc_analytics/custom_tables/fbg_ogtt.py +384 -0
- edc_analytics/custom_tables/gender.py +12 -0
- edc_analytics/custom_tables/hba1c.py +87 -0
- edc_analytics/custom_tables/ogtt.py +95 -0
- edc_analytics/custom_tables/waist.py +105 -0
- edc_analytics/data.py +36 -0
- edc_analytics/row/__init__.py +4 -0
- edc_analytics/row/row_definition.py +43 -0
- edc_analytics/row/row_definitions.py +32 -0
- edc_analytics/row/row_statistics.py +88 -0
- edc_analytics/row/row_statistics_with_gender.py +115 -0
- edc_analytics/stata/__init__.py +1 -0
- edc_analytics/stata/get_stata_labels_from_model.py +44 -0
- edc_analytics/styler.py +93 -0
- edc_analytics/table.py +108 -0
- edc_analytics/urls.py +6 -0
- edc_appointment/migrations/0018_auto_20190305_0123.py +1 -1
- edc_appointment/migrations/0051_alter_appointment_revision_and_more.py +38 -0
- edc_auth/migrations/0001_squashed_0033_alter_userprofile_is_multisite_viewer.py +1 -1
- edc_auth/migrations/0012_auto_20191026_0034.py +1 -1
- edc_auth/migrations/0013_auto_20191026_0055.py +1 -1
- edc_auth/migrations/0025_permissions.py +1 -1
- edc_auth/migrations/0037_alter_edcpermissions_revision_alter_role_revision.py +38 -0
- edc_consent/migrations/0001_initial.py +1 -1
- edc_consent/migrations/0007_alter_edcpermissions_revision.py +26 -0
- edc_crf/migrations/0010_alter_crfstatus_revision.py +26 -0
- edc_dashboard/migrations/0001_initial.py +1 -1
- edc_dashboard/migrations/0007_alter_edcpermissions_revision.py +26 -0
- edc_data_manager/migrations/0001_initial.py +1 -1
- edc_data_manager/migrations/0025_edcpermissions.py +1 -1
- edc_data_manager/migrations/0042_alter_datadictionary_revision_and_more.py +98 -0
- edc_dx/__init__.py +6 -0
- edc_dx/apps.py +5 -0
- edc_dx/diagnoses.py +250 -0
- edc_dx/form_validators/__init__.py +2 -0
- edc_dx/form_validators/diagnosis_form_validator_mixin.py +54 -0
- edc_dx/form_validators/result_form_validator_mixin.py +65 -0
- edc_dx/utils.py +42 -0
- edc_dx_review/__init__.py +0 -0
- edc_dx_review/apps.py +5 -0
- edc_dx_review/auth_objects.py +13 -0
- edc_dx_review/auths.py +12 -0
- edc_dx_review/choices.py +24 -0
- edc_dx_review/constants.py +7 -0
- edc_dx_review/fieldsets.py +47 -0
- edc_dx_review/form_mixins/__init__.py +3 -0
- edc_dx_review/form_mixins/clinical_review_baseline_required_form_mixin.py +25 -0
- edc_dx_review/form_validator_mixins/__init__.py +6 -0
- edc_dx_review/form_validator_mixins/clinical_review_baseline_form_validator_mixin.py +7 -0
- edc_dx_review/form_validator_mixins/clinical_review_followup_form_validator_mixin.py +25 -0
- edc_dx_review/list_data.py +19 -0
- edc_dx_review/medical_date.py +195 -0
- edc_dx_review/migrations/0001_initial.py +307 -0
- edc_dx_review/migrations/0002_diagnosislocations_extra_value_and_more.py +32 -0
- edc_dx_review/migrations/0003_alter_diagnosislocations_options_and_more.py +148 -0
- edc_dx_review/migrations/0004_remove_diagnosislocations_edc_dx_revi_name_a39b40_idx_and_more.py +20 -0
- edc_dx_review/migrations/__init__.py +0 -0
- edc_dx_review/model_mixins/__init__.py +20 -0
- edc_dx_review/model_mixins/clinical_review_baseline_model_mixin.py +25 -0
- edc_dx_review/model_mixins/clinical_review_followup/__init__.py +5 -0
- edc_dx_review/model_mixins/clinical_review_followup/clinical_review_followup_chol_model_mixin.py +54 -0
- edc_dx_review/model_mixins/clinical_review_followup/clinical_review_followup_dm_model_mixin.py +54 -0
- edc_dx_review/model_mixins/clinical_review_followup/clinical_review_followup_hiv_model_mixin.py +54 -0
- edc_dx_review/model_mixins/clinical_review_followup/clinical_review_followup_htn_model_mixin.py +56 -0
- edc_dx_review/model_mixins/clinical_review_followup/clinical_review_followup_model_mixin.py +25 -0
- edc_dx_review/model_mixins/dx_location_model_mixin.py +17 -0
- edc_dx_review/model_mixins/factory/__init__.py +4 -0
- edc_dx_review/model_mixins/factory/baseline_review_model_mixin_factory.py +55 -0
- edc_dx_review/model_mixins/factory/calculate_date.py +43 -0
- edc_dx_review/model_mixins/factory/dx_initial_review_model_mixin_factory.py +97 -0
- edc_dx_review/model_mixins/factory/followup_review_model_mixin_factory.py +39 -0
- edc_dx_review/model_mixins/factory/rx_initial_review_model_mixin_factory.py +69 -0
- edc_dx_review/model_mixins/followup_review/__init__.py +2 -0
- edc_dx_review/model_mixins/followup_review/followup_review_model_mixin.py +22 -0
- edc_dx_review/model_mixins/followup_review/hiv_followup_review_model_mixin.py +32 -0
- edc_dx_review/model_mixins/initial_review/__init__.py +6 -0
- edc_dx_review/model_mixins/initial_review/chol_initial_review_model_mixin.py +34 -0
- edc_dx_review/model_mixins/initial_review/hiv_initial_model_mixins.py +119 -0
- edc_dx_review/model_mixins/initial_review/ncd_initial_review_model_mixin.py +42 -0
- edc_dx_review/models.py +20 -0
- edc_dx_review/radio_fields.py +30 -0
- edc_dx_review/utils.py +220 -0
- edc_export/migrations/0004_auto_20190305_0123.py +1 -1
- edc_export/migrations/0013_edcpermissions.py +1 -1
- edc_export/migrations/0024_alter_datarequest_revision_and_more.py +170 -0
- edc_facility/migrations/0005_healthfacility_healthfacilitytypes_and_more.py +1 -1
- edc_facility/migrations/0018_alter_healthfacility_revision_and_more.py +38 -0
- edc_form_runners/migrations/0006_alter_issue_revision.py +26 -0
- edc_identifier/migrations/0012_alter_identifiermodel_revision.py +26 -0
- edc_lab/migrations/0039_alter_aliquot_revision_alter_box_revision_and_more.py +269 -0
- edc_lab_dashboard/migrations/0006_alter_edcpermissions_revision.py +26 -0
- edc_label/migrations/0008_alter_zpllabeltemplates_revision.py +26 -0
- edc_listboard/migrations/0008_alter_listboard_revision.py +26 -0
- edc_locator/migrations/0042_alter_historicalsubjectlocator_revision_and_more.py +38 -0
- edc_metadata/migrations/0032_alter_crfmetadata_revision_and_more.py +38 -0
- edc_navbar/migrations/0010_alter_edcpermissions_revision.py +26 -0
- edc_notification/migrations/0012_alter_notification_revision.py +26 -0
- edc_offstudy/migrations/0025_alter_historicalsubjectoffstudy_revision_and_more.py +41 -0
- edc_pharmacy/migrations/0091_alter_allocation_revision_alter_assignment_revision_and_more.py +794 -0
- edc_protocol_incident/migrations/0026_alter_historicalprotocoldeviationviolation_revision_and_more.py +65 -0
- edc_pylabels/migrations/0014_alter_labelconfiguration_revision.py +26 -0
- edc_qareports/migrations/0021_alter_edcpermissions_revision_alter_note_revision.py +38 -0
- edc_randomization/migrations/0015_alter_edcpermissions_revision_and_more.py +50 -0
- edc_refusal/migrations/0014_alter_historicalsubjectrefusal_revision_and_more.py +38 -0
- edc_registration/migrations/0034_alter_historicalregisteredsubject_revision_and_more.py +41 -0
- edc_reportable/migrations/0008_alter_gradingdata_revision_and_more.py +110 -0
- edc_review_dashboard/migrations/0007_alter_edcpermissions_revision.py +26 -0
- edc_screening/migrations/0006_alter_edcpermissions_revision.py +26 -0
- edc_sites/migrations/0011_alter_edcpermissions_revision.py +26 -0
- edc_subject_dashboard/migrations/0006_alter_edcpermissions_revision.py +26 -0
- edc_unblinding/migrations/0016_alter_historicalunblindingrequest_revision_and_more.py +65 -0
- edc_visit_schedule/migrations/0021_alter_historicalonschedule_revision_and_more.py +89 -0
- edc_visit_tracking/migrations/0011_alter_historicalsubjectvisit_revision_and_more.py +65 -0
- edc_vitals/model_mixins/blood_pressure_model_mixin.py +1 -0
- {clinicedc-2.0.11.dist-info → clinicedc-2.0.13.dist-info}/WHEEL +0 -0
- {clinicedc-2.0.11.dist-info → clinicedc-2.0.13.dist-info}/licenses/LICENSE +0 -0
edc_action_item/migrations/0041_alter_actionitem_revision_alter_actiontype_revision_and_more.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-24 04:56
|
|
2
|
+
|
|
3
|
+
import django_revision.revision_field
|
|
4
|
+
from django.db import migrations
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
("edc_action_item", "0040_alter_actionitem_report_datetime_and_more"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AlterField(
|
|
15
|
+
model_name="actionitem",
|
|
16
|
+
name="revision",
|
|
17
|
+
field=django_revision.revision_field.RevisionField(
|
|
18
|
+
blank=True,
|
|
19
|
+
default="",
|
|
20
|
+
editable=False,
|
|
21
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
22
|
+
max_length=75,
|
|
23
|
+
verbose_name="Revision",
|
|
24
|
+
),
|
|
25
|
+
),
|
|
26
|
+
migrations.AlterField(
|
|
27
|
+
model_name="actiontype",
|
|
28
|
+
name="revision",
|
|
29
|
+
field=django_revision.revision_field.RevisionField(
|
|
30
|
+
blank=True,
|
|
31
|
+
default="",
|
|
32
|
+
editable=False,
|
|
33
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
34
|
+
max_length=75,
|
|
35
|
+
verbose_name="Revision",
|
|
36
|
+
),
|
|
37
|
+
),
|
|
38
|
+
migrations.AlterField(
|
|
39
|
+
model_name="edcpermissions",
|
|
40
|
+
name="revision",
|
|
41
|
+
field=django_revision.revision_field.RevisionField(
|
|
42
|
+
blank=True,
|
|
43
|
+
default="",
|
|
44
|
+
editable=False,
|
|
45
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
46
|
+
max_length=75,
|
|
47
|
+
verbose_name="Revision",
|
|
48
|
+
),
|
|
49
|
+
),
|
|
50
|
+
migrations.AlterField(
|
|
51
|
+
model_name="historicalactionitem",
|
|
52
|
+
name="revision",
|
|
53
|
+
field=django_revision.revision_field.RevisionField(
|
|
54
|
+
blank=True,
|
|
55
|
+
default="",
|
|
56
|
+
editable=False,
|
|
57
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
58
|
+
max_length=75,
|
|
59
|
+
verbose_name="Revision",
|
|
60
|
+
),
|
|
61
|
+
),
|
|
62
|
+
migrations.AlterField(
|
|
63
|
+
model_name="historicalreference",
|
|
64
|
+
name="revision",
|
|
65
|
+
field=django_revision.revision_field.RevisionField(
|
|
66
|
+
blank=True,
|
|
67
|
+
default="",
|
|
68
|
+
editable=False,
|
|
69
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
70
|
+
max_length=75,
|
|
71
|
+
verbose_name="Revision",
|
|
72
|
+
),
|
|
73
|
+
),
|
|
74
|
+
migrations.AlterField(
|
|
75
|
+
model_name="reference",
|
|
76
|
+
name="revision",
|
|
77
|
+
field=django_revision.revision_field.RevisionField(
|
|
78
|
+
blank=True,
|
|
79
|
+
default="",
|
|
80
|
+
editable=False,
|
|
81
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
82
|
+
max_length=75,
|
|
83
|
+
verbose_name="Revision",
|
|
84
|
+
),
|
|
85
|
+
),
|
|
86
|
+
]
|
|
@@ -4,7 +4,7 @@ import _socket
|
|
|
4
4
|
import django_audit_fields.fields.hostname_modification_field
|
|
5
5
|
import django_audit_fields.fields.userfield
|
|
6
6
|
import django_audit_fields.fields.uuid_auto_field
|
|
7
|
-
import
|
|
7
|
+
import django.utils.timezone
|
|
8
8
|
import django_revision.revision_field
|
|
9
9
|
from django.db import migrations, models
|
|
10
10
|
import django.utils.timezone
|
|
@@ -4,7 +4,7 @@ import _socket
|
|
|
4
4
|
import django_audit_fields.fields.hostname_modification_field
|
|
5
5
|
import django_audit_fields.fields.userfield
|
|
6
6
|
import django_audit_fields.fields.uuid_auto_field
|
|
7
|
-
import
|
|
7
|
+
import django.utils.timezone
|
|
8
8
|
import django_revision.revision_field
|
|
9
9
|
from django.db import migrations, models
|
|
10
10
|
import django.utils.timezone
|
|
@@ -4,7 +4,7 @@ import _socket
|
|
|
4
4
|
import django_audit_fields.fields.hostname_modification_field
|
|
5
5
|
import django_audit_fields.fields.userfield
|
|
6
6
|
import django_audit_fields.fields.uuid_auto_field
|
|
7
|
-
import
|
|
7
|
+
import django.utils.timezone
|
|
8
8
|
import django_revision.revision_field
|
|
9
9
|
from django.db import migrations, models
|
|
10
10
|
import django.utils.timezone
|
|
@@ -4,7 +4,7 @@ import _socket
|
|
|
4
4
|
import django_audit_fields.fields.hostname_modification_field
|
|
5
5
|
import django_audit_fields.fields.userfield
|
|
6
6
|
import django_audit_fields.fields.uuid_auto_field
|
|
7
|
-
import
|
|
7
|
+
import django.utils.timezone
|
|
8
8
|
import django_revision.revision_field
|
|
9
9
|
from django.db import migrations, models
|
|
10
10
|
import django.utils.timezone
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-24 04:56
|
|
2
|
+
|
|
3
|
+
import django_revision.revision_field
|
|
4
|
+
from django.db import migrations
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
(
|
|
11
|
+
"edc_adverse_event",
|
|
12
|
+
"0016_alter_aeactionclassification_device_created_and_more",
|
|
13
|
+
),
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
operations = [
|
|
17
|
+
migrations.AlterField(
|
|
18
|
+
model_name="aeactionclassification",
|
|
19
|
+
name="revision",
|
|
20
|
+
field=django_revision.revision_field.RevisionField(
|
|
21
|
+
blank=True,
|
|
22
|
+
default="",
|
|
23
|
+
editable=False,
|
|
24
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
25
|
+
max_length=75,
|
|
26
|
+
verbose_name="Revision",
|
|
27
|
+
),
|
|
28
|
+
),
|
|
29
|
+
migrations.AlterField(
|
|
30
|
+
model_name="aeclassification",
|
|
31
|
+
name="revision",
|
|
32
|
+
field=django_revision.revision_field.RevisionField(
|
|
33
|
+
blank=True,
|
|
34
|
+
default="",
|
|
35
|
+
editable=False,
|
|
36
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
37
|
+
max_length=75,
|
|
38
|
+
verbose_name="Revision",
|
|
39
|
+
),
|
|
40
|
+
),
|
|
41
|
+
migrations.AlterField(
|
|
42
|
+
model_name="causeofdeath",
|
|
43
|
+
name="revision",
|
|
44
|
+
field=django_revision.revision_field.RevisionField(
|
|
45
|
+
blank=True,
|
|
46
|
+
default="",
|
|
47
|
+
editable=False,
|
|
48
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
49
|
+
max_length=75,
|
|
50
|
+
verbose_name="Revision",
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
|
+
migrations.AlterField(
|
|
54
|
+
model_name="edcpermissions",
|
|
55
|
+
name="revision",
|
|
56
|
+
field=django_revision.revision_field.RevisionField(
|
|
57
|
+
blank=True,
|
|
58
|
+
default="",
|
|
59
|
+
editable=False,
|
|
60
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
61
|
+
max_length=75,
|
|
62
|
+
verbose_name="Revision",
|
|
63
|
+
),
|
|
64
|
+
),
|
|
65
|
+
migrations.AlterField(
|
|
66
|
+
model_name="saereason",
|
|
67
|
+
name="revision",
|
|
68
|
+
field=django_revision.revision_field.RevisionField(
|
|
69
|
+
blank=True,
|
|
70
|
+
default="",
|
|
71
|
+
editable=False,
|
|
72
|
+
help_text="System field. From git repository (tag:branch:commit), project metadata, project toml, project VERSION, or settings.",
|
|
73
|
+
max_length=75,
|
|
74
|
+
verbose_name="Revision",
|
|
75
|
+
),
|
|
76
|
+
),
|
|
77
|
+
]
|
|
@@ -54,9 +54,7 @@ class HospitalizationModelMixin(NonUniqueSubjectIdentifierFieldMixin, models.Mod
|
|
|
54
54
|
)
|
|
55
55
|
|
|
56
56
|
narrative = models.TextField(
|
|
57
|
-
verbose_name="Narrative",
|
|
58
|
-
max_length=500,
|
|
59
|
-
blank=True,
|
|
57
|
+
verbose_name="Narrative", max_length=500, blank=True, default=""
|
|
60
58
|
)
|
|
61
59
|
|
|
62
60
|
class Meta(NonUniqueSubjectIdentifierFieldMixin.Meta):
|
edc_analytics/apps.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
MEAN_95CI = "mean_95ci"
|
|
2
|
+
MEAN_RANGE = "mean_range"
|
|
3
|
+
MEAN_SD = "mean_sd"
|
|
4
|
+
MEDIAN_IQR = "median_iqr"
|
|
5
|
+
MEDIAN_RANGE = "median_range"
|
|
6
|
+
N_MEAN = "n_mean"
|
|
7
|
+
N_ONLY = "n_only"
|
|
8
|
+
N_RANGE = "n_range"
|
|
9
|
+
N_WITH_COL_PROP = "n_with_col_prop"
|
|
10
|
+
N_WITH_ROW_PROP: str = "n_with_row_prop"
|
|
11
|
+
|
|
12
|
+
COUNT_COLUMN = "count"
|
|
13
|
+
TITLE_COLUMN = "title"
|
|
14
|
+
|
|
15
|
+
STATISTICS = [
|
|
16
|
+
MEAN_95CI,
|
|
17
|
+
MEAN_RANGE,
|
|
18
|
+
MEAN_SD,
|
|
19
|
+
MEDIAN_IQR,
|
|
20
|
+
MEDIAN_RANGE,
|
|
21
|
+
N_MEAN,
|
|
22
|
+
N_ONLY,
|
|
23
|
+
N_RANGE,
|
|
24
|
+
N_WITH_COL_PROP,
|
|
25
|
+
N_WITH_ROW_PROP,
|
|
26
|
+
]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .age import AgeTable
|
|
2
|
+
from .art import ArtTable
|
|
3
|
+
from .bmi import BmiTable
|
|
4
|
+
from .bp import BpTable
|
|
5
|
+
from .fasting import FastingTable
|
|
6
|
+
from .fbg import FbgTable
|
|
7
|
+
from .fbg_ogtt import FbgOgttTable
|
|
8
|
+
from .gender import GenderTable
|
|
9
|
+
from .hba1c import HbA1cTable
|
|
10
|
+
from .ogtt import OgttTable
|
|
11
|
+
from .waist import WaistCircumferenceTable
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from edc_constants.constants import FEMALE, MALE
|
|
3
|
+
|
|
4
|
+
from ..constants import MEDIAN_RANGE, N_ONLY, N_WITH_COL_PROP, N_WITH_ROW_PROP
|
|
5
|
+
from ..row import RowDefinition, RowDefinitions
|
|
6
|
+
from ..table import Table
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AgeTable(Table):
|
|
10
|
+
|
|
11
|
+
col_a = FEMALE
|
|
12
|
+
col_b = MALE
|
|
13
|
+
column_name = "gender"
|
|
14
|
+
|
|
15
|
+
def __init__(self, main_df: pd.DataFrame = None):
|
|
16
|
+
super().__init__(colname="age_in_years", main_df=main_df, title="Age (years)")
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def row_definitions(self) -> RowDefinitions:
|
|
20
|
+
df_tmp = self.main_df.copy()
|
|
21
|
+
row_defs = RowDefinitions(reverse_rows=False)
|
|
22
|
+
row0 = RowDefinition(
|
|
23
|
+
title=self.title,
|
|
24
|
+
label=self.default_sublabel,
|
|
25
|
+
condition=(df_tmp[self.column_name].notna()),
|
|
26
|
+
columns={
|
|
27
|
+
self.col_a: (N_ONLY, 2),
|
|
28
|
+
self.col_b: (N_ONLY, 2),
|
|
29
|
+
"All": (N_ONLY, 2),
|
|
30
|
+
},
|
|
31
|
+
drop=False,
|
|
32
|
+
)
|
|
33
|
+
row_defs.add(row0)
|
|
34
|
+
columns = {
|
|
35
|
+
self.col_a: (N_WITH_COL_PROP, 2),
|
|
36
|
+
self.col_b: (N_WITH_COL_PROP, 2),
|
|
37
|
+
"All": (N_WITH_ROW_PROP, 2),
|
|
38
|
+
}
|
|
39
|
+
bin1 = (df_tmp[self.colname] >= 18) & (df_tmp[self.colname] < 35)
|
|
40
|
+
bin2 = (df_tmp[self.colname] >= 35) & (df_tmp[self.colname] < 50)
|
|
41
|
+
bin3 = (df_tmp[self.colname] >= 50) & (df_tmp[self.colname] < 65)
|
|
42
|
+
bin4 = df_tmp[self.colname] >= 65
|
|
43
|
+
row_defs.add(RowDefinition(label="18-34", condition=bin1, columns=columns, drop=False))
|
|
44
|
+
row_defs.add(RowDefinition(label="35-49", condition=bin2, columns=columns, drop=False))
|
|
45
|
+
row_defs.add(RowDefinition(label="50-64", condition=bin3, columns=columns, drop=False))
|
|
46
|
+
row_defs.add(
|
|
47
|
+
RowDefinition(label="65 and older", condition=bin4, columns=columns, drop=False)
|
|
48
|
+
)
|
|
49
|
+
if len(df_tmp[df_tmp[self.colname].isna()]) > 0:
|
|
50
|
+
row_defs.add(
|
|
51
|
+
RowDefinition(
|
|
52
|
+
colname="age_in_years",
|
|
53
|
+
label="not recorded",
|
|
54
|
+
condition=(df_tmp[self.colname].isna()),
|
|
55
|
+
columns=columns,
|
|
56
|
+
drop=False,
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
columns = {
|
|
60
|
+
self.col_a: (MEDIAN_RANGE, 2),
|
|
61
|
+
self.col_b: (MEDIAN_RANGE, 2),
|
|
62
|
+
"All": (MEDIAN_RANGE, 2),
|
|
63
|
+
}
|
|
64
|
+
row_defs.add(
|
|
65
|
+
RowDefinition(
|
|
66
|
+
colname="age_in_years",
|
|
67
|
+
label="Median (range)",
|
|
68
|
+
condition=(self.main_df[self.colname].notna()),
|
|
69
|
+
columns=columns,
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
return row_defs
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from edc_constants.constants import FEMALE, MALE
|
|
3
|
+
|
|
4
|
+
from ..constants import N_ONLY, N_WITH_COL_PROP, N_WITH_ROW_PROP
|
|
5
|
+
from ..row import RowDefinition, RowDefinitions
|
|
6
|
+
from ..table import Table
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ArtTable(Table):
|
|
10
|
+
def __init__(self, main_df: pd.DataFrame = None):
|
|
11
|
+
super().__init__(colname=None, main_df=main_df, title="HIV Care")
|
|
12
|
+
|
|
13
|
+
@property
|
|
14
|
+
def row_definitions(self) -> RowDefinitions:
|
|
15
|
+
df_tmp = self.main_df.copy()
|
|
16
|
+
row_defs = RowDefinitions(reverse_rows=False)
|
|
17
|
+
row0 = RowDefinition(
|
|
18
|
+
title=self.title,
|
|
19
|
+
label=self.default_sublabel,
|
|
20
|
+
condition=(df_tmp["gender"].notna()),
|
|
21
|
+
columns={FEMALE: (N_ONLY, 2), MALE: (N_ONLY, 2), "All": (N_ONLY, 2)},
|
|
22
|
+
drop=False,
|
|
23
|
+
)
|
|
24
|
+
row_defs.add(row0)
|
|
25
|
+
columns = {
|
|
26
|
+
FEMALE: (N_WITH_COL_PROP, 2),
|
|
27
|
+
MALE: (N_WITH_COL_PROP, 2),
|
|
28
|
+
"All": (N_WITH_ROW_PROP, 2),
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
cond_art_stable = (
|
|
32
|
+
(df_tmp["on_rx_stable"] == "Yes")
|
|
33
|
+
& (df_tmp["vl_undetectable"] == "Yes")
|
|
34
|
+
& (df_tmp["art_six_months"] == "Yes")
|
|
35
|
+
)
|
|
36
|
+
row_defs.add(
|
|
37
|
+
RowDefinition(
|
|
38
|
+
label="Stable on ART (6m)",
|
|
39
|
+
condition=cond_art_stable,
|
|
40
|
+
columns=columns,
|
|
41
|
+
drop=True,
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# look for anyone that is not stable by these three values
|
|
46
|
+
condition_partially_stable = (
|
|
47
|
+
(df_tmp["on_rx_stable"] == "Yes")
|
|
48
|
+
| (df_tmp["vl_undetectable"] == "Yes")
|
|
49
|
+
| (df_tmp["art_six_months"] == "Yes")
|
|
50
|
+
)
|
|
51
|
+
row_defs.add(
|
|
52
|
+
RowDefinition(
|
|
53
|
+
label="Other stable (`VL` or `on ART` or `stable 6m`)",
|
|
54
|
+
condition=condition_partially_stable,
|
|
55
|
+
columns=columns,
|
|
56
|
+
drop=True,
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
condition_other = (
|
|
61
|
+
(df_tmp["on_rx_stable"] == "No")
|
|
62
|
+
| (df_tmp["vl_undetectable"] == "No")
|
|
63
|
+
| (df_tmp["art_six_months"] == "No")
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
row_defs.add(
|
|
67
|
+
RowDefinition(
|
|
68
|
+
label="Other",
|
|
69
|
+
condition=condition_other,
|
|
70
|
+
columns=columns,
|
|
71
|
+
drop=True,
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
condition_not_recorded = (
|
|
76
|
+
(df_tmp["on_rx_stable"].isna())
|
|
77
|
+
& (df_tmp["vl_undetectable"].isna())
|
|
78
|
+
& (df_tmp["art_six_months"].isna())
|
|
79
|
+
)
|
|
80
|
+
row_defs.add(
|
|
81
|
+
RowDefinition(
|
|
82
|
+
label="Not recorded",
|
|
83
|
+
condition=condition_not_recorded,
|
|
84
|
+
columns=columns,
|
|
85
|
+
drop=True,
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
return row_defs
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from edc_constants.constants import FEMALE, MALE
|
|
3
|
+
|
|
4
|
+
from ..constants import (
|
|
5
|
+
MEDIAN_IQR,
|
|
6
|
+
MEDIAN_RANGE,
|
|
7
|
+
N_ONLY,
|
|
8
|
+
N_WITH_COL_PROP,
|
|
9
|
+
N_WITH_ROW_PROP,
|
|
10
|
+
)
|
|
11
|
+
from ..row import RowDefinition, RowDefinitions
|
|
12
|
+
from ..table import Table
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BmiTable(Table):
|
|
16
|
+
|
|
17
|
+
colname = "calculated_bmi_value"
|
|
18
|
+
|
|
19
|
+
def __init__(self, main_df: pd.DataFrame = None):
|
|
20
|
+
super().__init__(
|
|
21
|
+
colname="calculated_bmi_value",
|
|
22
|
+
main_df=main_df,
|
|
23
|
+
title="BMI categories (kg/m2)",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def row_definitions(self) -> RowDefinitions:
|
|
28
|
+
df_tmp = self.main_df.copy()
|
|
29
|
+
row_defs = RowDefinitions(reverse_rows=False)
|
|
30
|
+
row0 = RowDefinition(
|
|
31
|
+
title=self.title,
|
|
32
|
+
label=self.default_sublabel,
|
|
33
|
+
condition=(df_tmp["gender"].notna()),
|
|
34
|
+
columns={FEMALE: (N_ONLY, 2), MALE: (N_ONLY, 2), "All": (N_ONLY, 2)},
|
|
35
|
+
drop=False,
|
|
36
|
+
)
|
|
37
|
+
row_defs.add(row0)
|
|
38
|
+
columns = {
|
|
39
|
+
FEMALE: (N_WITH_COL_PROP, 2),
|
|
40
|
+
MALE: (N_WITH_COL_PROP, 2),
|
|
41
|
+
"All": (N_WITH_ROW_PROP, 2),
|
|
42
|
+
}
|
|
43
|
+
row_defs.add(
|
|
44
|
+
RowDefinition(
|
|
45
|
+
colname="calculated_bmi_value",
|
|
46
|
+
label="Less than 18.5",
|
|
47
|
+
condition=(df_tmp[self.colname] < 18.5),
|
|
48
|
+
columns=columns,
|
|
49
|
+
drop=False,
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
row_defs.add(
|
|
53
|
+
RowDefinition(
|
|
54
|
+
colname="calculated_bmi_value",
|
|
55
|
+
label="18.5-24.9",
|
|
56
|
+
condition=(df_tmp[self.colname] >= 18.5) & (df_tmp[self.colname] < 25.0),
|
|
57
|
+
columns=columns,
|
|
58
|
+
drop=False,
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
row_defs.add(
|
|
62
|
+
RowDefinition(
|
|
63
|
+
colname="calculated_bmi_value",
|
|
64
|
+
label="25.0-29.9",
|
|
65
|
+
condition=(df_tmp[self.colname] >= 25.0) & (df_tmp[self.colname] < 30.0),
|
|
66
|
+
columns=columns,
|
|
67
|
+
drop=False,
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
row_defs.add(
|
|
71
|
+
RowDefinition(
|
|
72
|
+
colname="calculated_bmi_value",
|
|
73
|
+
label="30.0-39.9",
|
|
74
|
+
condition=(df_tmp[self.colname] >= 30.0) & (df_tmp[self.colname] < 40.0),
|
|
75
|
+
columns=columns,
|
|
76
|
+
drop=False,
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
row_defs.add(
|
|
80
|
+
RowDefinition(
|
|
81
|
+
colname="calculated_bmi_value",
|
|
82
|
+
label="40 or above",
|
|
83
|
+
condition=(df_tmp[self.colname] >= 40.0),
|
|
84
|
+
columns=columns,
|
|
85
|
+
drop=False,
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
cond = df_tmp[self.colname].isna()
|
|
89
|
+
if len(df_tmp[cond]) > 0:
|
|
90
|
+
row_defs.add(
|
|
91
|
+
RowDefinition(
|
|
92
|
+
colname="calculated_bmi_value",
|
|
93
|
+
label="not measured",
|
|
94
|
+
condition=cond,
|
|
95
|
+
columns=columns,
|
|
96
|
+
drop=False,
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
row_defs.add(
|
|
100
|
+
RowDefinition(
|
|
101
|
+
colname="calculated_bmi_value",
|
|
102
|
+
label="Median (IQR)",
|
|
103
|
+
condition=(df_tmp["gender"].notna()),
|
|
104
|
+
columns={
|
|
105
|
+
FEMALE: (MEDIAN_IQR, 2),
|
|
106
|
+
MALE: (MEDIAN_IQR, 2),
|
|
107
|
+
"All": (MEDIAN_IQR, 2),
|
|
108
|
+
},
|
|
109
|
+
drop=False,
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
row_defs.add(
|
|
113
|
+
RowDefinition(
|
|
114
|
+
colname="calculated_bmi_value",
|
|
115
|
+
label="Median (range)",
|
|
116
|
+
condition=(df_tmp["gender"].notna()),
|
|
117
|
+
columns={
|
|
118
|
+
FEMALE: (MEDIAN_RANGE, 2),
|
|
119
|
+
MALE: (MEDIAN_RANGE, 2),
|
|
120
|
+
"All": (MEDIAN_RANGE, 2),
|
|
121
|
+
},
|
|
122
|
+
drop=False,
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
return row_defs
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from edc_constants.constants import FEMALE, MALE
|
|
3
|
+
|
|
4
|
+
from ..constants import N_ONLY, N_WITH_COL_PROP, N_WITH_ROW_PROP
|
|
5
|
+
from ..row import RowDefinition, RowDefinitions
|
|
6
|
+
from ..table import Table
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BpTable(Table):
|
|
10
|
+
|
|
11
|
+
sys_col_name = "sys_blood_pressure_avg"
|
|
12
|
+
dia_col_name = "dia_blood_pressure_avg"
|
|
13
|
+
|
|
14
|
+
def __init__(self, main_df: pd.DataFrame = None):
|
|
15
|
+
super().__init__(
|
|
16
|
+
colname="",
|
|
17
|
+
main_df=main_df,
|
|
18
|
+
title="Blood pressure at baseline (mmHg)",
|
|
19
|
+
)
|
|
20
|
+
self.table_df = self.table_df.reindex(index=self.table_df.index[::-1])
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def row_definitions(self) -> RowDefinitions:
|
|
24
|
+
df_tmp = self.main_df.copy()
|
|
25
|
+
row_defs = RowDefinitions(reverse_rows=True)
|
|
26
|
+
row0 = RowDefinition(
|
|
27
|
+
title=self.title,
|
|
28
|
+
label=self.default_sublabel,
|
|
29
|
+
condition=(df_tmp["gender"].notna()),
|
|
30
|
+
columns={
|
|
31
|
+
FEMALE: (N_ONLY, 2),
|
|
32
|
+
MALE: (N_ONLY, 2),
|
|
33
|
+
"All": (N_ONLY, 2),
|
|
34
|
+
},
|
|
35
|
+
drop=False,
|
|
36
|
+
)
|
|
37
|
+
row_defs.add(row0)
|
|
38
|
+
columns = {
|
|
39
|
+
FEMALE: (N_WITH_COL_PROP, 2),
|
|
40
|
+
MALE: (N_WITH_COL_PROP, 2),
|
|
41
|
+
"All": (N_WITH_ROW_PROP, 2),
|
|
42
|
+
}
|
|
43
|
+
row_defs.add(
|
|
44
|
+
RowDefinition(
|
|
45
|
+
label="Severe hypertension (>=180/110)",
|
|
46
|
+
condition=(
|
|
47
|
+
(df_tmp[self.sys_col_name] >= 180) | (df_tmp[self.dia_col_name] >= 110)
|
|
48
|
+
),
|
|
49
|
+
columns=columns,
|
|
50
|
+
drop=True,
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
row_defs.add(
|
|
54
|
+
RowDefinition(
|
|
55
|
+
label="Hypertension (>=140/90)",
|
|
56
|
+
condition=(
|
|
57
|
+
(df_tmp[self.sys_col_name] >= 140) | (df_tmp[self.dia_col_name] >= 90)
|
|
58
|
+
),
|
|
59
|
+
columns=columns,
|
|
60
|
+
drop=True,
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
row_defs.add(
|
|
64
|
+
RowDefinition(
|
|
65
|
+
label="Pre-hypertension (<140/90)",
|
|
66
|
+
condition=(
|
|
67
|
+
(df_tmp[self.sys_col_name] >= 120) | (df_tmp[self.dia_col_name] >= 80)
|
|
68
|
+
),
|
|
69
|
+
columns=columns,
|
|
70
|
+
drop=True,
|
|
71
|
+
)
|
|
72
|
+
)
|
|
73
|
+
row_defs.add(
|
|
74
|
+
RowDefinition(
|
|
75
|
+
label="Normal (<120/80)",
|
|
76
|
+
condition=(
|
|
77
|
+
(df_tmp[self.sys_col_name] >= 90) | (df_tmp[self.dia_col_name] >= 60)
|
|
78
|
+
),
|
|
79
|
+
columns=columns,
|
|
80
|
+
drop=True,
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
row_defs.add(
|
|
84
|
+
RowDefinition(
|
|
85
|
+
label="Low (<90/60)",
|
|
86
|
+
condition=(
|
|
87
|
+
(df_tmp[self.sys_col_name] >= 0) | (df_tmp[self.dia_col_name] >= 0)
|
|
88
|
+
),
|
|
89
|
+
columns=columns,
|
|
90
|
+
drop=True,
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
row_defs.add(
|
|
94
|
+
RowDefinition(
|
|
95
|
+
label="not measured",
|
|
96
|
+
condition=(
|
|
97
|
+
(df_tmp[self.sys_col_name].isna()) & (df_tmp[self.dia_col_name].isna())
|
|
98
|
+
),
|
|
99
|
+
columns=columns,
|
|
100
|
+
drop=True,
|
|
101
|
+
)
|
|
102
|
+
)
|
|
103
|
+
return row_defs
|