--[[
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))
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))