Модуль:Statistics

Материал из Поле цифровой дидактики

Для документации этого модуля может быть создана страница Модуль:Statistics/doc

-- Модуль для статистических расчетов
-- Использование: {{#invoke:Statistics|functionName|arg1|arg2|...}}

local stats = {}

-- Функция для разбора CSV-строки
local function parseCSV(str)
    local numbers = {}
    for num in string.gmatch(str, "[^,]+") do
        table.insert(numbers, tonumber(num))
    end
    return numbers
end

-- Функция для расчета среднего арифметического (mean)
function stats.mean(frame)
    local data = parseCSV(frame.args[1])
    if #data == 0 then return "Ошибка: пустые данные" end
    
    local sum = 0
    for _, v in ipairs(data) do
        sum = sum + v
    end
    
    local mean = sum / #data
    return string.format("%.2f", mean)
end

-- Функция для расчета медианы
function stats.median(frame)
    local data = parseCSV(frame.args[1])
    if #data == 0 then return "Ошибка: пустые данные" end
    
    -- Сортировка данных
    table.sort(data)
    
    local n = #data
    local median
    
    if n % 2 == 0 then
        median = (data[n/2] + data[n/2 + 1]) / 2
    else
        median = data[math.ceil(n/2)]
    end
    
    return string.format("%.2f", median)
end

-- Функция для расчета дисперсии (variance)
function stats.variance(frame)
    local data = parseCSV(frame.args[1])
    if #data == 0 then return "Ошибка: пустые данные" end
    
    -- Расчет среднего значения
    local sum = 0
    for _, v in ipairs(data) do
        sum = sum + v
    end
    local mean = sum / #data
    
    -- Расчет дисперсии
    local variance_sum = 0
    for _, v in ipairs(data) do
        variance_sum = variance_sum + (v - mean) ^ 2
    end
    
    local variance = variance_sum / (#data - 1)
    return string.format("%.2f", variance)
end

-- Функция для расчета стандартного отклонения (standard deviation)
function stats.stddev(frame)
    local data = parseCSV(frame.args[1])
    if #data == 0 then return "Ошибка: пустые данные" end
    
    -- Расчет среднего значения
    local sum = 0
    for _, v in ipairs(data) do
        sum = sum + v
    end
    local mean = sum / #data
    
    -- Расчет дисперсии
    local variance_sum = 0
    for _, v in ipairs(data) do
        variance_sum = variance_sum + (v - mean) ^ 2
    end
    
    local variance = variance_sum / (#data - 1)
    local stddev = math.sqrt(variance)
    
    return string.format("%.2f", stddev)
end

-- Функция для минимума и максимума
function stats.minmax(frame)
    local data = parseCSV(frame.args[1])
    if #data == 0 then return "Ошибка: пустые данные" end
    
    local min_val = data[1]
    local max_val = data[1]
    
    for _, v in ipairs(data) do
        if v < min_val then min_val = v end
        if v > max_val then max_val = v end
    end
    
    return "Мин: " .. string.format("%.2f", min_val) .. 
           " | Макс: " .. string.format("%.2f", max_val)
end

-- Функция для расчета суммы
function stats.sum(frame)
    local data = parseCSV(frame.args[1])
    if #data == 0 then return "Ошибка: пустые данные" end
    
    local sum = 0
    for _, v in ipairs(data) do
        sum = sum + v
    end
    
    return string.format("%.2f", sum)
end

-- Функция для расчета количества элементов (count)
function stats.count(frame)
    local data = parseCSV(frame.args[1])
    return tostring(#data)
end

-- Функция для расчета корреляции Пирсона
function stats.correlation(frame)
    local data_x = parseCSV(frame.args[1])
    local data_y = parseCSV(frame.args[2])
    
    if #data_x ~= #data_y then
        return "Ошибка: размеры массивов не совпадают"
    end
    if #data_x == 0 then
        return "Ошибка: пустые данные"
    end
    
    -- Средние значения
    local mean_x = 0
    local mean_y = 0
    for i = 1, #data_x do
        mean_x = mean_x + data_x[i]
        mean_y = mean_y + data_y[i]
    end
    mean_x = mean_x / #data_x
    mean_y = mean_y / #data_y
    
    -- Расчет корреляции
    local numerator = 0
    local denominator_x = 0
    local denominator_y = 0
    
    for i = 1, #data_x do
        numerator = numerator + (data_x[i] - mean_x) * (data_y[i] - mean_y)
        denominator_x = denominator_x + (data_x[i] - mean_x) ^ 2
        denominator_y = denominator_y + (data_y[i] - mean_y) ^ 2
    end
    
    local correlation = numerator / math.sqrt(denominator_x * denominator_y)
    return string.format("%.4f", correlation)
end

-- Функция для создания таблицы статистики
function stats.summary(frame)
    local data = parseCSV(frame.args[1])
    if #data == 0 then return "Ошибка: пустые данные" end
    
    local sum = 0
    for _, v in ipairs(data) do
        sum = sum + v
    end
    local mean = sum / #data
    
    local variance_sum = 0
    for _, v in ipairs(data) do
        variance_sum = variance_sum + (v - mean) ^ 2
    end
    local variance = variance_sum / (#data - 1)
    local stddev = math.sqrt(variance)
    
    table.sort(data)
    local n = #data
    local median
    if n % 2 == 0 then
        median = (data[n/2] + data[n/2 + 1]) / 2
    else
        median = data[math.ceil(n/2)]
    end
    
    local result = ""
    result = result .. "{| class='wikitable'\n"
    result = result .. "! Показатель\n! Значение\n|-\n"
    result = result .. "| Количество (N)\n| " .. tostring(#data) .. "\n|-\n"
    result = result .. "| Среднее\n| " .. string.format("%.2f", mean) .. "\n|-\n"
    result = result .. "| Медиана\n| " .. string.format("%.2f", median) .. "\n|-\n"
    result = result .. "| Дисперсия\n| " .. string.format("%.2f", variance) .. "\n|-\n"
    result = result .. "| Стандартное отклонение\n| " .. string.format("%.2f", stddev) .. "\n|-\n"
    result = result .. "| Минимум\n| " .. string.format("%.2f", data[1]) .. "\n|-\n"
    result = result .. "| Максимум\n| " .. string.format("%.2f", data[#data]) .. "\n|-\n"
    result = result .. "|}\n"
    
    return result
end

return stats