Persistent Absentees

One of the challenges I've recently faced is how to get a measure to show persistent absentees (students with <90% attendance), that will respond to any time period on a date slicer.

If you want to follow along with this example then you can access a sample data set or if you just want to visualise I will refer to two tables: 

Students - a list of students
StudentAttendances - a list of attendance records, with one row per student per session that includes the mark meaning (P - present, E - Approved Educational Activity, A - Absent, U - Unauthorised, C - Cancelled).
Students is related to StudentAttendances with a one-to-many relationship.

Step 1: Present and Possible

My first step was to create two columns on the StudentAttendances table. 

Present: = if(or(StudentAttendances[MarkMeaning]="P",StudentAttendances[MarkMeaning]="E"),1,0)

Possible  = if(StudentAttendances[MarkMeaning]="C",0,1)

Step 2: Attendance% measure

Next I created a measure on the StudentAttenances table to calculate the percentage attendance

Attendance% = sum(StudentAttendances[Present])/sum(StudentAttendances[Possible])

Side Note: Columns increase the size the memory used, so this isn't the maximally efficient way of doing this. For a school sized db that probably won't matter so I prefer the simplicity of creating the columns separately. For a large MAT with millions of attendance records, it could be better to not make the columns and do the present possible calculation in the measure like this:

Attendance%2 = sumx(StudentAttendances,if(or(StudentAttendances[MarkMeaning]="P",StudentAttendances[MarkMeaning]="E"),1,0))/sumx(StudentAttendances,if(StudentAttendances[MarkMeaning]="C",0,1))

The (function)x functions in DAX essentially let you create temporary calculated columns in tables with measures.

Step 3: Persistent Absentee Measure

Persistent Absence is a condition of students, so for this we create a measure on the Students table, first to count the number of students whose attendance% is less than 90%

PersistentAbs = countrows(filter(students,and(calculate(StudentAttendances[Attendance%])<.9,isnumber(calculate(StudentAttendances[Attendance%])))))

Calculate in this measure does what BI calls 'preserve the row context'. That means that it works out the Attendance% figure for each row (ie each student) rather than for all the students combined. 
The IsNumber formula checks that attendance exists for the student - if their attendance percentage is a number then they have at least one possible session.

Step 4: Persistent Absence Percentage

Finally we divide our PersistenAbs student total by the number of students with attendance in this period (which could include students who are now off roll). The denominator is like the PersistentAbs count but without the condition that Attendance% is <90%.

PersistantAbs% = [PersistentAbs]/countrows(filter(students,isnumber(calculate(StudentAttendances[Attendance%]))))

Here are the figures from the sample data set


Comments

  1. Hi,

    Thanks for all your work on the blog and trying to demystify PowerBI. I am trying to follow along your example but can't seem to get past step three. When I enter the formula it tells me that "a single value for column 'Attendance%' cannot be determined .... etc.

    Presumably this is because there are multiple rows (even though they should all have the same attendance%). Can't work out how to get past this. Any guidance greatly appreciated!

    ReplyDelete
  2. Hiya,

    That sounds to me like you're entering the formula as a column instead of a measure. Columns give us a single figure in the table to which they are added. Measures are much more flexible as they change according to context. E.g. if you create the persistent absentee measure and drag it on the canvas as a card it will give you the figure for the whole school, drag it into a table with students gender it will give you separate figures for boys and girls etc.

    ReplyDelete
  3. Thanks for your work on this. I've been wracking my brain for a way to get PA working as a measure and came up short. Your solution works perfectly!

    ReplyDelete

Post a Comment

Popular posts from this blog

Data modelling for a large MAT

Subject - Class - Pupil Table

Attainment 8 in BI - Part 1