# Interquartile range

``````--[[
Calculates the interquartile range of a table.
The interquartile range is the difference between the upper and lower quartiles.
The upper quartile is the median of the upper half of the table.
The lower quartile is the median of the lower half of the table.
The median is the middle value of the table.
If the table has an even number of values, the median is the average of the two middle values.
@param t The table.
@return The interquartile range.
]]
function get_interquartile_range(t)
local median = get_median(t)
local lower_half = {}
local upper_half = {}
for i, v in ipairs(t) do
if v < median then
table.insert(lower_half, v)
elseif v > median then
table.insert(upper_half, v)
end
end
return get_median(upper_half) - get_median(lower_half)
end

--[[
Calculates the median of a table.
The median is the middle value of the table.
If the table has an even number of values, the median is the average of the two middle values.
@param t The table.
@return The median.
]]
function get_median(t)
local sorted = {}
for i, v in ipairs(t) do
table.insert(sorted, v)
end
table.sort(sorted)
local middle = math.floor(#sorted / 2)
if #sorted % 2 == 0 then
return (sorted[middle] + sorted[middle + 1]) / 2
else
return sorted[middle + 1]
end
end

local t = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
print(get_interquartile_range(t))
``````

IQR basically is Q3 - Q1 with Q3 being the 75% value of a table and Q1 being the 25% value

The way I would tackle this is like this:

``````function IQR(t)
local Q1 = t[#t*0.25]
local Q3 = t[#t*0.75]
return Q3 - Q1
end

local newTable = {1,2,3,4,5}
print(IQR(newTable))
``````

This could work but you run into a problem when the #t isn’t even but it’s odd

What I would do to get the Q1 and Q3 is:

``````function IQR(t)
if #t % 2 == 0 then -- Checks if it's even
local Q1 = t[#t*0.25] -- Gets the Q1th value of the table
local Q3 = t[#t*0.75]
return Q3 - Q1
else -- If it isn't then we tackle it another way
local medQ1 = (math.round(#t*.25) + (math.round(#t*.25)+1))/2 -- Since #t isn't a rounded number it would error so we round it up and get the next number to find the median of those two to then calculate what exact number to look for in our table
local medQ3 = (math.round(#t*.75) + (math.round(#t*.75)+1))/2
if medQ1 % 2 == 0 and medQ3 % 2 == 0 then --if the median is even then great we can just do what we did on the first part of the function
local Q1 = t[medQ1]
local Q3 = t[medQ3]
return Q3 - Q1
else
local Q1 = (t[math.round(medQ1)] + t[math.round(medQ1)-1])/2 -- if it isn't since medQn can either be a rounded number or a number like 1.5 and 1.5 will get rounded up to 2 so we get the number before so that we can get the median of the two and then we got Q1
local Q3 = (t[math.round(medQ3)] + t[math.round(medQ3)-1])/2
return Q3 - Q1
end
end
end

local newTable = {1,2,3,4,5}
print(IQR(newTable))
``````

Assuming of course the table is sorted which can easily be done.

Its works with odd. Though… 20c

I updated the script, and even tested it as you can see below, I believe it doesn’t have any errors.

``````function IQR(t)
if (#t % 2) == 0 then -- Checks if it's even
local Q1 = t[math.round(#t*0.25)] -- Gets the Q1th value of the table
local Q3 = t[math.round(#t*0.75)]
print("passed1",Q1,Q3,#t)
return Q3 - Q1
else -- If it isn't then we tackle it another way
local medQ1 = (math.round(#t*.25) + (math.round(#t*.25)+1))/2 -- Since #t isn't a rounded number it would error so we round it up and get the next number to find the median of those two to then calculate what exact number to look for in our table
local medQ3 = (math.round(#t*.75) + (math.round(#t*.75)+1))/2
if (medQ1 % 2 == 0) and (medQ3 % 2 == 0) then --if the median is even then great we can just do what we did on the first part of the function
local Q1 = t[medQ1]
local Q3 = t[medQ3]
print("passed2",Q1,Q3)
return Q3 - Q1
else
local Q1 = (t[math.round(medQ1)] + t[math.round(medQ1)-1])/2 -- if it isn't since medQn can either be a rounded number or a number like 1.5 and 1.5 will get rounded up to 2 so we get the number before so that we can get the median of the two and then we got Q1
local Q3 = (t[math.round(medQ3)] + t[math.round(medQ3)-1])/2
print("passed3",Q1,Q3)
return Q3 - Q1
end
end
end

function makeTable()
local t = {}
local tableSize = math.random(1,100)
for i = 1, tableSize do
table.insert(t,math.random(1,10))
i += 1
end

table.sort(t,function(a,b)
return a < b
end)
print(t)
return t
end

local newTable = makeTable()

print(IQR(newTable))
``````

I don’t even need to find the IQR of a table, idek why I created the script.