UDF Error - Structure or Datatype?

Juggler_IN

Active Member
Joined
Nov 19, 2014
Messages
349
Office Version
  1. 2003 or older
Platform
  1. Windows
I am trying to generate Pearson's Correlation Matrix; and subsequently Spearman's.

When I use the Excel's in-built Correl function, I get the output. But, when I use my custom function for correl, I get a VALUE# error. That is, if I replace "Application.WorksheetFunction.Correl" with "PEARSONRHO" I do not get an output.

Functions are:
Code:
Public Function PEARSONMAT(ByVal rng As Range) As Variant

    Dim outRslt() As Double, i As Long, j As Long, iCols As Long


    iCols = rng.Columns.Count
    ReDim outRslt(iCols - 1, iCols - 1)


    For i = 1 To iCols
        For j = 1 To iCols
            outRslt(i - 1, j - 1) = Application.WorksheetFunction.Correl(rng.Columns(i), rng.Columns(j))
        Next j
    Next i


    PEARSONMAT = outRslt


End Function

Public Function PEARSONRHO(ByVal x As Variant, ByVal y As Variant) As Variant


    Dim sx As Double, sy As Double
    Dim s1 As Double, s2 As Double, s3 As Double
    Dim k As Long


    sx = 0
    sy = 0
    s1 = 0
    s2 = 0
    s3 = 0


    For k = 1 To x.Rows.Count
        sx = x(k) + sx
        sy = y(k) + sy
    Next


    sx = sx / x.Rows.Count
    sy = sy / y.Rows.Count


    For k = 1 To x.Rows.Count
        s1 = s1 + (x(k) - sx) * (y(k) - sy)
        s2 = s2 + (x(k) - sx) ^ 2
        s3 = s3 + (y(k) - sy) ^ 2
    Next


    PEARSONRHO = s1 / Sqr(s2 * s3)


End Function
 

Excel Facts

Format cells as time
Select range and press Ctrl+Shift+2 to format cells as time. (Shift 2 is the @ sign).
Application.WorksheetFunction is only for built-in Excel worksheet functions.
 
Upvote 0
Yes, I am aware of the same. When I replace the whole of "Application.WorksheetFunction.Correl" with PEARSONRHO I get an error. PEARSONRHO on a standalone basis works with x,y data.
 
Upvote 0
So where/when do you get the error?
 
Upvote 0
Let me explain, I have the following data:

abcd
44.0089.4744.6111.37
44.0085.8454.308.65
38.0089.0249.8711.95
40.0075.9845.6811.95
44.0081.4239.4413.08
44.0073.0350.5410.13
45.0066.4544.7511.12
54.0083.1251.8610.33
51.0069.6340.8410.95
48.0091.6346.7710.25
57.0073.3739.4112.63
52.0076.3245.449.63
51.0067.2545.1211.08
51.0073.7145.7910.47

<colgroup><col span="4"></colgroup><tbody>
</tbody>

With "Application.WorksheetFunction.Correl" in PEARSONMAT I get the following output from PEARSONMAT as an Array formula:

abcd
1.000000-0.357957-0.305628-0.129392
-0.3579571.0000000.383502-0.095889
-0.3056280.3835021.000000-0.706011
-0.129392-0.095889-0.7060111.000000

<colgroup><col span="4"></colgroup><tbody>
</tbody>

But when I replace the .Correl with PEARSONRHO, I get error:

abcd
#VALUE!#VALUE!#VALUE!#VALUE!
#VALUE!#VALUE!#VALUE!#VALUE!
#VALUE!#VALUE!#VALUE!#VALUE!
#VALUE!#VALUE!#VALUE!#VALUE!

<colgroup><col span="4"></colgroup><tbody>
</tbody>

Why is this happening?
 
Upvote 0
The modified function, which is giving error, is:

Code:
Public Function PEARSONMAT(ByVal rng As Range) As Variant

    Dim outRslt() As Double, i As Long, j As Long, iCols As Long


    iCols = rng.Columns.Count
    ReDim outRslt(iCols - 1, iCols - 1)


    For i = 1 To iCols
        For j = 1 To iCols
            outRslt(i - 1, j - 1) = PEARSONRHO(rng.Columns(i), rng.Columns(j))
        Next j
    Next i


    PEARSONMAT = outRslt

End Function
 
Upvote 0
The PEARSONRHO function fails here.
Code:
    For k = 1 To x.Rows.Count
        sx = x(k) + sx
        sy = y(k) + sy
    Next
Not 100% sure why but code stops execution on this line.
Code:
sx = x(k) + sx

If I step through the code and stop at the line immediately before the above line and then enter this,
Code:
? x(k)
in the Immediate Window I get a type mismatch error.

What should x(k) return?
 
Upvote 0
When rng.Columns(i) is passed to PEARSONRHO, it receives a Range object. However, since it receives a column, you'll need to refer to the Cells property of the Range object. Also, since it refers to a worksheet range, the reference is a two dimensional one. So, for example, you should do it like this...

sx = x.cells(k,1).value + sx
 
Upvote 0
Try this.
Code:
Public Function PEARSONRHO(ByVal x As Variant, ByVal y As Variant) As Variant
Dim sx As Double, sy As Double
Dim s1 As Double, s2 As Double, s3 As Double
Dim k As Long

    For k = 1 To x.Rows.Count
        sx = x.Cells(k, 1).Value + sx
        sy = y.Cells(k, 1) + sy
    Next

    sx = sx / x.Rows.Count
    sy = sy / y.Rows.Count

    For k = 1 To x.Rows.Count
        s1 = s1 + (x.Cells(k, 1).Value - sx) * (y.Cells(k, 1).Value - sy)
        s2 = s2 + (x.Cells(k, 1).Value - sx) ^ 2
        s3 = s3 + (y.Cells(k, 1).Value - sy) ^ 2
    Next

    PEARSONRHO = s1 / Sqr(s2 * s3)

End Function

PS You could probable avoid having to use Cells if you passed arrays to PEARSONRHO rather than ranges.
 
Last edited:
Upvote 0

Forum statistics

Threads
1,215,514
Messages
6,125,272
Members
449,219
Latest member
daynle

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top