clinicedc 2.0.12__py3-none-any.whl → 2.0.14__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.

Files changed (101) hide show
  1. {clinicedc-2.0.12.dist-info → clinicedc-2.0.14.dist-info}/METADATA +2 -2
  2. {clinicedc-2.0.12.dist-info → clinicedc-2.0.14.dist-info}/RECORD +101 -24
  3. edc_action_item/migrations/0017_auto_20190305_0123.py +1 -1
  4. edc_action_item/migrations/0030_edcpermissions.py +1 -1
  5. edc_adverse_event/migrations/0001_initial.py +1 -1
  6. edc_adverse_event/migrations/0002_auto_20190802_0059.py +1 -1
  7. edc_adverse_event/migrations/0008_auto_20220825_0451.py +1 -1
  8. edc_adverse_event/migrations/0009_auto_20220907_0157.py +1 -1
  9. edc_adverse_event/model_mixins/hospitaization/hospitalization_model_mixin.py +1 -3
  10. edc_analytics/__init__.py +3 -0
  11. edc_analytics/apps.py +8 -0
  12. edc_analytics/constants.py +26 -0
  13. edc_analytics/custom_tables/__init__.py +11 -0
  14. edc_analytics/custom_tables/age.py +72 -0
  15. edc_analytics/custom_tables/art.py +88 -0
  16. edc_analytics/custom_tables/bmi.py +125 -0
  17. edc_analytics/custom_tables/bp.py +103 -0
  18. edc_analytics/custom_tables/fasting.py +126 -0
  19. edc_analytics/custom_tables/fbg.py +98 -0
  20. edc_analytics/custom_tables/fbg_ogtt.py +384 -0
  21. edc_analytics/custom_tables/gender.py +12 -0
  22. edc_analytics/custom_tables/hba1c.py +87 -0
  23. edc_analytics/custom_tables/ogtt.py +95 -0
  24. edc_analytics/custom_tables/waist.py +105 -0
  25. edc_analytics/data.py +36 -0
  26. edc_analytics/row/__init__.py +4 -0
  27. edc_analytics/row/row_definition.py +43 -0
  28. edc_analytics/row/row_definitions.py +32 -0
  29. edc_analytics/row/row_statistics.py +88 -0
  30. edc_analytics/row/row_statistics_with_gender.py +115 -0
  31. edc_analytics/stata/__init__.py +1 -0
  32. edc_analytics/stata/get_stata_labels_from_model.py +44 -0
  33. edc_analytics/styler.py +93 -0
  34. edc_analytics/table.py +108 -0
  35. edc_analytics/urls.py +6 -0
  36. edc_appointment/migrations/0018_auto_20190305_0123.py +1 -1
  37. edc_auth/migrations/0001_squashed_0033_alter_userprofile_is_multisite_viewer.py +1 -1
  38. edc_auth/migrations/0012_auto_20191026_0034.py +1 -1
  39. edc_auth/migrations/0013_auto_20191026_0055.py +1 -1
  40. edc_auth/migrations/0025_permissions.py +1 -1
  41. edc_consent/migrations/0001_initial.py +1 -1
  42. edc_dashboard/migrations/0001_initial.py +1 -1
  43. edc_data_manager/migrations/0001_initial.py +1 -1
  44. edc_data_manager/migrations/0025_edcpermissions.py +1 -1
  45. edc_dx/__init__.py +6 -0
  46. edc_dx/apps.py +5 -0
  47. edc_dx/diagnoses.py +250 -0
  48. edc_dx/form_validators/__init__.py +2 -0
  49. edc_dx/form_validators/diagnosis_form_validator_mixin.py +54 -0
  50. edc_dx/form_validators/result_form_validator_mixin.py +65 -0
  51. edc_dx/utils.py +42 -0
  52. edc_dx_review/__init__.py +0 -0
  53. edc_dx_review/apps.py +5 -0
  54. edc_dx_review/auth_objects.py +13 -0
  55. edc_dx_review/auths.py +12 -0
  56. edc_dx_review/choices.py +24 -0
  57. edc_dx_review/constants.py +7 -0
  58. edc_dx_review/fieldsets.py +47 -0
  59. edc_dx_review/form_mixins/__init__.py +3 -0
  60. edc_dx_review/form_mixins/clinical_review_baseline_required_form_mixin.py +25 -0
  61. edc_dx_review/form_validator_mixins/__init__.py +6 -0
  62. edc_dx_review/form_validator_mixins/clinical_review_baseline_form_validator_mixin.py +7 -0
  63. edc_dx_review/form_validator_mixins/clinical_review_followup_form_validator_mixin.py +25 -0
  64. edc_dx_review/list_data.py +19 -0
  65. edc_dx_review/medical_date.py +195 -0
  66. edc_dx_review/migrations/0001_initial.py +307 -0
  67. edc_dx_review/migrations/0002_diagnosislocations_extra_value_and_more.py +32 -0
  68. edc_dx_review/migrations/0003_alter_diagnosislocations_options_and_more.py +148 -0
  69. edc_dx_review/migrations/0004_remove_diagnosislocations_edc_dx_revi_name_a39b40_idx_and_more.py +20 -0
  70. edc_dx_review/migrations/__init__.py +0 -0
  71. edc_dx_review/model_mixins/__init__.py +20 -0
  72. edc_dx_review/model_mixins/clinical_review_baseline_model_mixin.py +25 -0
  73. edc_dx_review/model_mixins/clinical_review_followup/__init__.py +5 -0
  74. edc_dx_review/model_mixins/clinical_review_followup/clinical_review_followup_chol_model_mixin.py +54 -0
  75. edc_dx_review/model_mixins/clinical_review_followup/clinical_review_followup_dm_model_mixin.py +54 -0
  76. edc_dx_review/model_mixins/clinical_review_followup/clinical_review_followup_hiv_model_mixin.py +54 -0
  77. edc_dx_review/model_mixins/clinical_review_followup/clinical_review_followup_htn_model_mixin.py +56 -0
  78. edc_dx_review/model_mixins/clinical_review_followup/clinical_review_followup_model_mixin.py +25 -0
  79. edc_dx_review/model_mixins/dx_location_model_mixin.py +17 -0
  80. edc_dx_review/model_mixins/factory/__init__.py +4 -0
  81. edc_dx_review/model_mixins/factory/baseline_review_model_mixin_factory.py +55 -0
  82. edc_dx_review/model_mixins/factory/calculate_date.py +43 -0
  83. edc_dx_review/model_mixins/factory/dx_initial_review_model_mixin_factory.py +97 -0
  84. edc_dx_review/model_mixins/factory/followup_review_model_mixin_factory.py +39 -0
  85. edc_dx_review/model_mixins/factory/rx_initial_review_model_mixin_factory.py +69 -0
  86. edc_dx_review/model_mixins/followup_review/__init__.py +2 -0
  87. edc_dx_review/model_mixins/followup_review/followup_review_model_mixin.py +22 -0
  88. edc_dx_review/model_mixins/followup_review/hiv_followup_review_model_mixin.py +32 -0
  89. edc_dx_review/model_mixins/initial_review/__init__.py +6 -0
  90. edc_dx_review/model_mixins/initial_review/chol_initial_review_model_mixin.py +34 -0
  91. edc_dx_review/model_mixins/initial_review/hiv_initial_model_mixins.py +119 -0
  92. edc_dx_review/model_mixins/initial_review/ncd_initial_review_model_mixin.py +42 -0
  93. edc_dx_review/models.py +20 -0
  94. edc_dx_review/radio_fields.py +30 -0
  95. edc_dx_review/utils.py +220 -0
  96. edc_export/migrations/0004_auto_20190305_0123.py +1 -1
  97. edc_export/migrations/0013_edcpermissions.py +1 -1
  98. edc_facility/migrations/0005_healthfacility_healthfacilitytypes_and_more.py +1 -1
  99. edc_vitals/model_mixins/blood_pressure_model_mixin.py +1 -0
  100. {clinicedc-2.0.12.dist-info → clinicedc-2.0.14.dist-info}/WHEEL +0 -0
  101. {clinicedc-2.0.12.dist-info → clinicedc-2.0.14.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,384 @@
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 FbgOgttTable1(Table):
10
+
11
+ fbg_colname = "fbg"
12
+ ogtt_colname = "ogtt"
13
+
14
+ def __init__(self, main_df: pd.DataFrame = None):
15
+ super().__init__(
16
+ colname="",
17
+ main_df=main_df,
18
+ title="OGTT & FBG (mmol/L) categories",
19
+ )
20
+
21
+ @property
22
+ def row_definitions(self) -> RowDefinitions:
23
+ df_tmp = self.main_df.copy()
24
+ row_defs = RowDefinitions(reverse_rows=False)
25
+ row0 = RowDefinition(
26
+ title=self.title,
27
+ label=self.default_sublabel,
28
+ condition=(df_tmp["gender"].notna()),
29
+ columns={FEMALE: (N_ONLY, 2), MALE: (N_ONLY, 2), "All": (N_ONLY, 2)},
30
+ drop=False,
31
+ )
32
+ row_defs.add(row0)
33
+ columns = {
34
+ FEMALE: (N_WITH_COL_PROP, 2),
35
+ MALE: (N_WITH_COL_PROP, 2),
36
+ "All": (N_WITH_ROW_PROP, 2),
37
+ }
38
+
39
+ row_defs.add(
40
+ RowDefinition(
41
+ colname=self.colname,
42
+ label="Not fasted",
43
+ condition=(
44
+ (self.main_df["fasting_fbg_hrs"] < 8.0)
45
+ | (self.main_df["fasting_ogtt_hrs"] < 8.0)
46
+ ),
47
+ columns=columns,
48
+ drop=True,
49
+ )
50
+ )
51
+
52
+ condition = (
53
+ (self.main_df[self.ogtt_colname] >= 11.1)
54
+ & (self.main_df[self.fbg_colname] >= 7.0)
55
+ & (self.main_df[self.ogtt_colname].notna())
56
+ & (self.main_df[self.fbg_colname].notna())
57
+ )
58
+ row_defs.add(
59
+ RowDefinition(
60
+ colname=self.colname,
61
+ label="OGTT ≥11.1 and FBG ≥7.0",
62
+ condition=condition,
63
+ columns=columns,
64
+ drop=True,
65
+ )
66
+ )
67
+
68
+ condition = (
69
+ ((df_tmp[self.ogtt_colname] >= 11.1) | (df_tmp[self.fbg_colname] >= 7.0))
70
+ & (df_tmp[self.fbg_colname].notna())
71
+ & (df_tmp[self.ogtt_colname].notna())
72
+ )
73
+
74
+ row_defs.add(
75
+ RowDefinition(
76
+ colname=self.colname,
77
+ label="OGTT ≥11.1 or FBG ≥7.0",
78
+ condition=condition,
79
+ columns=columns,
80
+ drop=True,
81
+ )
82
+ )
83
+
84
+ condition = (
85
+ ((df_tmp[self.fbg_colname] >= 6.1) | (df_tmp[self.ogtt_colname] >= 7.8))
86
+ & (df_tmp[self.fbg_colname].notna())
87
+ & (df_tmp[self.ogtt_colname].notna())
88
+ )
89
+ row_defs.add(
90
+ RowDefinition(
91
+ colname=self.colname,
92
+ label="OGTT ≥7.8 or FBG ≥6.1",
93
+ condition=condition,
94
+ columns=columns,
95
+ drop=True,
96
+ )
97
+ )
98
+
99
+ condition = (
100
+ ((df_tmp[self.fbg_colname] < 6.1) | (df_tmp[self.ogtt_colname] < 7.8))
101
+ & (df_tmp[self.fbg_colname].notna())
102
+ & (df_tmp[self.ogtt_colname].notna())
103
+ )
104
+ row_defs.add(
105
+ RowDefinition(
106
+ colname=self.colname,
107
+ label="OGTT <7.8 or FBG <6.1",
108
+ condition=condition,
109
+ columns=columns,
110
+ drop=True,
111
+ )
112
+ )
113
+
114
+ condition = (df_tmp[self.fbg_colname].notna()) & (df_tmp[self.ogtt_colname].notna())
115
+ row_defs.add(
116
+ RowDefinition(
117
+ colname=self.colname,
118
+ label="Other",
119
+ condition=condition,
120
+ columns=columns,
121
+ drop=True,
122
+ )
123
+ )
124
+
125
+ condition = (df_tmp[self.fbg_colname].notna()) & (df_tmp[self.ogtt_colname].isna())
126
+ row_defs.add(
127
+ RowDefinition(
128
+ colname=self.colname,
129
+ label="OGTT not measured",
130
+ condition=condition,
131
+ columns=columns,
132
+ drop=True,
133
+ )
134
+ )
135
+ condition = (df_tmp[self.fbg_colname].isna()) & (df_tmp[self.ogtt_colname].notna())
136
+ row_defs.add(
137
+ RowDefinition(
138
+ colname=self.colname,
139
+ label="FBG not measured",
140
+ condition=condition,
141
+ columns=columns,
142
+ drop=True,
143
+ )
144
+ )
145
+ condition = (df_tmp[self.fbg_colname].isna()) & (df_tmp[self.ogtt_colname].isna())
146
+ row_defs.add(
147
+ RowDefinition(
148
+ colname=self.colname,
149
+ label="not measured",
150
+ condition=condition,
151
+ columns=columns,
152
+ drop=True,
153
+ )
154
+ )
155
+ return row_defs
156
+
157
+
158
+ class FbgOgttTable2(Table):
159
+
160
+ fbg_colname = "fbg"
161
+ ogtt_colname = "ogtt"
162
+
163
+ def __init__(self, main_df: pd.DataFrame = None):
164
+ super().__init__(
165
+ colname="",
166
+ main_df=main_df,
167
+ title="OGTT & FBG (mmol/L) additional",
168
+ )
169
+
170
+ @property
171
+ def row_definitions(self) -> RowDefinitions:
172
+ df_tmp = self.main_df.copy()
173
+ row_defs = RowDefinitions(reverse_rows=False)
174
+ row0 = RowDefinition(
175
+ title=self.title,
176
+ label="Glucose levels, n (%)",
177
+ condition=(df_tmp["gender"].notna()),
178
+ columns={FEMALE: (N_ONLY, 2), MALE: (N_ONLY, 2), "All": (N_ONLY, 2)},
179
+ drop=False,
180
+ )
181
+ row_defs.add(row0)
182
+ columns = {
183
+ FEMALE: (N_WITH_COL_PROP, 2),
184
+ MALE: (N_WITH_COL_PROP, 2),
185
+ "All": (N_WITH_ROW_PROP, 2),
186
+ }
187
+
188
+ row_defs.add(
189
+ RowDefinition(
190
+ colname=self.colname,
191
+ label="Not fasted",
192
+ condition=(
193
+ (self.main_df["fasting_fbg_hrs"] < 8.0)
194
+ | (self.main_df["fasting_ogtt_hrs"] < 8.0)
195
+ ),
196
+ columns=columns,
197
+ drop=True,
198
+ )
199
+ )
200
+
201
+ condition = (
202
+ (self.main_df[self.fbg_colname] < 6.1)
203
+ & (self.main_df[self.ogtt_colname] < 7.8)
204
+ & (self.main_df[self.ogtt_colname].notna())
205
+ & (self.main_df[self.fbg_colname].notna())
206
+ )
207
+ row_defs.add(
208
+ RowDefinition(
209
+ colname=self.colname,
210
+ label="FBG <6.1 mmol/l and after OGTT <7.8 mmol/l",
211
+ condition=condition,
212
+ columns=columns,
213
+ drop=True,
214
+ )
215
+ )
216
+
217
+ condition = (
218
+ (self.main_df[self.fbg_colname] < 6.1)
219
+ & (self.main_df[self.ogtt_colname] >= 7.8)
220
+ & (self.main_df[self.ogtt_colname] < 11.1)
221
+ & (self.main_df[self.ogtt_colname].notna())
222
+ & (self.main_df[self.fbg_colname].notna())
223
+ )
224
+ row_defs.add(
225
+ RowDefinition(
226
+ colname=self.colname,
227
+ label="FBG <6.1 mmol/l and after OGTT 7.8–11.0 mmol/l",
228
+ condition=condition,
229
+ columns=columns,
230
+ drop=True,
231
+ )
232
+ )
233
+
234
+ condition = (
235
+ (self.main_df[self.fbg_colname] >= 6.1)
236
+ & (self.main_df[self.fbg_colname] < 7.0)
237
+ & (self.main_df[self.ogtt_colname] < 7.8)
238
+ & (self.main_df[self.ogtt_colname].notna())
239
+ & (self.main_df[self.fbg_colname].notna())
240
+ )
241
+ row_defs.add(
242
+ RowDefinition(
243
+ colname=self.colname,
244
+ label="FBG 6.1–6.9 mmol/l and after OGTT <7.8 mmol/l",
245
+ condition=condition,
246
+ columns=columns,
247
+ drop=True,
248
+ )
249
+ )
250
+
251
+ condition = (
252
+ (self.main_df[self.fbg_colname] >= 6.1)
253
+ & (self.main_df[self.fbg_colname] < 7.0)
254
+ & (self.main_df[self.ogtt_colname] >= 7.8)
255
+ & (self.main_df[self.ogtt_colname] < 11.1)
256
+ & (self.main_df[self.ogtt_colname].notna())
257
+ & (self.main_df[self.fbg_colname].notna())
258
+ )
259
+ row_defs.add(
260
+ RowDefinition(
261
+ colname=self.colname,
262
+ label="FBG 6.1–6.9 mmol/l and after OGTT 7.8–11.0 mmol/l",
263
+ condition=condition,
264
+ columns=columns,
265
+ drop=True,
266
+ )
267
+ )
268
+
269
+ condition = (
270
+ (self.main_df[self.fbg_colname] >= 6.1)
271
+ & (self.main_df[self.fbg_colname] < 7.0)
272
+ & (self.main_df[self.ogtt_colname] >= 11.1)
273
+ & (self.main_df[self.ogtt_colname].notna())
274
+ & (self.main_df[self.fbg_colname].notna())
275
+ )
276
+ row_defs.add(
277
+ RowDefinition(
278
+ colname=self.colname,
279
+ label="FBG 6.1–6.9 mmol/l and after OGTT ≥11.0 mmol/l",
280
+ condition=condition,
281
+ columns=columns,
282
+ drop=True,
283
+ )
284
+ )
285
+
286
+ condition = (
287
+ (self.main_df[self.fbg_colname] >= 7.0)
288
+ & (self.main_df[self.ogtt_colname] < 7.8)
289
+ & (self.main_df[self.ogtt_colname].notna())
290
+ & (self.main_df[self.fbg_colname].notna())
291
+ )
292
+ row_defs.add(
293
+ RowDefinition(
294
+ colname=self.colname,
295
+ label="FBG ≥7.0 mmol/l and after OGTT <7.8 mmol/l",
296
+ condition=condition,
297
+ columns=columns,
298
+ drop=True,
299
+ )
300
+ )
301
+
302
+ condition = (
303
+ (self.main_df[self.fbg_colname] >= 7.0)
304
+ & (self.main_df[self.ogtt_colname] >= 7.8)
305
+ & (self.main_df[self.ogtt_colname] < 11.1)
306
+ & (self.main_df[self.ogtt_colname].notna())
307
+ & (self.main_df[self.fbg_colname].notna())
308
+ )
309
+ row_defs.add(
310
+ RowDefinition(
311
+ colname=self.colname,
312
+ label="FBG ≥7.0 mmol/l and after OGTT 7.8–11.0 mmol/l",
313
+ condition=condition,
314
+ columns=columns,
315
+ drop=True,
316
+ )
317
+ )
318
+
319
+ condition = (
320
+ (self.main_df[self.fbg_colname] >= 7.0)
321
+ & (self.main_df[self.ogtt_colname] >= 11.1)
322
+ & (self.main_df[self.ogtt_colname].notna())
323
+ & (self.main_df[self.fbg_colname].notna())
324
+ )
325
+ row_defs.add(
326
+ RowDefinition(
327
+ colname=self.colname,
328
+ label="FBG ≥7.0 mmol/l and after OGTT ≥11.1 mmol/l",
329
+ condition=condition,
330
+ columns=columns,
331
+ drop=True,
332
+ )
333
+ )
334
+
335
+ condition = (self.main_df[self.ogtt_colname].notna()) | (
336
+ self.main_df[self.fbg_colname].isna()
337
+ )
338
+ row_defs.add(
339
+ RowDefinition(
340
+ colname=self.colname,
341
+ label="FBG not measured",
342
+ condition=condition,
343
+ columns=columns,
344
+ drop=True,
345
+ )
346
+ )
347
+
348
+ condition = (self.main_df[self.ogtt_colname].isna()) | (
349
+ self.main_df[self.fbg_colname].notna()
350
+ )
351
+ row_defs.add(
352
+ RowDefinition(
353
+ colname=self.colname,
354
+ label="OGTT not measured",
355
+ condition=condition,
356
+ columns=columns,
357
+ drop=True,
358
+ )
359
+ )
360
+
361
+ condition = (self.main_df[self.ogtt_colname].isna()) | (
362
+ self.main_df[self.fbg_colname].isna()
363
+ )
364
+ row_defs.add(
365
+ RowDefinition(
366
+ colname=self.colname,
367
+ label="not measured",
368
+ condition=condition,
369
+ columns=columns,
370
+ drop=True,
371
+ )
372
+ )
373
+ return row_defs
374
+
375
+
376
+ class FbgOgttTable(Table):
377
+
378
+ def __init__(self, main_df: pd.DataFrame = None):
379
+ super().__init__(colname="", main_df=main_df, title="")
380
+
381
+ def build_table_df(self) -> None:
382
+ df1 = FbgOgttTable1(main_df=self.main_df).table_df
383
+ df2 = FbgOgttTable2(main_df=self.main_df).table_df
384
+ self.table_df = pd.concat([df1, df2])
@@ -0,0 +1,12 @@
1
+ import pandas as pd
2
+
3
+ from ..table import Table
4
+
5
+
6
+ class GenderTable(Table):
7
+ def __init__(self, main_df: pd.DataFrame = None):
8
+ super().__init__(
9
+ colname="gender",
10
+ main_df=main_df,
11
+ title="Gender",
12
+ )
@@ -0,0 +1,87 @@
1
+ import pandas as pd
2
+ from edc_constants.constants import FEMALE, MALE
3
+
4
+ from ..constants import MEAN_95CI, 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 HbA1cTable(Table):
10
+ def __init__(self, main_df: pd.DataFrame = None):
11
+ super().__init__(
12
+ colname="hba1c_value",
13
+ main_df=main_df,
14
+ title="HbA1C (%) categories",
15
+ )
16
+
17
+ @property
18
+ def row_definitions(self) -> RowDefinitions:
19
+ df_tmp = self.main_df.copy()
20
+ row_defs = RowDefinitions(reverse_rows=False)
21
+ row0 = RowDefinition(
22
+ title=self.title,
23
+ label=self.default_sublabel,
24
+ condition=(df_tmp["gender"].notna()),
25
+ columns={FEMALE: (N_ONLY, 2), MALE: (N_ONLY, 2), "All": (N_ONLY, 2)},
26
+ drop=False,
27
+ )
28
+ row_defs.add(row0)
29
+
30
+ columns = {
31
+ FEMALE: (MEAN_95CI, 2),
32
+ MALE: (MEAN_95CI, 2),
33
+ "All": (MEAN_95CI, 2),
34
+ }
35
+ row_mean = RowDefinition(
36
+ colname=self.colname,
37
+ label="Mean (95% CI)",
38
+ condition=(self.main_df[self.colname].notna()),
39
+ columns=columns,
40
+ drop=False,
41
+ )
42
+
43
+ columns = {
44
+ FEMALE: (N_WITH_COL_PROP, 2),
45
+ MALE: (N_WITH_COL_PROP, 2),
46
+ "All": (N_WITH_ROW_PROP, 2),
47
+ }
48
+ row_defs.add(
49
+ RowDefinition(
50
+ colname=self.colname,
51
+ label="<6.0",
52
+ condition=(self.main_df[self.colname] < 6.0),
53
+ columns=columns,
54
+ drop=False,
55
+ )
56
+ )
57
+ row_defs.add(
58
+ RowDefinition(
59
+ colname=self.colname,
60
+ label="≥6.0 and ≤6.4",
61
+ condition=(
62
+ (self.main_df[self.colname] >= 6.0) & (self.main_df[self.colname] <= 6.4)
63
+ ),
64
+ columns=columns,
65
+ drop=False,
66
+ )
67
+ )
68
+ row_defs.add(
69
+ RowDefinition(
70
+ colname=self.colname,
71
+ label=">6.4",
72
+ condition=(self.main_df[self.colname] > 6.4),
73
+ columns=columns,
74
+ drop=False,
75
+ )
76
+ )
77
+ row_defs.add(
78
+ RowDefinition(
79
+ colname=self.colname,
80
+ label="not measured",
81
+ condition=(self.main_df[self.colname].isna()),
82
+ columns=columns,
83
+ drop=False,
84
+ )
85
+ )
86
+ row_defs.add(row_mean)
87
+ return row_defs
@@ -0,0 +1,95 @@
1
+ import pandas as pd
2
+ from edc_constants.constants import FEMALE, MALE
3
+
4
+ from ..constants import MEAN_95CI, 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 OgttTable(Table):
10
+ def __init__(self, main_df: pd.DataFrame = None):
11
+ super().__init__(
12
+ colname="ogtt",
13
+ main_df=main_df,
14
+ title="OGTT (mmol/L) categories",
15
+ )
16
+
17
+ @property
18
+ def row_definitions(self) -> RowDefinitions:
19
+ df_tmp = self.main_df.copy()
20
+ row_defs = RowDefinitions(reverse_rows=False)
21
+ row0 = RowDefinition(
22
+ title=self.title,
23
+ label=self.default_sublabel,
24
+ condition=(df_tmp["gender"].notna()),
25
+ columns={FEMALE: (N_ONLY, 2), MALE: (N_ONLY, 2), "All": (N_ONLY, 2)},
26
+ drop=False,
27
+ )
28
+ row_defs.add(row0)
29
+ columns = {
30
+ FEMALE: (N_WITH_COL_PROP, 2),
31
+ MALE: (N_WITH_COL_PROP, 2),
32
+ "All": (N_WITH_ROW_PROP, 2),
33
+ }
34
+ row_defs.add(
35
+ RowDefinition(
36
+ colname=self.colname,
37
+ label="Not fasted",
38
+ condition=(self.main_df["fasting_ogtt_hrs"] < 8.0),
39
+ columns=columns,
40
+ drop=True,
41
+ )
42
+ )
43
+ row_defs.add(
44
+ RowDefinition(
45
+ colname=self.colname,
46
+ label="<7.8",
47
+ condition=(self.main_df[self.colname] < 7.8),
48
+ columns=columns,
49
+ drop=False,
50
+ )
51
+ )
52
+ row_defs.add(
53
+ RowDefinition(
54
+ colname=self.colname,
55
+ label="7.8-11.1",
56
+ condition=(self.main_df[self.colname] >= 7.8)
57
+ & (self.main_df[self.colname] < 11.1),
58
+ columns=columns,
59
+ drop=False,
60
+ )
61
+ )
62
+ row_defs.add(
63
+ RowDefinition(
64
+ colname=self.colname,
65
+ label="11.1 and above",
66
+ condition=(self.main_df[self.colname] >= 11.1),
67
+ columns=columns,
68
+ drop=False,
69
+ )
70
+ )
71
+ row_defs.add(
72
+ RowDefinition(
73
+ colname=self.colname,
74
+ label="not measured",
75
+ condition=(self.main_df[self.colname].isna()),
76
+ columns=columns,
77
+ drop=False,
78
+ )
79
+ )
80
+ columns = {
81
+ FEMALE: (MEAN_95CI, 2),
82
+ MALE: (MEAN_95CI, 2),
83
+ "All": (MEAN_95CI, 2),
84
+ }
85
+ row_defs.add(
86
+ RowDefinition(
87
+ colname=self.colname,
88
+ label="Mean (95% CI)",
89
+ condition=(self.main_df[self.colname].notna()),
90
+ columns=columns,
91
+ drop=False,
92
+ )
93
+ )
94
+
95
+ return row_defs
@@ -0,0 +1,105 @@
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 WaistCircumferenceTable(Table):
16
+
17
+ def __init__(self, main_df: pd.DataFrame = None):
18
+ super().__init__(
19
+ colname="waist_circumference",
20
+ main_df=main_df,
21
+ title="Waist circumference (cm)",
22
+ )
23
+
24
+ @property
25
+ def row_definitions(self) -> RowDefinitions:
26
+ df_tmp = self.main_df.copy()
27
+ row_defs = RowDefinitions(reverse_rows=False)
28
+ row0 = RowDefinition(
29
+ title=self.title,
30
+ label=self.default_sublabel,
31
+ condition=(df_tmp["gender"].notna()),
32
+ columns={FEMALE: (N_ONLY, 2), MALE: (N_ONLY, 2), "All": (N_ONLY, 2)},
33
+ drop=False,
34
+ )
35
+ row_defs.add(row0)
36
+
37
+ columns = {
38
+ FEMALE: (N_WITH_COL_PROP, 2),
39
+ MALE: (N_WITH_COL_PROP, 2),
40
+ "All": (N_WITH_ROW_PROP, 2),
41
+ }
42
+
43
+ cond_lt_102 = (
44
+ (self.main_df[self.colname] < 102.0) & (self.main_df["gender"] == "Male")
45
+ ) | ((self.main_df[self.colname] < 88.0) & (self.main_df["gender"] == "Female"))
46
+ row_defs.add(
47
+ RowDefinition(
48
+ colname=self.colname,
49
+ label="Women<88 / Men<102",
50
+ condition=cond_lt_102,
51
+ columns=columns,
52
+ drop=False,
53
+ )
54
+ )
55
+ cond_gte_102 = (
56
+ (self.main_df[self.colname] >= 102.0) & (self.main_df["gender"] == "Male")
57
+ ) | ((self.main_df[self.colname] >= 88.0) & (self.main_df["gender"] == "Female"))
58
+ row_defs.add(
59
+ RowDefinition(
60
+ colname=self.colname,
61
+ label="Women>=88 / Men>=102",
62
+ condition=cond_gte_102,
63
+ columns=columns,
64
+ drop=False,
65
+ )
66
+ )
67
+ cond_gte_missing = self.main_df[self.colname].isna()
68
+ row_defs.add(
69
+ RowDefinition(
70
+ colname=self.colname,
71
+ label="not measured",
72
+ condition=cond_gte_missing,
73
+ columns=columns,
74
+ drop=False,
75
+ )
76
+ )
77
+
78
+ columns = {
79
+ FEMALE: (MEDIAN_RANGE, 2),
80
+ MALE: (MEDIAN_RANGE, 2),
81
+ "All": (MEDIAN_RANGE, 2),
82
+ }
83
+ row_defs.add(
84
+ RowDefinition(
85
+ colname=self.colname,
86
+ label="Median (range)",
87
+ condition=(self.main_df[self.colname].notna()),
88
+ columns=columns,
89
+ )
90
+ )
91
+
92
+ columns = {
93
+ FEMALE: (MEDIAN_IQR, 2),
94
+ MALE: (MEDIAN_IQR, 2),
95
+ "All": (MEDIAN_IQR, 2),
96
+ }
97
+ row_defs.add(
98
+ RowDefinition(
99
+ colname=self.colname,
100
+ label="Median (IQR)",
101
+ condition=(self.main_df[self.colname].notna()),
102
+ columns=columns,
103
+ )
104
+ )
105
+ return row_defs