Simple Stats

lua-users home
wiki

This is a small set of functions to do some statistics (e.g. mean, mode, median, standard deviation, and min/max) on tables. Just fill your tables with numbers and call the function you want. I haven't optimised these at all.

All function except mode will skip over any non-numeric data and also the table does not have to be indexed. E.g.

t = {[1]=5, [2]=7, [3]=8, [4]='Something else.'}  -- or

t = {["a"]=5, ["b"]=7, ["c"]=8, ["name"]='My table of numbers'}

is fine for input to these. Note that the 'Mode' function is slightly different. It works on anything, not just numbers.

-- Small stats library                      --

----------------------------------------------

-- Version History --

-- 1.0 First written.



-- Tables supplied as arguments are not changed.





-- Table to hold statistical functions

stats={}



-- Get the mean value of a table

function stats.mean( t )

  local sum = 0

  local count= 0



  for k,v in pairs(t) do

    if type(v) == 'number' then

      sum = sum + v

      count = count + 1

    end

  end



  return (sum / count)

end



-- Get the mode of a table.  Returns a table of values.

-- Works on anything (not just numbers).

function stats.mode( t )

  local counts={}



  for k, v in pairs( t ) do

    if counts[v] == nil then

      counts[v] = 1

    else

      counts[v] = counts[v] + 1

    end

  end



  local biggestCount = 0



  for k, v  in pairs( counts ) do

    if v > biggestCount then

      biggestCount = v

    end

  end



  local temp={}



  for k,v in pairs( counts ) do

    if v == biggestCount then

      table.insert( temp, k )

    end

  end



  return temp

end



-- Get the median of a table.

function stats.median( t )

  local temp={}



  -- deep copy table so that when we sort it, the original is unchanged

  -- also weed out any non numbers

  for k,v in pairs(t) do

    if type(v) == 'number' then

      table.insert( temp, v )

    end

  end



  table.sort( temp )



  -- If we have an even number of table elements or odd.

  if math.fmod(#temp,2) == 0 then

    -- return mean value of middle two elements

    return ( temp[#temp/2] + temp[(#temp/2)+1] ) / 2

  else

    -- return middle element

    return temp[math.ceil(#temp/2)]

  end

end

    



-- Get the standard deviation of a table

function stats.standardDeviation( t )

  local m

  local vm

  local sum = 0

  local count = 0

  local result



  m = stats.mean( t )



  for k,v in pairs(t) do

    if type(v) == 'number' then

      vm = v - m

      sum = sum + (vm * vm)

      count = count + 1

    end

  end



  result = math.sqrt(sum / (count-1))



  return result

end



-- Get the max and min for a table

function stats.maxmin( t )

  local max = -math.huge

  local min = math.huge



  for k,v in pairs( t ) do

    if type(v) == 'number' then

      max = math.max( max, v )

      min = math.min( min, v )

    end

  end



  return max, min

end


RecentChanges · preferences
edit · history
Last edited July 4, 2008 4:56 pm GMT (diff)