2014-04-29

Medir el tiempo de ejecución de procesos en R

Title

proc.time

Para medir el tiempo de ejecución de nuestro código en R usamos la función proc.time. Esta función determina el tiempo real y de la CPU (en segundos) desde que el proceso se inició en R.

t <- proc.time() # Inicia el cronómetro
# NUESTRO CODIGO
proc.time()-t    # Detiene el cronómetro
Muestra en la consola 3 valores: user, system, y elapsed.

user  system elapsed 
0.02    0.00    0.09 
User time es el tiempo de la CPU dedicado a la ejecución del las instrucciones del proceso. System time es el tiempo de la CPU empleado por el sistema operativo (el núcleo o kernel) siguiendo las instrucciones del proceso (abrir ficheros, iniciar otros procesos o mirar al reloj del sistema, etc.). Elapsed time es el tiempo transcurrido 'real' desde que se inició el proceso.

system.time

Para evaluar una sola expresión de R usamos la función system.time. Esta función llama a la función proc.time, evalúa la expresión y vuelve a llamar a la función proc.time devolviendo la diferencia entre ambas llamadas a proc.time.

system.time(NUESTRA EXPRESIÓN) # Sólo necesita un argumento

# Ejemplo:
system.time(for(i in 1:1e7) x <- 1)
Muestra en la consola los mismos valores que proc.time.

user  system elapsed 
2.59    0.01    2.60 

Notas

Aproximadamente el elapsed time es la suma de los dos anteriores: user time más system time. Pero esto no siempre es así. Por ejemplo, si dos tareas de 15 segundos se ejecutan en paralelo en dos núcleos, el user time computa la suma de las dos: 30 segundos. Mientras que elapsed time no incluye la suma del tiempo de las dos tareas en paralelo, solo el tiempo 'real' que la CPU tardó: 15 segundos. El caso contrario sucede, por ejemplo, si introducimos la expresión Sys.sleep(60) en algún punto de nuestro código. Durante ese tiempo la CPU no será utilizada, 0 segundos, pero el elapsed time computará esos 60 segundos y será mayor que la suma del user time más el system time.

Referencias:

proc.time y system.time
IDRE(UCLA)
Significado de proc.time
User time mayor que elapsed time

2014-04-25

Abrir ficheros y aplicaciones con cuadro de diálogo e hipervínculo en Excel

Title En Excel, dos alternativas para abrir otros ficheros o aplicaciones son el cuadro de diálogo y el hipervínculo.

Cuadro de diálogo

   1. Copiamos una de las siguientes subrutinas en un módulo.

'Para un único fichero de Excel
Sub AbrirCuadroDialogo1()
Application.Dialogs(xlDialogOpen).Show
End Sub
'Para abrir múltiples ficheros o aplicaciones
Sub AbrirCuadroDialogo2()
Dim cd As FileDialog
Set cd = Application.FileDialog(msoFileDialogFilePicker)
Dim vrtSelectedItem As Variant
     With cd
        .AllowMultiSelect = True
        If .Show = -1 Then
        For Each vrtSelectedItem In .SelectedItems
            ActiveWorkbook.FollowHyperlink vrtSelectedItem
        Next
        End If
    End With
    Set cd = Nothing
End Sub
   2. Asignamos la macro a la autoforma: clic sobre el botón secundario y elegir Asignar macro en el menú contextual.

   3. Al hacer clic en la autoforma abrirá el cuadro de diálogo y podremos seleccionar uno o múltiples ficheros.

Una alternativa, en el caso de abrir siempre el mismo fichero de Excel, es crear esta subrutina que abrirá el fichero especificado tras Filename:=  

Sub AbrirFichero()
Workbooks.Open Filename:="C:\Carpeta\Libro.xlsx"
End Sub

Hipervínculo 


Los hipervínculos nos permiten acceder a la información dentro del mismo documento o en otros archivos desde Excel. Vamos a tratar de los vínculos a otros documentos, ya sean otros ficheros de Excel, páginas webs u otros programas. 

El hipervínculo se puede asociar a una celda, pero también a un objeto, imagen o gráfico. Seleccionamos la celda u objeto:

- clic sobre el botón secundario y elegir Hipervínculo en el menú contextual; o
- presionamos Ctrl+Alt+K

2014-04-21

Gráfico con punto destacado similar a Google Analytics

Title En Google Analytics podemos hacer un seguimiento de las visitas a nuestro blog con el siguiente gráfico. Si situamos el cursor sobre un día nos indica la fecha y el número de visitas.

Google Analytics


En Excel


Creamos un gráfico similar en Excel. Partimos de dos columnas A y B con los datos exportados de Google Analytics, con las fechas y el número de visitas. Añadimos una columna que representará el punto destacado indicando el número de visitas diarias.

La fórmula de la columna C comprueba si el número de fila es el mismo que el número de la celda E2 vinculada a la barra de desplazamiento. Si es falso, introduce la función NOD que devuelve el valor de error #N/A. Así conseguimos que sólo represente el punto seleccionado con la barra de desplazamiento.

Creamos el gráfico


Creamos un gráfico de área para las visitas y de línea con marcadores para el punto destacado. Formateamos los mismos para obtener los colores apropiados y ajustamos la transparencia para hacer visibles las líneas de división de 60 y 120. Eliminamos la línea del eje de ordenadas. En el eje de abscisas dentro de opciones de eje, al ser una fecha podemos seleccionar la unidad (días, meses o años). En este caso cada 15 días.

Resultado final


Con la barra de desplazamiento controlamos la posición del punto destacado.

2014-04-18

Exportar tabla o consulta de Access como CSV

Title Exportar los distintos objetos de Access, tablas, consultas, formularios e informes es relativamente sencillo a través del asistente para la exportación. Puedes encontrar instrucciones detalladas en exportar datos a un archivo de texto

Un aspecto interesante es guardar las especificaciones de exportación para usarlas más adelante, bien en una macro o bien dentro de un módulo de VBA. Vemos a continuación un ejemplo suponiendo que el tipo de fichero que deseamos exportar es (*.csv).

1. Guardar la especificación de exportación.
2. En el diseño de la macro clic sobre Mostrar todas las acciones y seleccionar TransferirTexto. En argumentos de la acción indicamos los parámetros requeridos:


Tipo de transferencia: Exportar delimitado
Nombre de las especificación: estará disponible la especificación previamente guardada.
Nombre de la tabla, o del objeto que deseamos exportar.
Nombre del archivo: ruta completa del archivo de texto al que se va a exportar.
Contiene nombres de campo: sí.
Las dos últimos parámetros no son necesarios en este caso.

En VBA:

Function ExportarCSV()
DoCmd.TransferText acExportDelim, "Especificacion1", "Tabla1", "C:\Ruta\Tabla1.csv", True, ""
End Function
Entradas relacionadas:
Importar una especificación de importación/exportación en Ms Access: dos métodos
Más entradas de especificación de importación/exportación

2014-04-15

Generar un número aleatorio sin la función ALEATORIO en Excel

Title Casualmente, hace unos días encontré un artículo de ayuda de Microsoft en el que explica como generar un número aleatorio sin la función ALEATORIO en Excel. Particularmente, no encuentro ventaja alguna en la alternativa. Ambas funciones, AHORA y ALEATORIO son volátiles y la alternativa es más verbosa. Por curiosidad y traducir las fórmulas del artículo de Microsoft, muestro la expresión alternativa para generar números aleatorios:

Explicación

Al multiplicar AHORA por 100.000 desplazamos el separador decimal 5 posiciones a la derecha de 41743. Le sustraemos el valor entero y nos queda un número aleatorio decimal entre 0 y 1. Pues a partir de ese 5º dígito decimal, es impredecible el número de serie que genera Excel para almacenar la fecha. Excel almacena las fechas como números secuenciales. Los números enteros (5 primeros dígitos) son las fechas y las fracciones decimales son las horas, minutos y segundos. De esa forma se pueden realizar operaciones con ellas y darles diferentes formatos.

Conviene recordar que los números aleatorios generados por Excel no son realmente aleatorios. Genera números pseudoaleatorios que supuestamente, de acuerdo a Microsoft, satisfacen las pruebas estándar de aleatoriedad (batería de pruebas Diehard). Otros autores afirman lo contrario.

Referencias

2014-04-13

Saltar líneas al importar un fichero de texto en Access

Cuando importamos un fichero de texto, Access no permite especificar desde que línea deseamos que comience la importación. Tan solo podemos indicar si la primera fila contiene los nombres de los campos (saltar la primera fila). 

Para poder indicar a Access el número de líneas que debe saltarse antes de comenzar la importación necesitamos guardar previamente la configuración de importación como una especificación. Una vez guardada, los pasos  a seguir son:

1. Botón de inicio, Opciones de Access, clic en Opciones de exploración o presionamos la secuencia ALT+A+O.


2. En Opciones de exploración, seleccionamos Mostrar objetos del sistema y clic sobre Aceptar.


3. En el panel de control podemos ver las tablas del sistema ocultas.


4. Abrimos la tabla MSysIMEXSpecs. Cada registro es una especificación guardada, comprobamos el nombre aquella que deseamos modificar en el campo SpecName. En el campo StartRow, cambiamos el cero o uno si la primera fila tiene encabezado, por el número de filas que queremos saltar. StartRow empieza la numeración en cero. Por tanto, la especificación de importación importará a partir de la fila indicada más uno.


Cerramos la tabla. En nuestro ejemplo saltará 6 filas y comenzará en la fila nº 7.

2014-04-09

Sucesión de Fibonacci en R

Title Para calcular números de la secuencia de Fibonacci en R, he empleado el código de Neha Pandey

fib <- function(n) {
    a = 0
    b = 1
    for (i in 1:n) {
        tmp = b
        b = a
        a = a + tmp
    }
    return(a)
}
print(fib(79), digits=20)
Sin embargo, si el número sobrepasa los 16 dígitos, de fib(79) en adelante, obtenemos resultados imprecisos. Por ejemplo: fib(79) = 14472334024676220 cuando el resultado correcto es: fib(79) = 14472334024676221.

fib(77) = 5527939700884757 16 dígitos
+
fib(78) = 8944394323791464 16 dígitos
=
fib(79) = 14472334024676221 17 dígitos

Esto es debido a que R almacena los números como números de doble precisión. Una precisión de 53 bits (16 dígitos decimales significativos aproximadamente.

Resolvemos el problema usando el paquete gmp (Multiple Precision Arithmetic). Específicamente la función add.bigz, con la que sumamos bigz (Large Sized Integer Values) números enteros muy grandes.

install.packages("gmp")
require(gmp)
fib <- function(n) {
    a = 0
    b = 1
    for (i in 1:n) {
        tmp = b
        b = a
        a = add.bigz(a, tmp)  # gmp function
    }
    return(a)
}
fib(79)
Así calculamos correctamente números de más de 16 dígitos. He comprobado los resultados para números mucho más largos fib(25000), 5225 dígitos, y los resultados parecen ser precisos hasta el último dígito.

R al igual que otros lenguajes tiene limitaciones internas. Aunque en la práctica es poco probable que topemos con ellas, es útil tenerlas presentes y, si es posible, ser capaces de sobrepasarlas. En este caso, ya sabemos como sortear la limitación en la precisión de los cálculos más allá de los 16 dígitos con el paquete gmp.

Referencias:

Double-precision floating-point format
R Accuracy
?double en la consola de R

Entradas relacionadas:
Sucesión de Fibonacci en Excel y VBA

2014-04-06

Sucesión de Fibonacci en Excel y VBA

Title La sucesión de Fibonacci es una sucesión infinita en la que los dos primeros elementos son 0 y 1, y los siguientes términos son la suma de los dos anteriores:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377...

En Excel podemos generar la sucesión mediante fórmulas. Sumamos los dos primeros elementos y arrastramos el controlador de relleno.

Sin embargo, como el elemento 74, fib(74) = 1304969544928657, excede los 15 dígitos, Excel devuelve un número incorrecto: 1304969544928660.

Microsoft Excel admite un máximo de 15 dígitos significativos en todo momento. Este límite se aplica a un valor que se calcula mediante una fórmula. Debido a esta limitación, en cualquier momento una fórmula calcula un valor que supere los 15 dígitos de longitud, dígitos más allá el decimoquinto dígito significativo se cambian a ceros.

Función

Para resolver este comportamiento recurrimos a VBA. Traté con el código publicado en rosettacode.org. Pero fib(46) provoca un desbordamiento. Además, provocaría siempre el desbordamiento un término antes del máximo posible porque calcula el próximo nº Fibonacci un término antes de lo necesario, .

'Desbordamiento en fib(46)
Public Function Fib(n As Integer) As Long
    Dim fib0, fib1, sum As Long
    Dim i As Integer
    fib0 = 0
    fib1 = 1
    For i = 1 To n
        sum = fib0 + fib1 'Calcula nº siguiente antes de tiempo
        fib0 = fib1
        fib1 = sum
    Next
    Fib = fib0
End Function
Finalmente, ver notas abajo, modificando este código consigo calcular hasta fib(139) sin desbordamiento.

'Desbordamiento en fib(139)
Public Function Fibonacci(ByVal n As Long)
    Dim i As Long
    Dim a As Variant, b As Variant, tmp As Variant
    a = 0
    b = 1
    For i = 1 To n
        tmp = b
        b = a
        a = CDec(a + tmp) 'Conversión de Variant a Decimal
    Next
    Fibonacci = CStr(a) 'Mostrar todos los dígitos como texto
End Function

Subrutina

A continuación transformamos la función definida por el usuario (FDU) anterior en subrutina. En el cuadro de diálogo escribimos el número Fibonacci que queremos calcular.

'Desbordamiento en fib(139)
Sub Secuencia_Fibonacci()
    n = VBA.InputBox("Número de la serie Fibonacci a calcular. Máx. 139.")
    Dim i As Long
    Dim a As Variant, b As Variant, tmp As Variant
    a = 0
    b = 1
    For i = 1 To n
        tmp = b
        b = a
        a = CDec(a + tmp) 
    Next
    MsgBox "Fib(" & n & ")= " & a, vbInformation 
End Sub
End Sub

Notas

Necesitamos forzar la conversión del resultado a = CDec(a + tmp) con CDec de Variant a Decimal (28 dígitos). De esta manera, evitamos que VBA pierda la precisión necesaria y redondee a 15 dígitos a partir de fib(74) = 1,30496954492866E+15 en lugar de 1304969544928657 (16 dígitos). No podemos declarar las variables como Decimal directamente. Debemos definirlas como Variant y luego asignarles el tipo Decimal. Finalmente, convertimos el resultado de la función en texto con CStr para que Excel conserve todos los dígitos en las celdas y no vuelva redondear a 15 dígitos.

En cualquier caso, el término máximo de la sucesión Fibonacci que Excel puede calcular es el 139. Pues fib(140) = 81055900096023504197206408605 excede el valor máximo que Excel puede usar: 79228162514264337593543950335.

Referencias:

Límite de 15 dígitos.
Definir variable como Decimal.
Calculadora de sucesión de Fibonacci

Entradas relacionadas:
Sucesión de Fibonacci en R

2014-04-04

Diagrama de Pareto en Excel

Title Un diagrama de Pareto es un gráfico empleado para mostrar los motivos que contribuyen a un problema e identificar si siguen el principio de Pareto: si el 20% de los motivos representan el 80% del problema. El principal valor de este análisis es priorizar los esfuerzos y discriminar los motivos pocos pero vitales en lugar de los muchos pero triviales.

Las aplicaciones son múltiples: logística (análisis ABC), empresa (contribución de productos, clientes y venta), control de calidad, economía, etc.

Diagrama de Pareto

El resultado final muestra las causas más comunes de los fallos en la fabricación de circuitos integrados: corrosión, contaminación de la superficie, defectos en el sílice, en el óxido y la metalización. Se puede observar como tres tipos de errores originan el 81% de los mismos.


Preparación de los datos

En nuestro ejemplo partimos de 31 observaciones de errores en la fabricación de circuitos integrados.

Se agrupan las frecuencias relativas de las causas en orden descendente, el porcentaje de error, el porcentaje acumulado y una columna con el límite: 80%.

Creación del gráfico

1. Insertamos un gráfico de barras, seleccionando la causa, la frecuencia del error, el % errores acumulado y el límite.

2. Trazamos las series 2 y 3 en el eje secundario. Seleccionamos la serie, botón secundario del ratón o Ctrl+1 y seleccionamos Dar formato a la serie de datos. En Opciones de serie, clic sobre Trazar serie en Eje secundario.


3. Ahora necesitamos cambiar el tipo de gráfico para estas dos series. Seleccionamos % Error Acumulado y cambiamos a gráfico de línea con marcadores y el límite a gráfico de líneas.

4. Formateamos el gráfico. Aumentamos el ancho de la columna, coloreamos de manera diferente las causas que generan el 81% de los fallos, las líneas de las series del eje secundario. Añadimos etiquetas a las series, y eliminamos las del eje y sus líneas.

2014-04-01

Exportar tabla como archivo de texto sin truncar los decimales

Title
Si en Access tratamos de exportar una tabla a un archivo de texto, los campos numéricos exportados conservarán como máximo 2 decimales. Para evitar que se trunque el campo, creamos una consulta en la que especificaremos el número de decimales del campo.

Por ejemplo, para conservar 6 decimales del CampoNumerico:

1. Creamos una consulta con el campo:

Campo: Format([Tabla1]![CampoNumerico];"0,000000")
2. Guardamos la consulta.
3. Exportamos la consulta, la seleccionamos y:
  • Botón secundario del ratón > Exportar > Archivo de texto; o bien
  • En la ficha Datos externos, en el grupo Exportar, Archivo de texto:

Entradas relacionadas

Nube de datos