miércoles, 23 de octubre de 2024

Funciones. Estadística.

Puntuaciones estandarizadas (Z)

Las puntuaciones estandarizadas o tipificadas o simplemente puntuaciones Z son otros estadísticos que requieren del conocimiento previo de la media (promedio) y de la desviación típica (Dt). En vez de orientarse al análisis descriptivo de los datos, se orientan al análisis de los resultados individuales, aunque en términos de referencia a la norma (normalización estadística), lo que supone, a su vez, referencia a la curva de distribución "normal".


En términos de programación, en este caso, aunque contamos con una función Calc que [nos permite realizar estos cálculos] (1), el uso de OOo Basic nos aporta ventajas en el cálculo (y el análisis) de estas puntuaciones, aunque para ello deberemos integrar la función de cálculo de las puntuaciones Z en un procedimiento general de trabajo con el conjunto de datos, cosa que queda pendiente, ya que sobrepasa los objetivos de esta entrada. 

En ella me limitaré a desarrollar una función que calcule estos valores, pero, como no puede ser de otra manera en esta ocasión, será necesario acompañar la explicación de la función (fPntZ()) con la del script desde el que se la llama, adelantando hasta donde es imprescindible, lo que corresponde al desarrollo del procedimiento de trabajo.

Sub DtDatos

'Variables

Dim mNotas() As Integer
Dim vMed As Double, vDt As Double
Dim mPuntZ() As Double
Dim i As Integer

'Contenido de las matrices

mNotas() = Array(0,0,0,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,5,6,6,6,6,6,6,7,7,7,8,8,8,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10)
ReDim mPuntZ(UBound(mNotas()))

'Llamadas a funciones

vMed =fMedia(mNotas())
vDt = fDesTip(mNotas())
mPuntZ() = fPntZ(vMed,vDt,mNotas())

'Mostrar resultados

MsgBox "Valor de la media de la muestra: " & CStr(vMed)
MsgBox "Valor de la desviación típica de la muestra:  " & CStr(vDt)

For i = 0 To UBound(mPuntZ())
MsgBox "Puntuación directa (PD)  " & CStr(mNotas(i)) & Chr(13) & "Puntuación típica (Z) " & CStr(mPuntZ(i))
Next

End Sub

En el script deberemos contar con las variables y matrices necesarias para contender los datos del promedio (vMed), la Dt (vDt), las puntuaciones directas (PD) (mNotas()) y las puntuaciones Z (pZ) (mPuntZ()).

Por agilizar la ejemplificación, se recogen las PD mediante un array para completar la matriz correspondiente (mNotas()) y se dimensiona la matriz de las pZ en base al tamaño de esa matriz (ReDim mPuntZ(UBound(mNotas()))).

Posteriormente se llaman a las funciones de cálculo de la media (vMed =fMedia(mNotas())), la Dt (vDt = fDesTip(mNotas())) y las pZ (mPuntZ() = fPntZ(vMed,vDt,mNotas())) (2).

Para finalizar, y por mostrar los resultados y comprobar el funcionamiento del script y de las funciones, hago uso de la función MsgBox() para mostrar los resultados parciales (v.g. MsgBox "Valor de la media de la muestra: " & CStr(vMed)) y final, éste mediante un ciclo (For i = 0 To UBound(mPuntZ())) que recorre ambas matrices y muestra los valores PD y pZ, también mediante MsgBox().

En cuanto a la función mPuntZ() propiamente dicha...

Function fPntZ(pMed As Double, pDt As Double, pPD() As Object) As Object

Dim i As Integer
Dim mNormalizar() As Double

ReDim mNormalizar(UBound(pPD()))

For i = 0 To UBound(pPD())
mNormalizar(i) = (pPD(i)-pMed)/pDt
Next

fPntZ = mNormalizar()

End Function

... cuenta con tres parámetros (fPntZ(pMed As Double, pDt As Double, pPD() As Object) As Object), motivo por el que debe recibirlos desde el script (mPuntZ() = fPntZ(vMed,vDt,mNotas())), para lo que antes de ser llamada deben haberlo sido las funciones que aportan los datos que son requeridos (3). Obsérvese que el último de estos parámetros se define en la función como de tipo Object (pPD() As Object), al igual que la propia función.

Además de estos tres parámetros, fPntZ() precisa una variable contador (Dim i As Integer) y una matriz de trabajo (Dim mNormalizar() As Double), que será la que reciba el resultado de los cálculos. Dado que no podemos dimensionarla en el momento de su declaración (4) lo hacemos a posteriori sobre el dato que nos aporta la función UBound() aplicada sobre la matriz-parámetro (ReDim mNormalizar(UBound(pPD()))).

Lo que resta es recorrer la matriz-parámetro (que contiene los datos de las PD) mediante un bucle (For i = 0 To UBound(pPD())) para asignar a la matriz de trabajo el resultado de la fórmula de cálculo de la pZ [ver aquí] (mNormalizar(i) = (pPD(i)-pMed)/pDt) y retornar la matriz como resultante de la función (fPntZ = mNormalizar()). Mediante este procedimiento podemos realizar el cálculo de pZ de un amplico conjunto de datos de una sola vez (5).

En cierto modo, y al margen del interés que tienen los datos que aporta esta función, en términos de programación, también nos interesa por ser expresión de un procedimiento de trabajo en el que devolvemos como resultado de la función una matriz de datos numérica, complementaria y paralela a la matriz originaria.

NOTAS

(1) En esta entrada se expone también la explicación de las puntuaciones normalizadas. Se recomienda su lectura.
(2) Obsérvese que es el script el encargado de utilizar estas funciones, lo que implica un planteamiento modular. Dado que las funciones fMedia() fDesTip() ya han sido explicadas, no corresponde hacerlo ahora; sí la nueva función fPntZ()  que explicaré a continuación, por lo que será necesario volver sobre este punto del desarrollo del script.
(3) Me refiero al valor Promedio y Dt que aportan las funciones correspondientes, citadas también en la nota 2.
(4) Por un motivo obvio: desconocemos el tamaño de la matriz que contiene los datos de las PD y que es pasada como parámetro desde el script (en nuestro caso mNotas() -> pPD() As Object), siendo necesario que ambas tengan el mismo número de elementos.
(5) Lo que, en términos de automatización del proceso, supone una ventaja respecto al uso de la función Calc.

martes, 22 de octubre de 2024

Procedimientos. Datos.

Funciones estadísticas Calc. Puntaciones normalizadas Z. 

Disponemos en Calc de una función que nos permite calcular las puntuaciones Z o puntuaciones normalizadas. Se trata de la función NORMALIZACION(). Dedicaremos esta entrada a explicar esta función y su significado en cuanto a proceso de normalización de las puntuaciones directas, entre otras razones, por el interés que tiene para el análisis de los resultados de las pruebas de evaluación.


El cálculo de las puntuaciones normalizadas (Z) asume que las puntuaciones directas (PD) de la muestra de datos (y más aun de la poblacional) presentan una distribución normal (curva en forma de campana, y más específicamente como campana de Gauss). Se basa en el conocimiento de la media (promedio) y de la desviación típica (Dt), estadísticos que se emplean para su cálculo...

... que se puede describir como cociente de la diferencia de la puntuación directa (PD) respecto a la media, dividido entre la desviación típica (Dt). El resultado puede interpretarse como el número de Dt en que se sitúa la PD. Calcular las p. Z es asignar los datos a una distribución de media 0 y Dt 1.

Este resultado se expresa en valores de signo - (cuando PD es inferior a la media) o de signo + (cuando la PD es superior a la media) que se encuentra acotado inferiormente por -3 y superiormente por +3 (1), siendo excepcionales (atípicos) los valores que se sitúan por debajo o por encima de estos límite. Una p. Z -2 indica que la PD se encuentra situada a 2 Dt por debajo de la media y una p. Z +1 indica que la PD se encuentra situada a 1 Dt por encima de la media.

Las puntuaciones Z permiten comparar las posiciones relativas de dos datos respecto al conjunto de las observaciones, eliminando los efectos de la ubicación y de la escala en que se presenta la PD de dichos datos; además permite identificar los posibles valores atípicos y, en términos de comparación de muestras, facilita las comparaciones entre conjuntos de datos con diferentes métricas.

El cálculo de las puntuaciones normalizadas (Z) se puede realizar en Calc haciendo uso de la función NORMALIZACION(), que requiere tres parámetros: el datos a normalizar (x), el valor de la media (promedio) y el valor de la desviación estándar (Dt).

Para cubrir el conjunto de datos de una muestra deberemos anclar las referencia a Promedio (PROMEDIO()) y a Dt (DESVEST()) y arrastrar el cursor hasta finalizar el recorrido por la columna o fila que contenga los datos de las PD.

En OOo Basic no contamos con una función Built-In para realizar el cálculo de este estadístico, pero aquí te muestro [una creada] por mí, siguiendo la lógica de la función NORMALIZACION() pero aplicada automáticamente a un conjunto de datos, lo que supone una ventaja sobre la función Calc.

NOTA

(1) Dentro de este intervalo (-3/+3) se encuentra el 99,7% de las observaciones en la población. Dentro del intervalo central (Md+/- 1 Dt) se encuentran situadas el 68,2% de las observaciones de la población.

Funciones. Estadística.

Cálculo del coeficiente de variación (Cv)

Una vez que disponemos de funciones para calcular el promedio, la varianza y la desviación típica, tanto como funciones Calc, como funciones OOo Basic, podemos empezar a pensar en desarrollar otras funciones estadísticas que, basadas en ellas, nos permitan trabajar a nivel de análisis de la muestra, creación de valores derivados de dichos estadísticos y análisis de mayor complejidad, como los que implican al menos dos muestras. Empezaremos por el cálculo del coeficiente de variación (Cv).


Hasta donde yo sé, ni Calc ni OOo Basic cuentan con funciones específicas para el cálculo de este coeficiente, por lo que nos deberemos plantear desarrollar directamente un función específica (o genérica) mediante el lenguaje OOo Basic (1). Pero antes de abordar esta tarea, ya que no podemos hacerlo en otro lugar, corresponde que realicemos en esta entrada una breve explicación sobre Cv, su funcionalidad y formulación como estadístico.

El Cv (2) es un estadístico de utilidad relativa tanto para el análisis descriptivo (de la media y de las características de la distribución) como para la estadística bivariada (comparación entre dos variables en cuanto a su grado de homogeniedad vs. dispersión o variabilidad). 

Su cálculo resulta de la división de la media (promedio) entre la desviación típica (Dt) de los datos muestrales y se puede expresar como tal o en forma de porcentaje:


Es, por tanto, un valor que indica el número de veces que el promedio se encuentra dentro de la Dt, lo que equivale a indicar cuánto de homogéneos o dispersos son los datos de esa muestra (o población).

Aunque excepcionalmente pueda ser superior a 1, los valores más frecuentes se dan dentro del intervalo 0-1, de ahí que, para una mejor interpretación de su valor, se emplee su expresión como porcentaje.

Sea en una u otra forma, cuando el Cv es superior a 0,30 o su equivalente porcentual (30%), se entiende que, salvo situaciones especiales (3), la muestra presenta un bajo grado de homogeneidad (alto de variabilidad) y la media (promedio) no resulta ser una medida representativa del conjunto de los datos (no es una buena medida de la tendencia central de los mismos).

Cuando comparamos dos muestras, el Cv sirve para analizar comparativamente su grado o nivel de homogeneidad, sin que sea posible hacer otras afirmaciones, salvo las que derivan de la valoración previa de sus respectivos valores promedio.

Dentro de este campo (análisis bivariado), el Cv aporta la posibilidad de comparación entre variables cuyos valores (valores observacionales, promedios...) se expresan en diferentes unidades o diferentes magnitudes. Ello es debido a que el Cv es adimensional e insensible a los cambios de escala.

A nivel de formulación de la función en OOo Basic, debemos plantearnos previamente si deseamos desarrollar una función que resuelva íntegramente el cálculo del Cv o si haremos uso de un procedimiento modular. 

En el primer caso, la función fCv() (por ejemplo) deberá asumir el cálculo del promedio, de la varianza y de la Dt antes de abordar el cálculo del Cv propiamente dicho. 

En el segundo deberemos plantearnos cómo articular la llamada a las funciones que resuelven esos cálculos previos, incluyendo el papel de la fCv() en ese proceso.

Dado que la primera opción parece poco funcional por excesivamente compleja y extensa (y más si ya disponemos de funciones que resuelve esos cálculos), parece conveniente optar por la segunda solución; pero aun no hemos terminado de resolver cómo enfocar el desarrollo de nuestra función (ahora sí) específica de cálculo del Cv.

Aunque es posible (y para ciertos contextos o preferencias incluso preferible), por sencillez en el planteamiento, mi opción (y la solución que formulo en consecuencia) se basa en asumir que es el script y no la función fCv() el que asume la llamada a las funciones complementarias y previas de cálculo de los estadísticos necesarios (promedio y Dt) (4), por lo que construyo mi función con dos parámetros que se supone entrega el script a la función: uno para el valor del promedio y otro para el valor de la Dt (fCv(med As Long, Dt As Long)), siendo el script igualmente, el responsable de la interpretación del valor resultante (5). Esto supone simplificar en gran medida la formulación de nuestra función, aunque supone un incremento de la complejidad del script, lo que considero se ajusta adecuadamente a la naturaleza del procedimiento y acentúa su modularidad (6).

Atendiendo a las decisiones adoptadas, en este caso es necesario exponer (y explicar) tanto el script desde el que llamamos a la función como la propia función, que resulta extremadamente sencilla. Empecemos por el script.

Sub CoefVar

Dim mDatos() As Integer
Dim vPromedio As Double, vDt As Double, vCv As Double, vCvPc As Double
Dim vValoraMed As String

'Datos de la matriz

mDatos() = Array(0,0,0,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,5,5,6,6,6,6,6,6,7,7,7,8,8,8,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10)

'Llamadas a las funciones

vPromedio = fPromedio(mDatos())
vDt = fDesTip(mDatos())
vCV = fCv(vPromedio,vDt)

'Cálculo del Cv como porcentaje 

vCvPc = vCv * 100

'Valoración cualitativa del resultado (valoración de la media) 

If vCvPc > 30 Then
vValoraMed = "No se puede considerar que la media de la muestra sea un buen resumen de ésta." & CHr(13) &_
"La muestra presenta una elevada variabilidad."
Else
vValoraMed = "La media de la muestra describe correctamente este conjunto de datos."  & CHr(13) &_
"La muestra presenta tendencia a la homogeneidad."

End If

'Visualización de los resultados 

Msgbox vPromedio & " - " & vDt & " - " & vCv & " - " & vCvPc 
MsgBox vValoraMed

 End Sub


En este script, además de recoger el array de los datos (mDatos()) declaramos las variables necesarias para asignar los resultados de las funciones que calculan los estadísticos que necesita el Cv: promedio (vPromedio) y Dt (vDt), así como las relativas al propio Cv en sus dos expresiones numéricas - como cociente (vCv) y como porcentaje (vCvPc), y la valoración de dicho estadístico (vValoraMed) (7).

El paso siguiente implica llamar a las funciones; primero a las que calculan el promedio (vPromedio = fPromedio(mDatos())) y la Dt (vDt = fDesTip(mDatos())) y después (y no antes), disponiendo ya de los datos necesarios, a la función fCv() (vCV = fCv(vPromedio,vDt)) (8).

Posteriormente se realiza el cálculo de Cv en porcentaje (vCvPc = vCv * 100) y el análisis de éste (9) mediante un condicional (If vCvPc > 30 Then) procediendo a su valoración sobre la variable vValoraMed.

Para finalizar el script se muestran los resultados mediante MsgBox(), sin prestar en este momento especial atención a la forma.

Function fCv(promed As Double, Dt As Double) As Double

Dim vCv As Double

vCv = Dt/promed

fCv = vCv

End Function

Sobre la función, como se puede apreciar en el código anterior, hay poco que decir: se trata de una función que recibe dos parámetros numéricos (promed As Double, Dt As Double) y retorna un resultado también numérico (todos ellos de tipo Double). Internamente cuenta con una variable (Dim vCv As Double) receptora del cálculo (vCv = Dt/promed) consistente en una división (Dt/promed) tal y como se expresa en la fórmula de este estadístico. El retorno es también muy simple (fCv = vCv) (10)

NOTAS

(1) Esta limitación en Calc viene dada por la sencillez de la fórmula de dicho coeficiente, aunque es cierto que existen otros de similar nivel de dificultad que sí cuentan con funciones Calc específicas. En OOo Basic la explicación es más sencilla: no existen funciones estadísticas Built-In.
(2) Cv o coeficiente de variación o también coeficiente de variación de Pearson.
(3) Por ejemplo, cuando la media se acerca a 0, el Cv pierde significación, ya que es muy elevado sin que realmente exista necesariamente una alta dispersión de los datos.
(4) El cálculo de la varianza está implícito en el de la Dt y no es directamente necesario en función de la fórmula de cálculo del Cv.
(5) Esta segunda decisión se justifica por las peculiaridades de esta interpretación en función del contexto de los datos, del análisis y del propio tipo de análisis (de la homogeneidad de la muestra vs. de la comparación entre dos variables).
(6) Cierto es que supone un cambio de enfoque respecto a lo mantenido en otras funciones, como la del cálculo de la [varianza] y [de la Dt]. Diré que este cambio de enfoque está justificado por la inviabilidad de un planteamiento de resolución integral de procesos complejos, más allá de los cálculos básicos. De no hacerlo así, las funciones terminarían siendo programas, con lo que perderían su razón de ser.  Al acentuar la modularidad trasladamos la problemática al desarrollo de los procedimientos algorítmicos que involucran varias funciones y script. 
(7) Esta es la única variable de tipo string, siendo las demás (salvo la matriz mDatos()) de tipo Double, ya que así lo requieren los datos resultantes de las funciones.
(8) Posteriormente explicaré la función fCv().
(9) Igualmente, y con el cambio que corresponde en la expresión (If vCvPc > 30 Then) se podría emplear la variable vCv.
(10) Dado que no corresponde en esta entrada, no incido en su texto en el procedimiento de uso de las funciones aquí auxiliares, aunque queda patente el esquema básico del procedimiento modular. En una entrada específica trataré esta cuestión (pendiente)

Funciones. Estadística.

Función para el cálculo de la desviación típica (Dt)

Sabemos que la desviación típica o desviación estándar (Dt en adelante) es un estadístico de dispersión que se basa en la varianza (ver [en esta entrada], en concreto es su raíz cuadrada. Y como no contamos con una función Built-In OOo Basic, deberemos crear una función para su cálculo.


Siendo la Dt un estadístico (s) derivado de la varianza (s2), podemos formular su cálculo como sigue...


... entendiendo que nos estamos refiriendo a la Dt de la muestra, dado que partimos del cálculo de la varianza de ésta y no de la población (1). Lo que tenemos en esta fórmula, es la formulación del cálculo de la varianza sobre la que aplicamos una raíz cuadrada.

En términos de formulación del algoritmo de la función optaremos por partir de la [función del cálculo de la varianza] de modo que sólo nos restará calcular la raíz cuadrada del resultado que nos devuelve dicha función (2).

Pero nos encontramos con un problema: en OOo Basic no contamos con un operador para el cálculo de la raíz cuadrada, por lo que deberemos buscar una alternativa. Esta alternativa consiste en aplicar la equivalencia entre las expresiones de la potencia y de la raíz, partiendo de las propiedades de los exponentes, uno de cuyos casos son los exponentes fraccionarios:

Dado que los exponentes fraccionarios son equivalentes a las raíces, éstas se pueden expresar y calcular como potencias de exponentes fraccionarios, lo que para nuestro caso (raíz cuadrada) permite la siguiente igualdad...


... y aplicado al valor de la varianza se puede expresar como...


... con lo que en nuestro algoritmo podemos usar la segunda expresión de la igualdad para realizar nuestro cálculo, dado que, como dijimos antes, en OOo Basic no disponemos del operador raíz cuadrada.

La función OOo Basic para calcular la Dt (s), queda como sigue:

Function fDesTip(ByRef mDatos() As Object) As Double

Dim vSum As Long
Dim vCuad As Double, vSumCuad As Double, vDesTip As Double
dim vN As Integer, i As Integer
Dim vMed As Double, vVarianza As Double

'Calculo del promedio

vSum = 0
vN = 0

For i = 0 To UBound(mDatos())
vSum = vSum + mDatos(i)
vN = i
Next

vN = vN + 1
vMed = vSum/vN

'Cálculo de la varianza

vCuad = 0
vSumCuad = 0

For i = 0 To UBound(mDatos())
vCuad = ((mDatos(i)-vMed)^2)
vSumCuad = vSumCuad + vCuad
Next

vVarianza = vSumCuad/(vN-1)

'Cálculo de la DT

vDesTip = vVarianza^(1/2) 

fDesTip = vDesTip

End Function

Una vez aclarada la forma de resolver el cálculo de la Dt, la función no presenta mayor dificultad: partimos de la función de la varianza, que a su vez implica el cálculo del promedio, y añadimos el cálculo de la Dt (vDesTip = vVarianza^(1/2)) según lo explicado anteriormente respecto a la equivalencia entre raíz cuadrada y potencia con exponente fraccionario (3). 

NOTA

(1) En cuyo caso, como sabemos, en lugar de n-1 deberíamos usar como divisor el valor N. Obsérvese que ahora s no aparece elevado al cuadrado, ya que usamos precisamente la raíz cuadrada para eliminar el efecto del cuadrado que se aplica a la diferencia de los valores respecto al promedio de los datos de la muestra.
(2) Al igual que en esa función, también aquí podríamos plantearnos usar fVarianza como función auxiliar, reduciendo en mucho el código de la función de cálculo de Dt. No obstante, y por las mismas razones que en esa ocasión, desarrollaremos una función que resuelva el procedimiento al completo.
(3) Lógicamente deberemos añadir una variable Double (vDesTip As Double) para asignar el resultado de dicho cálculo, además de modificar la expresión del Return (ahora fDesTip = vDesTip).

lunes, 21 de octubre de 2024

Funciones. Estadística.

Función para el cálculo de la varianza.

Ya analizamos en [esta entrada] las funciones Calc que nos permiten conocer la variabilidad de la serie o colección de datos que conforman una muestra, destacando la varianza y su derivada, la desviación típica o desviación estándar. Observamos en ella que no existen funciones integrada (Built-In) OOo Basic que nos permita realizar estos cálculos, por lo que deberemos crearlas.


El objetivo de esta entrada es desarrollar el código OOo Basic de la función que calcula la varianza de una muestra, tomando como referencia la fórmula recogida ya en [la entrada] referida a la función Calc equivalente y que reproduzco a continuación:


En cuanto al significado de la fórmula, diremos que la varianza es una unidad promedio de las diferencias entre los valores de la muestra y su media; al elevar este resultado al cuadrado se elimina el efecto de reducción del valor que en el sumatorio tendrían las sumas de valores positivos y negativos. El denominador (n-1) diferencia la fórmula del cálculo del valor muestral del cálculo del valor poblacional (N), en el que no se efectúa esa resta.

En términos de creación de la función OOo Basic, deberemos observar que la varianza (s2) es resultado del sumatorio de las diferencias entre los valores observados y la media aritmética de la muestra, lo que implica que deberemos haber calculado previamente dicho estadístico. También deberemos elevar esos valores al cuadrado y identificar el valor de n (número de observaciones), aunque en este caso, dado que se trata de calcular el estadístico muestral, lo que nos interesa calcular es n-1.

A pesar de las diferencia conceptuales y estadísticas entre media y varianza, en términos de desarrollo del algoritmo de la función, los planteamientos empleados en la función de cálculo de la media nos van a ser útiles para crear esta segunda función. 

De hecho, la primera decisión que deberemos tomar es si creamos una función que calcule la media o si utilizamos la función ya creada desde la nueva, ahorrándonos trabajo y complejidad en la función actual.

Aplicando el principio de modularidad, la respuesta es la segunda opción, pero no siempre resulta funcional, ya que obligamos al usuario de contar con ambas y a relacionarlas. De hecho, en Calc, al menos aparentemente (1), se adopta el criterio de resolver ambos cálculos en una única función, evitando así tener que recurrir al cálculo previo del promedio. 

Por  motivos de funcionalidad, esta segunda opción será la que se asuma en nuestra propuesta, lo que incluye reutilizar el código de la función que calcula el promedio. No obstante, en la explicación de la función de cálculo de la varianza omitiré la explicación de lo que se refiere al de la media aritmética. Para ésta remito a la explicación dada en [la entrada] en que se expone esa función.

Function fVarianza(ByRef mDatos() As Object) As Double

Dim vSum As Long
Dim vCuad As Double, vSumCuad As Double
dim vN As Integer, i As Integer
Dim vMed As Double, vVarianza As Double

'Calculo del promedio

vSum = 0
vN = 0

For i = 0 To UBound(mDatos())
vSum = vSum + mDatos(i)
vN = i
Next

vN = vN + 1
vMed = vSum/vN

'Cálculo de la varianza

vCuad = 0
vSumCuad = 0

For i = 0 To UBound(mDatos())
vCuad = ((mDatos(i)-vMed)^2)
vSumCuad = vSumCuad + vCuad
Next

vVarianza = vSumCuad/(vN-1)

fVarianza = vVarianza

End Function

Es importante que nos fijemos en las variables privadas de la función que tienen que ver con el cálculo de la varianza: todas estas variables (vCuad, vSumCuad vVarianza) han sido declaradas como variables de tipo Double, ya que los cálculos que vamos a realizar requieren este tipo de variable numérica decimal, al tomar como referencia un valor también de tipo (vMed). Si no empleamos una tipología de número decimal, obtendremos un resultado aparentemente correcto, pero estará sesgado si nuestro tipo no incluye valores decimales (por ejemplo, si empleamos el tipo Long), generando un error difícil de localizar y de corregir en algoritmos complejos que empleen nuestra función.

Dicho esto, el modo de realizar el sumatorio de las diferencias entre los valores y la media, elevándolos al cuadrado (2) se resuelve de nuevo con un bucle que recorre la matriz de datos, sobre la que se realiza el sumatorio que, en este caso, incluye una operación (((mDatos(i)-vMed)^2)). Obsérvese que hemos diferenciado la operación (vCuad = ((mDatos(i)-vMed)^2)) del sumatorio propiamente dicho (vSumCuad = vSumCuad + vCuad), dado que trabajamos con dos variables que se complementan (vCuad y vSumCuad). Esto es así por motivos didácticos y de claridad en la formulación del algoritmo, pero podríamos haber trabajado con una única variable y resulto el procedimiento con una única instrucción, sin que se viera afectado el cálculo (v.g. vSumCuad = vSumCuad + ((mDatos(i)-vMed)^2)).

El divisor (vN-1) se ajusta a lo establecido en la fórmula de la varianza de la muestra, aprovechando el valor establecido en vN en el cálculo de la media, aunque cabrían otras opciones (3). Lo que conlleva la opción adoptada es que la resta n-1 sea encuadrada entre paréntesis, ya que, de no ser así, por la primacía de los operadores, primero se realizaría la división vSumCuad/vN y después se restaría -1, algo que evidentemente no nos interesa ya que da lugar a un resultados erróneo (4).


NOTAS

(1) Por apariencia entiendo aquí los datos que se solicitan en la fórmula Calc, que se limitan a la matriz de los valores muestrales.
(2) Tal y como se recoge en la fórmula de la varianza y por las razones que se explican en el texto de la entrada.
(3) Por ejemplo, utilizar como divisor el resultado de la función UBound(mDatos()), lo que ahorraría el uso de la variable vN y aprovecharía el hecho de que ese resultado se ajuste a la fórmula n-1.
(4) En el cálculo de la media esto no sucede porque previamente al uso de vN como divisor del sumatorio de datos, procedemos a modificar esa variable (vN = vN + 1 -> vMed = vSum/vN). También podríamos proceder del mismo modo en el cálculo de la varianza; pero he preferido ejemplarizar los dos modos de proceder.