Reputation: 153
So here is my situation:
I've a large amount of data, with x values of 1-18, but y values that vary.. some of which are blanks because the equation is /0 - arranged in rows.
I am trying to get the m^3, m^2, m, c coefficients of the polynomial trend line for every row of y values.. y1, y2 etc.
Because I can not use Linest() with blanks I am trying to use VBA to copy out all the relevant (non-blank) y-values, but also removing the associated x-value for that row.
Here is an example section of the data - but there are more rows
x 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 m3 m2 m c
y1 0.0 1.0 2.0 2.0 1.0 0.0 1.0 - 2.0 2.0 1.0 2.0 2.5 1.0 1.0 2.0 1.0 4.0 ? ? ? ?
y2 0.0 1.0 - 2.0 2.0 0.0 2.0 2.0 0.0 1.7 4.0 1.0 2.0 2.0 4.0 1.0 3.0 2.0 ? ? ? ?
So far I have been trying without much success.
So far I have been trying something like this, but without success, but this is my first ever VBA attempts.. so sorry if I am unaware of the obvious!!
'code to identify known_y and known_x ranges
For each testvalue in known_y
If testvalue indicates that this point should be included in regression
then copy this data point (both known_y and known_x value for this point) either into an array (if I want to invoke LINEST() from within VBA) or into another range in the spreadsheet.
Next testvalue
Invoke LINEST() using the copied data
If anyone could help it would be much appreciated!!
Upvotes: 0
Views: 286
Reputation: 60199
Here is one approach using VBA. Since you start by looking for m3, I am assuming this is a third order polynomial. In any event, in the UDF myPolyLinest, the "order" is an argument named "maxPower. Other than that, it is similar to the worksheetfunction, and returns the same array of results. It filters out columns that don't have a numeric value. It does it for each set of Y values individually.
The formula on the worksheet would look like:
m3: =INDEX(myPolyLinest($B2:$S2,$B$1:$S$1,3),1,1)
m2: =INDEX(myPolyLinest($B2:$S2,$B$1:$S$1,3),1,2)
m1 =INDEX(myPolyLinest($B2:$S2,$B$1:$S$1,3),1,2)
where the arguments for the INDEX function are used to return the desired value I'm not sure what you mean by "c" coefficient as that is not described in LINEST Help for my version of Excel. But you should be able to figure it out from that file and the description of the return values.
Option Explicit
Function myPolyLinest(knownYs As Range, knownXs As Range, Optional maxPower As Long = 1, _
Optional notForceZero As Variant = True, Optional Stats As Variant = False) As Variant
Dim vX As Variant, vY As Variant
Dim I As Long
Dim J As Long
Dim colXY As Collection
vX = knownXs
vY = knownYs
Set colXY = New Collection
For I = 1 To UBound(vX, 1)
For J = 1 To UBound(vX, 2)
If Not IsError(vY(I, J)) Then
If vX(I, J) <> "" And vY(I, J) <> "" And _
IsNumeric(vX(I, J)) And IsNumeric(vY(I, J)) Then
colXY.Add Array(vX(I, J), vY(I, J))
End If
End If
Next J
Next I
ReDim vX(1 To colXY.Count, 1 To maxPower)
ReDim vY(1 To colXY.Count, 1 To 1)
For I = 1 To colXY.Count
For J = 1 To maxPower
vX(I, J) = colXY(I)(0) ^ (J)
Next J
vY(I, 1) = colXY(I)(1)
Next I
myPolyLinest = WorksheetFunction.LinEst(vY, vX, notForceZero, Stats)
End Function
Upvotes: 1