Skip to content

Commit cb19449

Browse files
Natasha ChetwyndNatasha Chetwynd
authored andcommitted
Added checknatval function
1 parent 9caf12b commit cb19449

1 file changed

Lines changed: 89 additions & 0 deletions

File tree

codonPython/checknatval.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import pandas as pd
2+
3+
4+
def check_nat_val(df: pd.DataFrame, breakdown_col: str = "Breakdown",
5+
measure_col: str = "Measure", value_col: str =
6+
"Value_Unsuppressed", nat_val: str = "National") -> bool:
7+
"""
8+
Check national value less than or equal to sum of breakdowns.
9+
10+
This function checks that the national value is less than or equal to the
11+
sum of each organisation level breakdown.
12+
This function does not apply to values which are averages.
13+
This function does not apply to values which are percentages calculated
14+
from the numerator and denominator.
15+
16+
Parameters
17+
----------
18+
df : pandas.DataFrame
19+
DataFrame of data to check.
20+
breakdown_col : str, default = "Breakdown"
21+
Column name for the breakdown level.
22+
measure_col : str, default = "Measure"
23+
Column name for measures
24+
value_col : str, default = "Value_Unsuppressed"
25+
Column name for values
26+
nat_val : str, default = "National"
27+
Value in breakdown column denoting national values
28+
Returns
29+
-------
30+
bool
31+
Whether the checks have been passed.
32+
33+
Examples
34+
--------
35+
>>> check_nat_val(
36+
... df = pd.DataFrame({
37+
... "Breakdown" : ['National', 'CCG', 'CCG', 'Provider', 'Provider',
38+
'National' ,'CCG', 'CCG', 'Provider', 'Provider','National' ,'CCG', 'CCG',
39+
'Provider', 'Provider',],
40+
... "Measure" : ['m1', 'm1', 'm1', 'm1', 'm1', 'm2', 'm2', 'm2', 'm2',
41+
'm2', 'm3', 'm3', 'm3', 'm3', 'm3',],
42+
... "Value_Unsuppressed" : [9, 4, 5, 3, 6, 11, 2, 9, 7, 4, 9, 5, 4, 6,
43+
3],
44+
... }),
45+
... breakdown_col = "Breakdown",
46+
... measure_col = "Measure",
47+
... value_col = "Value_Unsuppressed",
48+
... nat_val = "National",
49+
... )
50+
True
51+
>>> check_nat_val(
52+
... df = pd.DataFrame({
53+
... "Breakdown" : ['National', 'CCG', 'CCG', 'Provider', 'Provider',
54+
'National' ,'CCG', 'CCG', 'Provider', 'Provider','National' ,'CCG', 'CCG',
55+
'Provider', 'Provider',],
56+
... "Measure" : ['m1', 'm1', 'm1', 'm1', 'm1', 'm2', 'm2', 'm2', 'm2',
57+
'm2', 'm3', 'm3', 'm3', 'm3', 'm3',],
58+
... "Value_Unsuppressed" : [18, 4, 5, 3, 6, 11, 2, 9, 7, 4, 9, 5, 4, 6,
59+
3],
60+
... }),
61+
... breakdown_col = "Breakdown",
62+
... measure_col = "Measure",
63+
... value_col = "Value_Unsuppressed",
64+
... nat_val = "National",
65+
... )
66+
False
67+
"""
68+
69+
if not isinstance(breakdown_col, str) or not isinstance(measure_col, str)\
70+
or not isinstance(value_col, str):
71+
raise ValueError("Please input strings for column indexes.")
72+
if not isinstance(nat_val, str):
73+
raise ValueError("Please input strings for value indexes.")
74+
if breakdown_col not in df.columns or measure_col not in df.columns or\
75+
value_col not in df.columns:
76+
raise KeyError("Check column names correspond to the DataFrame.")
77+
# aggregate values by measure and breakdown
78+
grouped = df.groupby([measure_col, breakdown_col]).agg({value_col: sum})
79+
.reset_index()
80+
national = grouped.loc[grouped[breakdown_col] == nat_val].reset_index()
81+
non_national = grouped.loc[grouped[breakdown_col] != nat_val].reset_index()
82+
# check values are less than or equal to national value for each measure
83+
join = pd.merge(non_national, national, left_on=measure_col,
84+
right_on=measure_col, how='left')
85+
left = value_col + '_x'
86+
right = value_col + '_y'
87+
join['Check'] = join[right] <= join[left]
88+
result = all(join['Check']
89+
return result

0 commit comments

Comments
 (0)