基于范围内的数据计算线性回归,而不是完整数据集

问题描述 投票:-1回答:1

因此,目前可在以下位置获得的脚本://rawgithub.com/phpepe/highcharts-regression/master/highcharts-regression.js计算串行完整数据集的线性回归。是否可以修改此值以基于范围内的数据计算线性回归。即1个月线性回归,3个月线性回归...

function _linear(data, decimalPlaces, extrapolate) {
    var sum = [0, 0, 0, 0, 0], n = 0, results = [], N = data.length;

    for (; n < data.length; n++) {
        if (data[n]['x'] != null) {
            data[n][0] = data[n].x;
            data[n][1] = data[n].y;
        }
        if (data[n][1] != null) {
            sum[0] += data[n][0]; //Σ(X)
            sum[1] += data[n][1]; //Σ(Y)
            sum[2] += data[n][0] * data[n][0]; //Σ(X^2)
            sum[3] += data[n][0] * data[n][1]; //Σ(XY)
            sum[4] += data[n][1] * data[n][1]; //Σ(Y^2)
        } else {
            N -= 1;
        }
    }

我可以看到它正在计算完整data.length的线性回归。如何将数据长度设置在所选范围内。我想要每条回归线而不是一条回归线。

见jsfiddle:http://jsfiddle.net/x0pya5gt/

javascript highcharts
1个回答
3
投票

highcharts-regression默认情况下没有此功能。您可以更改regression.js并添加此功能。您应首先下载代码(显然)并将其放在某处并将该文件包含在您的代码中。那你应该像这样改变processSerie函数:

var processSerie = function (s, method, chart) {
    if (s.regression && !s.rendered) {
        s.regressionSettings = s.regressionSettings || {};
        s.regressionSettings.tooltip = s.regressionSettings.tooltip || {};
        s.regressionSettings.dashStyle = s.regressionSettings.dashStyle || 'solid';
        s.regressionSettings.decimalPlaces = s.regressionSettings.decimalPlaces || 2;
        s.regressionSettings.useAllSeries = s.regressionSettings.useAllSeries || false;
        s.regressionSettings.selectedRange = s.regressionSettings.selectedRange || []; // Add selectedRange for passing the range to regression.

        var regressionType = s.regressionSettings.type || "linear";
        var regression;
        var extraSerie = {
            data: [],
            color: s.regressionSettings.color || '',
            yAxis: s.yAxis,
            lineWidth: s.regressionSettings.lineWidth || 2,
            marker: {enabled: false},
            isRegressionLine: true,
            visible: s.regressionSettings.visible,
            type: s.regressionSettings.linetype || 'spline',
            name: s.regressionSettings.name || "Equation: %eq",
            id: s.regressionSettings.id,
            dashStyle: s.regressionSettings.dashStyle || 'solid',
            showInLegend: !s.regressionSettings.hideInLegend,
            tooltip: {
                valueSuffix: s.regressionSettings.tooltip.valueSuffix || ' '
            }
        };

        if (typeof s.regressionSettings.index !== 'undefined') {
            extraSerie.index = s.regressionSettings.index;
        }
        if (typeof s.regressionSettings.legendIndex !== 'undefined') {
            extraSerie.legendIndex = s.regressionSettings.legendIndex;
        }

        var mergedData = s.data;
        if (s.regressionSettings.useAllSeries) {
            mergedData = [];
            for (di = 0; di < series.length; di++) {
                var seriesToMerge = series[di];
                mergedData = mergedData.concat(seriesToMerge.data);
            }
        }

        if (regressionType == "linear") {
            var extrapolate = s.regressionSettings.extrapolate || 0;
            regression = _linear(mergedData, s.regressionSettings.decimalPlaces, extrapolate, s.regressionSettings.selectedRange); // Here you add selectedRange parameter for _linear function
            extraSerie.type = "line";
        } else if (regressionType == "exponential") {
            var extrapolate = s.regressionSettings.extrapolate || 0;
            regression = _exponential(mergedData, extrapolate);
        }
        else if (regressionType == "polynomial") {
            var order = s.regressionSettings.order || 2;
            var extrapolate = s.regressionSettings.extrapolate || 0;
            regression = _polynomial(mergedData, order, extrapolate);
        } else if (regressionType == "power") {
            var extrapolate = s.regressionSettings.extrapolate || 0;
            regression = _power(mergedData, extrapolate);
        } else if (regressionType == "logarithmic") {
            var extrapolate = s.regressionSettings.extrapolate || 0;
            regression = _logarithmic(mergedData, extrapolate);
        } else if (regressionType == "loess") {
            var loessSmooth = s.regressionSettings.loessSmooth || 25;
            regression = _loess(mergedData, loessSmooth / 100);
        } else {
            console.error("Invalid regression type: ", regressionType);
            return;
        }

        regression.rSquared = coefficientOfDetermination(mergedData, regression.points);
        regression.rValue = _round(Math.sqrt(regression.rSquared), s.regressionSettings.decimalPlaces);
        regression.rSquared = _round(regression.rSquared, s.regressionSettings.decimalPlaces);
        regression.standardError = _round(standardError(mergedData, regression.points), s.regressionSettings.decimalPlaces);
        extraSerie.data = regression.points;
        extraSerie.name = extraSerie.name.replace("%r2", regression.rSquared);
        extraSerie.name = extraSerie.name.replace("%r", regression.rValue);
        extraSerie.name = extraSerie.name.replace("%eq", regression.string);
        extraSerie.name = extraSerie.name.replace("%se", regression.standardError);

        if (extraSerie.visible === false) {
            extraSerie.visible = false;
        }
        extraSerie.regressionOutputs = regression;
        return extraSerie;

    }
}

考虑添加的行:

        s.regressionSettings.selectedRange = s.regressionSettings.selectedRange || []; // Add selectedRange for passing the range to regression.

这条线改变了:

        regression = _linear(mergedData, s.regressionSettings.decimalPlaces, extrapolate, s.regressionSettings.selectedRange); // Here you add selectedRange parameter for _linear function

然后在_linear函数中,您应该添加以下更改:

function _linear(data, decimalPlaces, extrapolate, selectedRange) {
    var sum = [0, 0, 0, 0, 0], n = 0, i = 0, results = [], N = data.length;

    for (; i < data.length; i++) {
        if (selectedRange.length == 2)
            if (i < selectedRange[0] || i > selectedRange[1])
                continue;
        if (data[n]['x'] != null) {
            data[n][0] = data[n].x;
            data[n][1] = data[n].y;
        }
        if (data[n][1] != null) {
            sum[0] += data[n][0]; //Σ(X)
            sum[1] += data[n][1]; //Σ(Y)
            sum[2] += data[n][0] * data[n][0]; //Σ(X^2)
            sum[3] += data[n][0] * data[n][1]; //Σ(XY)
            sum[4] += data[n][1] * data[n][1]; //Σ(Y^2)
        } else {
            N -= 1;
    }

的n ++; }

再次考虑将selectedRange添加到函数参数和下面添加的行:

        if (selectedRange.length == 2)
            if (i < selectedRange[0] || i > selectedRange[1])
                continue;

i = 0n++

最后要使用它,您可以在您在系列中使用的regressionSetting对象中传递selectedRange属性。

© www.soinside.com 2019 - 2024. All rights reserved.