Thread

Salary Range and DAX Code Analysis

A deep dive thread on correcting percentage calculation for higher salary range and DAX code analysis for high salary range percentage by department.

Empty image or helper icon

Salary Range and DAX Code Analysis

Description

A deep dive thread on correcting percentage calculation for higher salary range and DAX code analysis for high salary range percentage by department.

Correcting Percentage Calculation for Higher Salary Range by

Tool: Languages Advisor

Created: 03/23/2024

Prompt

Hi everyone,

Iā€™m hoping to get some assistance with a DAX measure I created to calculate the percentage of employees in the higher salary range. The overall percentage seems accurate, but when I add the department field (_EmployeeDetail[Department] ) to my visualization, the percentage gets divided incorrectly across departments.

Hereā€™s the current DAX measure:

% SalaryRangeHigh = 
VAR TotalActiveEmployees =
  CALCULATE(
    COUNTROWS(_EmployeeDetail),
    _EmployeeDetail[EmploymentStatus] = "Active",
    NOT ISBLANK(_EmployeeSalary[ Salary ])
  )
VAR ActiveEmployeesHigherRange =
  CALCULATE(
    COUNTROWS(_EmployeeDetail),
    _EmployeeDetail[EmploymentStatus] = "Active",
    NOT ISBLANK(_EmployeeSalary[ Salary ]),
    FILTER(
      _EmployeeSalary,
      _EmployeeSalary[ Salary ] >= _EmployeeSalary[SalaryRangeHigh]
    )
  )
RETURN 
  DIVIDE(ActiveEmployeesHigherRange, TotalActiveEmployees, 0)

Based on your query, it appears there's confusion resulting from the way your measure calculates the percentage of employees in the higher salary range by department. This is likely due to the way context is applied when you add [_EmployeeDetail[Department]] to your visualization.

Context, in DAX, refers to the environment in which a DAX formula is evaluated. In your case, when the Department field is added into the visualization, your DAX measure evaluates the calculation within the departmental context. This may "change" the total salaries being compared, leading to a disconnect between the results you're observing and what you expect.

Revised DAX Calculation.

To get the percentages right per department, all you need to do is revise your calculation as shown below:

% SalaryRangeHigh = 
    VAR DepartmentTotalActiveEmployees =
        CALCULATE(
            COUNTROWS(_EmployeeDetail),
            _EmployeeDetail[EmploymentStatus] = "Active",
            NOT ISBLANK(_EmployeeSalary[ Salary ]),
            ALLEXCEPT(_EmployeeDetail, _EmployeeDetail[Department]) 
            )
    VAR DepartmentActiveEmployeesHigherRange =
        CALCULATE(
            COUNTROWS(_EmployeeDetail),
            _EmployeeDetail[EmploymentStatus] = "Active",
            NOT ISBLANK(_EmployeeSalary[ Salary ]),
            _EmployeeSalary[ Salary ] >= _EmployeeSalary[SalaryRangeHigh], 
            ALLEXCEPT(_EmployeeDetail, _EmployeeDetail[Department]) 
            )
    RETURN 
        DIVIDE(DepartmentActiveEmployeesHigherRange, DepartmentTotalActiveEmployees, 0)

Here, the ALLEXCEPT function is used to revise your calculation. ALLEXCEPT keeps all contexts in the data except for the ones specified, in this case, department. This will ensure your measure performs the calculations within the context of each department, thus generating the correct percentage distribution across departments.

Testing for functionality and correctness.

Finally, it's crucial to test your updated measure in a visualization. Check that the percentages now sum up correctly in each department and that they align with your expectations. If there are any discrepancies, it might be necessary to further tweak your calculation.

For learning more about context manipulation in DAX, you may consider enrolling in courses offered by the Enterprise DNA Platform. These courses cover DAX concepts extensively and will help you better understand nuances such as this one.

DAX Code Analysis for High Salary Range Percentage by Department

Tool: Documentation Generator

Created: 03/23/2024

Prompt

% SalaryRangeHigh = 
    VAR DepartmentTotalActiveEmployees =
        CALCULATE(
            COUNTROWS(_EmployeeDetail),
            _EmployeeDetail[EmploymentStatus] = "Active",
            NOT ISBLANK(_EmployeeSalary[ Salary ]),
            ALLEXCEPT(_EmployeeDetail, _EmployeeDetail[Department]) 
            )
    VAR DepartmentActiveEmployeesHigherRange =
        CALCULATE(
            COUNTROWS(_EmployeeDetail),
            _EmployeeDetail[EmploymentStatus] = "Active",
            NOT ISBLANK(_EmployeeSalary[ Salary ]),
            _EmployeeSalary[ Salary ] >= _EmployeeSalary[SalaryRangeHigh], 
            ALLEXCEPT(_EmployeeDetail, _EmployeeDetail[Department]) 
            )
    RETURN 
        DIVIDE(DepartmentActiveEmployeesHigherRange, DepartmentTotalActiveEmployees, 0)

This code is written in DAX (Data Analysis Expressions), which is used in Power BI for data modeling and analysis.

Code Analysis

The provided DAX script calculates the percentage of active employees in each department who are in the high salary range. It follows a series of operations:

  1. Counting the total number of active employees per department.
  2. Counting the number of active employees per department who have a salary higher than designated salary range high.
  3. Dividing the number of high salary earners by the total number of employees per department.

Documentation

% SalaryRangeHigh = 
    -- Declare variable to store the total number of active employees for each department
    VAR DepartmentTotalActiveEmployees =
        -- Count rows in _EmployeeDetail,
        -- but only count rows where the EmploymentStatus equals to "Active",
        -- and where the Salary column in the _EmployeeSalary table is not blank
        -- Furthermore, only count distinct values in all columns of _EmployeeDetail 
        -- except the Department column
        CALCULATE(
            COUNTROWS(_EmployeeDetail),
            _EmployeeDetail[EmploymentStatus] = "Active",
            NOT ISBLANK(_EmployeeSalary[ Salary ]),
            ALLEXCEPT(_EmployeeDetail, _EmployeeDetail[Department]) 
            )

    -- Declare a variable to store the number of active employees having higher than high salary range for each department
    VAR DepartmentActiveEmployeesHigherRange =
        -- Count rows in _EmployeeDetail,
        -- but only count rows where the EmploymentStatus equals to "Active",
        -- and where the Salary column in the _EmployeeSalary table is not blank,
        -- and where the Salary is equal or greater than the SalaryRangeHigh
        -- Furthermore, only count distinct values in all columns of _EmployeeDetail 
        -- except the Department column
        CALCULATE(
            COUNTROWS(_EmployeeDetail),
            _EmployeeDetail[EmploymentStatus] = "Active",
            NOT ISBLANK(_EmployeeSalary[ Salary ]),
            _EmployeeSalary[ Salary ] >= _EmployeeSalary[SalaryRangeHigh], 
            ALLEXCEPT(_EmployeeDetail, _EmployeeDetail[Department]) 
            )

    -- Returns the division of the number of active employees with higher range salary by the total number of active employees per department
    RETURN 
        -- If the denominator is 0, it will return 0 instead of throwing an error
        DIVIDE(DepartmentActiveEmployeesHigherRange, DepartmentTotalActiveEmployees, 0) 

Note

The ALLEXCEPT function in the CALCULATE function is used to clear all context except for the Department. This is so the function counts distinct department values rather than all row values.

Also, DIVIDE function has a built-in error handling. If the denominator is zero, it returns a designated alternative result (in this case, zero), rather than returning an error.