【发布时间】:2015-06-02 22:19:09
【问题描述】:
我正在尝试编写一个线性回归函数,它可以动态引用列,可以处理#N/A 值,并且随着时间的推移添加额外的行。这是一个示例数据集:
Date Value 1 Value 2
1/2/1991 #N/A #N/A
2/4/2002 276.36 346.31
1/7/2003 252 350
1/21/2004 232 345.5
1/6/2005 257 368
2/1/2006 278.24 390.11
2/23/2007 #N/A 380.46
2/11/2008 326.34 383.04
2/12/2009 #N/A 399.9
2/17/2009 334.39 #N/A
1/29/2010 344.24 400.83
1/27/2011 342.88 404.52
2/7/2012 379 417.91
1/23/2013 #N/A 433.35
这是我目前基于this forum post 开发的功能。它计算值 1 的线性回归。
=TRANSPOSE(
LINEST(
N(
OFFSET(
INDIRECT("B2" & ":B" & COUNTA(B:B)),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT("B2" & ":B" & COUNTA(B:B))),
ROW(INDIRECT("B2:B" & COUNTA(B:B))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT("B2:B" & COUNTA(B:B))))))), 0, 1)),
N(
OFFSET(
INDIRECT("A2:A" & COUNTA($A:$A)),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT("B2:B" & COUNTA(B:B))),
ROW(INDIRECT("B2:B" & COUNTA(B:B))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT("B2:B" & COUNTA(B:B))))))), 0, 1)),
TRUE, FALSE))
按照目前的编写方式,将我的数组向右拖动以求解值 2 需要手动更新公式。 INDIRECT 公式中引号中的所有内容都必须手动从 B 更改为 C。不过,我有 40 列数据,所以我尝试使用 ADDRESS、ROW 和 COLUMN 使公式完全动态化:
=TRANSPOSE(
LINEST(
N(
OFFSET(
INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2))),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))),
ROW(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))))))), 0, 1)),
N(
OFFSET(
INDIRECT("A2:A" & COUNTA($A:$A)),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))),
ROW(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))))))), 0, 1)),
TRUE, FALSE))
这给了我#REF!。当我对公式进行逐步评估时,看起来问题出现在 Excel 评估 COLUMN 时。它在公式中引入了大括号,该大括号通过 INDIRECT 评估的其余部分传播。这是一个快速比较:
原公式:
INDIRECT("B2:B15")
动态公式:
INDIRECT({"$B$2:$B$15"})
计算结果为#VALUE,此时公式的其余部分被破坏。有没有办法强制 Excel 在此评估中不使用大括号,或者是否有更好的方法来进行此计算?
【问题讨论】:
-
所以最终目的是使第一个公式 'column relative' 可以向右拖动,并且引用字符串中的所有列引用将在离开时移动像 $A:$A 这样的绝对列引用?
-
C 列的正确结果(例如 Value 2)是否为 0.0207852803175708?
-
@Jeeped 在两个帐户上都是正确的。
-
所有答案都很好恕我直言。如果需要,可以扩展到多项式的另一个选项是:
=LINEST(IFERROR(B2:B15,),ISNUMBER(B2:B15)*A2:A15^{0,1},0)
标签: excel excel-formula