【问题标题】:C# to mimic Excel SLOPE functionC# 模仿 Excel SLOPE 函数
【发布时间】:2013-11-28 01:16:32
【问题描述】:

我正在尝试计算两个数据列表的斜率。您可以使用 SLOPE 函数在 EXCEL 中轻松计算此值。 =SLOPE(A1:A100, B1:B100)。我试图在 C# WinForm 中模仿这个函数。这是我的代码,它可以计算一些东西,但不是你从 Excel 函数中得到的正确数字。请帮我在这里找到错误。非常感谢!

private double Getslope(List<double> ProductGrossExcessReturnOverRFR, List<double> primaryIndexExcessReturnOverRFR, int months, int go_back = 0)
{
    double slope = 0;
    double sumx = 0, sumy = 0, sumxy = 0, sumx2 = 0;
    for (int i = ProductGrossExcessReturnOverRFR.Count - 1 - go_back; i > ProductGrossExcessReturnOverRFR.Count - (1 + months + go_back); i--)
    {
        sumxy += ProductGrossExcessReturnOverRFR[i] * primaryIndexExcessReturnOverRFR[i];
        sumx += ProductGrossExcessReturnOverRFR[i];
        sumy += primaryIndexExcessReturnOverRFR[i];
        sumx2 += ProductGrossExcessReturnOverRFR[i] * ProductGrossExcessReturnOverRFR[i];      
    }

    return slope = 1 / (((sumxy - sumx * sumy / months) / (sumx2 - sumx * sumx / months)));
}

测试数据:
{1.085231224, 2.335034309, 0.346667278}
{3.185231224,3.705034309 , -0.883332722} 如果您在 Excel 中使用 =SLOPE 函数计算,其斜率应为 0.3373。但我的代码以某种方式产生 0.47...

【问题讨论】:

  • 一些输入数据和预期结果会有所帮助
  • {1.085231224, 2.335034309, 0.346667278} 和 {3.185231224,3.705034309 , -0.883332722} 如果在 Excel 中使用 =SLOPE 函数计算,则斜率应为 0.3373。但我的代码以某种方式产生 0.47...
  • 您对输入条件非常不清楚({1.085231224, 2.335034309, 0.346667278}{3.185231224,3.705034309 , -0.883332722} 到底是什么意思?);关于你的公式(months 是什么意思?);而且您甚至没有提供验证计算的方法(可能很容易在 Excel 中输入的东西)。你能改善这一切吗?

标签: c# winforms excel list math


【解决方案1】:

我认为你的公式是错误的

根据 Excel 文档,SLOPE 的公式为

还要注意,函数的第一个参数是 y 值。

目前还不清楚gobackmonths 是如何应用的,但它看起来可能会起作用:

private double Getslope(List<double> ProductGrossExcessReturnOverRFR, 
                        List<double> primaryIndexExcessReturnOverRFR, 
                        int months, 
                        int go_back = 0)
{
    // calc # of items to skip
    int skip = ProductGrossExcessReturnOverRFR.Count - go_back - months;

    // get list of x's and y's
    var ys = ProductGrossExcessReturnOverRFR.Skip(skip).Take(months);
    var xs = primaryIndexExcessReturnOverRFR.Skip(skip).Take(months);

    // "zip" xs and ys to make the sum of products easier
    var xys = Enumerable.Zip(xs,ys, (x, y) => new {x = x, y = y});

    double xbar = xs.Average();
    double ybar = ys.Average();

    double slope = xys.Sum(xy => (xy.x - xbar) * (xy.y - ybar)) / xs.Sum(x => (x - xbar)*(x - xbar));

    return slope;
}

【讨论】:

  • @D Stanley,您的代码得到 2.11,即 1/0.47。所以本质上和我的一样。我的代码中的 int 月是每个列表中的数据数。 int go_back 在大多数情况下定义为 0,但我用它来处理其他函数中的 Year-To-Date 情况。这里应该不是问题。
  • @Eddie 您能否提供一种方法来验证您通过 cmets 建议的计算?例如 3/4 例。就涉及很多操作而言,这可能是一个舍入问题。
  • 我认为@D Stanley 刚刚在上面编辑了他的代码,它现在可以工作了。 @D Stanley 你能告诉我自从第一次发帖后你有什么变化吗?谢谢!
  • @Eddie 当您在给定用户的答案中时,您不需要写@。您也可以查看上面的“Edited X mins ago”链接。但是,请在未来提供更好的信息,因为 D Stanley 所做的基本上是一个幸运的猜测(你的问题中没有足够的信息来确定你想要什么)。 PS:如果您回答与您交谈的人,那将是一件好事。
  • @varocarbas 我切换了xs 和ys。 SLOPE 将 ys 作为第一个参数 - 我假设您使用 xs 的第一个参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-16
  • 2013-06-09
  • 1970-01-01
  • 2023-02-24
  • 1970-01-01
  • 2018-11-12
  • 1970-01-01
相关资源
最近更新 更多