El objetivo de esta clase es obtener algunos cálculos estadísticos a partir de una muestra (tabla o cursor) y de un nombre de campo a analizar. En el caso de Media Ponderada se describe el ejemplo con la media de población de una provincia y municipio, y es aplicable para otra situación.
Se puede complementar con otras funciones que no se calculan. El código fue escrito y depurado con la participación de Fernando Puyuelo Ossorio, Juan Carlos Sanchez, Jorge Mota y Ana María Bisbé. Esperamos que sea de utilidad. Agradecemos sugerencias.
* Ejemplo de llamada
* En cada Procedure se describen los parámetros
oEst = CREATEOBJECT("oEstadisticas")
oEst.CalculosEstadisticos(100, 10, 'curEstadisticas', 'Ventas', 'España', 'Madrid',;
&tnmedia, &tnDesviacionTipica, &tnModa, &tnMediana, &tnPercentil25,;
&tnPercentil75, &tnMaximo, &tnMinimo)
* Donde:
* tnMuestras - Cantidad de muestras que cumplieron las condicones. Por ej. 100
* tnPorcientoExtremo - Indica el porciento a eliminar en ambos extremos. Por ej. 10
* tcCursorMuestras - Nombre del cursor en el que se encuentra la muestra. Por ej. 'curEstadisticas'
* tcCampoValor - Campo por el que se realizarán los cálculos. Por ej. 'Ventas'
* tcPais - pais que se recibe como parámetro. Por ej. 'España'
* tcProvincia - provincia que se recibe como parámetro. Por ej. 'Madrid'
**************************************************
*-- Class: oestadisticas ()
*-- ParentClass: custom
*-- BaseClass: custom
*-- Time Stamp: 09/01/03 06:19:10 PM
* Programador: Ana María Bisbé York
DEFINE CLASS oestadisticas AS SESSION
HEIGHT = 23
WIDTH = 145
NAME = "oestadisticas"
PROCEDURE CalculosEstadisticos
*---------------------------------------------------------
* Método:
* OESTADISTICAS.CALCULOSESTADISTICOS
* Parameters:
* tnMuestras - Cantidad de muestras que cumplieron las condicones
* tcCampoValor - Campo por el que se realizarán los cálculos
* tnPorcientoExtremo - Indica el porciento a eliminar en ambos extremos
* tcCursorMuestras - Nombre del cursor en el que se encuentra la muestra
* tcPais - pais que se recibe como parámetro
* tcProvincia - provincia que se recibe como parámetro
* Valores que retorna
* Resultantes de los cálculos que son:
* lnMedia, lnDesviacionTipica, lnModa, lnMediana, lnPercentil25, lnPercentil75, lnMaximo, lnMinimo
* Objetivo:
* Obtener las estadísticas de los valores para la zona actual. Para ello es necesario
* - Descartar valores extremos
* - Calcular Media / Media Ponderada
* - Calcular Desviación Típica
* - Calcular Moda
* - Calcular Mediana
* - Calcular Percentil25
* - Calcular Percentil75
* - Calcular Máximo
* - Calcular Mínimo
*---------------------------------------------------------
PARAMETERS tnMuestras, tnPorcientoExtremo, tcCursorMuestras, tcCampoValor, tcPais, tcProvincia,;
tnmedia, tnDesviacionTipica, tnModa, tnMediana, tnPercentil25, tnPercentil75, tnMaximo, tnMinimo
* Descartar extremos
THIS.descartaextremos(tnMuestras, tnPorcientoExtremo, tcCursorMuestras)
* Calcular Media
tnmedia = THIS.calcularmedia(tcCursorMuestras, tcCampoValor)
* Calcular Media Ponderada
tnMediaPonderada = THIS.calcularmediaponderada(tcCursorMuestras, tcCampoValor, tcPais, tcProvincia)
* Calcular Desviación Típica
tnDesviacionTipica = THIS.calculardesviaciontipica(tcCursorMuestras, tcCampoValor)
* Calcular Moda
tnModa = THIS.calcularmoda(tcCursorMuestras, tcCampoValor)
* Calcular Mediana * idem fórmula para los percentiles 25, 75 y 50(mediana) se emplea el mismo método
tnMediana = THIS.calcularpercentil(tcCursorMuestras, 50, tcCampoValor)
* Calcular Percentil25
tnPercentil25 = THIS.calcularpercentil(tcCursorMuestras, 25, tcCampoValor)
* Calcular Percentil75
tnPercentil75 = THIS.calcularpercentil(tcCursorMuestras, 75, tcCampoValor)
* Calcular Máximo
SELE (tcCursorMuestras)
CALCULATE MAX(valor) TO tnMaximo
* Calcular Mínimo
SELE (tcCursorMuestras)
CALCULATE MIN(valor) TO tnMinimo
ENDPROC
PROTECTED PROCEDURE descartaextremos
*---------------------------------------------------------
* Método:
* OESTADISTICAS.DESCARTAEXTREMOS
* Parameters:
* tnMuestras - cantidad de muestras
* tnPorcientoExtremo - porciento a descartar
* tcCursorMuestras - nombre del cursor que contiene la muestra
* Objetivo:
* Descartar los valores extremos de la muestra.
* La cantidad de valores a descartar se determina por el porciento a descartar (tnPorcientoExtremo) y
* la cantidad de elementos de la muestra (tnMuestra)que es devuelto por THIS.DeterminaMinimoMuestras)
*---------------------------------------------------------
PARAMETERS tnMuestras, tnPorcientoExtremo, tcCursorMuestras
LOCAL lnExtremos
lnExtremos = 0 && Cantidad de elementos a descartar por cada extremo
lnExtremos = INT( tnMuestras * tnPorcientoExtremo / 100)
IF lnExtremos <> 0
IF USED(tcCursorMuestras)
SELE (tcCursorMuestras)
GO TOP
IF !EOF()
DELETE NEXT lnExtremos && elimino los valores extremos en el inicio del cursor
ENDIF
GO BOTT
IF !EOF()
SKIP - (lnExtremos - 1)
DELETE REST && elimino los valores extremos en el final del cursor
ENDIF
ENDIF
ENDIF
ENDPROC
PROCEDURE calcularmedia
*---------------------------------------------------------
* Método:
* OESTADISTICAS.CALCULARMEDIA
* Parameters:
* tcCursorMuestras - nombre del cursor que contiene la muestra
* tcCampoValor - nombre del campo
* Valor que retorna
* lnMedia - Valor de la media artimética
* Objetivo:
* Calcular media aritmética
* La media aritmética es la suma de todos los valores de la variable
* dividido por el número total de observaciones
*---------------------------------------------------------
PARAMETERS tcCursorMuestras, tcCampoValor
LOCAL lnMedia
lnMedia = 0 && Valor de la media artimética que se retorna
SELE (tcCursorMuestras)
CALCULATE AVG(&tcCampoValor) TO lnMedia
RETURN lnMedia
ENDPROC
PROCEDURE calculardesviaciontipica
*---------------------------------------------------------
* Método:
* OESTADISTICAS.CALCULARDESVIACIONTIPICA
* Parameters:
* tcCursorMuestras - nombre del cursor que contiene la muestra
* tcCampoValor - nombre del campo
* Valor que retorna
* lnDesviacionTipica - Valor calculado de Desviación Típica
* Objetivo:
* Calcular Desviación Típica - Raiz cuadrada de la varianza, hay función nativa de VFP para ello
*---------------------------------------------------------
PARAMETERS tcCursorMuestras, tcCampoValor, tnDesviacionTipica
LOCAL lnDesviacionTipica
lnDesviacionTipica = 0 && valor calculado de Desviación Típica
SELE (tcCursorMuestras)
CALCULATE STD(&tcCampoValor) TO lnDesviacionTipica
RETURN lnDesviacionTipica
ENDPROC
PROCEDURE calcularmoda
*---------------------------------------------------------
* Método:
* OESTADISTICAS.CALCULARMODA
* Parameters:
* tcCursorMuestras - nombre del cursor que contiene la muestra
* tcCampoValor - nombre del campo
* Valor que retorna
* lnModa - Valor de la Moda
* Objetivo:
* Calcular moda - es el valor que se repite más veces, es decir, aquel que tiene mayor frecuencia absoluta
* para variables con muchos valores posibles, tiene sentido considerar intervalos de valores
* y definir la moda como el intervalo que acumula mayor observaciones
* Se divide el recorrido de la variable en intervalos y se calcula cual es el intervalo o intervalos
* con mayor número de observaciones. Se toma el primer intervalo con mayor número de muestras.
*---------------------------------------------------------
PARAMETERS tcCursorMuestras, tcCampoValor
LOCAL lnModa, lccampo, lnRedondeo
lnModa = 0 && valor de Moda que se calcula
lccampo = '' && temporal para concatenar el campo del select
lnRedondeo = 100 && determina el valor al que se debe redondear (se puede pasar como parámetro)
lccampo= 'cursorMuestras.' + tcCampoValor
SELECT ROUND(&lccampo / lnRedondeo,0) * lnRedondeo AS valor, COUNT(*) AS cuenta;
FROM (tcCursorMuestras) AS CursorMuestras GROUP BY valor ORDER BY cuenta DESC;
INTO CURSOR TempModa
IF _TALLY <> 0
GO TOP
lnModa = valor
ENDIF
USE IN SELECT ('TempModa')
RETURN lnModa
ENDPROC
PROCEDURE calcularpercentil
*---------------------------------------------------------
* Método:
* OESTADISTICAS.CALCULARPERCENTIL
* Parameters:
* tcCursorMuestras - nombre del cursor que contiene la muestra
* tcCampoValor - nombre del campo
* tnPercentil - 25 / 50 / 75
* Valor que retorna
* lnPercentil - Valor del percentil calculado
* Objetivo:
* Calcular el Valor de la muestra en la posición que ocupa el 25 - 50 - 75 porciento
* Se denomina Mediana al valor de la variable que, tras ordenar los datos de menor a mayor
* deja a su izquierda y a su derecha igual cantidad de datos, o sea es el que esta en el medio
* es igual que sacar el Percentil del 50%
*---------------------------------------------------------
PARAMETERS tcCursorMuestras, tnpercentil, tcCampoValor
LOCAL lnPercentil, lnrecno, lccampo, lnValor
STORE 0 TO lnValor, lnrecno, lnPercentil
lccampo = tcCursorMuestras+'.'+tcCampoValor
SELECT &lccampo AS valor FROM (tcCursorMuestras) ORDER BY valor INTO CURSOR curPercentil
IF _TALLY <> 0
COUNT TO lnrecno && cantidad total de elementos de la muestra
lnValor = INT((lnrecno * tnpercentil) / 100)
IF lnValor = 0
GO TOP
ELSE
GO lnValor
ENDIF && voy al recno que se corresponde con la posición
lnPercentil = curPercentil.valor && toma el valor en el recno
USE IN SELECT ('curPercentil') && cierro el cursor, que no hace falta que permanezca abierto
ENDIF
RETURN lnPercentil
ENDPROC
PROCEDURE calcularmediaponderada
*---------------------------------------------------------
* Método:
* OESTADISTICAS.CALCULARMEDIAPONDERADA
* Parameters:
* tcCursorMuestras - nombre del cursor que contiene la muestra
* tcCampoValor - nombre del campo
* tcPais - pais que se recibe como parámetro
* tcProvincia - provincia que se recibe como parámetro
* Valor que retorna
* lnMediaPonderada - Valor de la media artimética ponderada para la provincia
* Objetivo:
* Calcular media ponderada a nivel de provicia
* La media aritmética es la suma de todos los valores ordenados de la variable
* dividido por el número total de observaciones
* A la media calculada para el campo valor a nivel de cada municipio se le asigna un peso que queda determinado
* por el porcentaje de habitantes que tiene respecto al total provincial. Para ello:
* - Obtener las poblaciones de los municipios de la provincia seleccionada y la media AVG(valor)
* - Se obtiene la cantidad total de poblacion para la provincia
* - Para cada municipio
* - Media ponderada = MediaPonderada + MediaMunicipio * (PoblacionMunicipio / PoblacionProvincia)
*---------------------------------------------------------
PARAMETERS tcCursorMuestras, tcCampoValor, tcPais, tcProvincia
LOCAL lnMediaPonderada, lnPoblacion, lcMunicipi
lnMediaPonderada = 0 && Valor calcularo de Media Aritmética Ponderada que se calcula
lnPoblacion = 0 && Población de un municipio
lnPobTotal = 0 && Población total de la provncia
lcMunicipi = '' && var. temporal para buscar
* De la tabla municipi se seleccionan los datos de población para cada municipiid que tengo
* en la muestra estadistica CursorMuestras.municipiid
SELECT curMuestraEstadis.municipiid, municipi.derecho AS poblacion, ;
AVG(curMuestraEstadis.valor) AS MediaMuni ;
FROM curMuestraEstadis, municipi ;
WHERE curMuestraEstadis.municipiid = municipi.municipiid AND ;
municipi.provinciid = tcProvincia AND municipi.paisid = tcPais;
GROUP BY municipi.municipiid ;
INTO CURSOR tempMedia
IF _TALLY <> 0
USE DBF('tempMedia') IN 0 SHARE AGAIN ALIAS ('curPoblacion')
ENDIF
USE IN SELECT('tempMedia')
USE IN SELECT ('municipi')
* Se obtiene la cantidad total de poblacion para la provincia
SELECT curPoblacion
SUM curPoblacion.poblacion TO lnPobTotal
GO TOP
SCAN
lnMediaPonderada = lnMediaPonderada + MediaMuni * IIF(lnPobTotal = 0, 0 , poblacion / lnPobTotal)
ENDSCAN
USE IN SELECT ('curPoblacion')
ENDIF
RETURN lnMediaPonderada
ENDPROC
ENDDEFINE
*
*-- EndDefine: oestadisticas
Fuente : PortalFox
Blasito.