2014-03-30

Directorio y entorno de trabajo en RStudio

Title

Directorio de trabajo

El directorio de trabajo (working directory, wd) en R es la carpeta que por defecto utiliza R para leer o escribir ficheros.

Para comprobar el directorio de trabajo actual:

getwd()
[1] "C:/Usuarios/Documentos/R"  # Ejemplo
Para cambiar el directorio de trabajo actual:

setwd("C:/Usuarios/Documentos/R") # Especificar la ruta completa.
Mediante la barra de menú en RStudio:

Entorno de trabajo

Por defecto al cerrar la sesión en RStudio nos preguntará si queremos guardar una copia del entorno de trabajo (Workspace) en el directorio de trabajo actual. Bien al cerrar usando la función q, o con un mensaje emergente si cerramos el programa:

q()
Save workspace image to ~/R/.RData? [y/n/c]: 

Aunque es práctico conservar los objetos de sesiones anteriores mientras realizamos nuestros análisis, es recomendable crear R Scripts que sean capaces de reconstruir todo el proceso por sí mismos. Es decir, que importen los datos y creen los objetos necesarios, en lugar de guardarlos en .RData.

En cualquier caso podemos abrir y guardar ficheros .RData mediante el menú File, con los iconos correspondientes en la pestaña Environment o con funciones :

save.image("~/R/.RData") # Guarda .RData
load("~/R/.RData")  # Carga .RData
En .Rhistory se guardan las instrucciones ejecutadas en R. RStudio por defecto guarda automáticamente el fichero .Rhistory en el directorio de trabajo actual, incluso cuando no guardamos .RData. Podemos abrir y guardar el .Rhistory mediante el menú File, con los iconos correspondientes en la pestaña History o mediante funciones:

savehistory("~/R/.Rhistory") # Guarda .Rhistory
loadhistory("~/R/.Rhistory") # Carga .Rhistory

Opciones Generales de R

Podemos modificar la configuración de RStudio, Tools> Options...> General R Options

Default working directory — Directorio de trabajo por defecto de RStudio. RStudio busca los ficheros .RData y .Rprofile en este directorio.

Restore .RData into workspace at startup — Al abrir RStudio, carga en el entorno de trabajo (Environment) el fichero .RData, (en el caso de encontrar alguno en el directorio de trabajo actual). Si el fichero .RData es muy grande conviene desmarcar la opción para acortar el tiempo de inicio.

Save workspace to .RData on exit — Las opciones son: preguntar al cerrar si deseamos guardarlo, guardar siempre o nunca el fichero .RData. Si no se ha realizado ningún cambio, RStudio no preguntará nada aunque especifiquemos preguntar al cerrar.

Always save history (even when not saving .RData) — Guarda el fichero .Rhistory con las instrucciones ejecutadas en la sesión incluso si no elegimos guardar el fichero .RData al cerrar RStudio.

2014-03-26

Calcular la duración del día y el horario de verano en Excel

El próximo fin de semana comienza el horario de verano (CEST – Central European Summer Time). En torno a los cambios de horario de verano en marzo y octubre, tendemos a fijarnos más en como los días se alargan o se acortan. ¿La duración del día varía más en algunos periodos del año o es un efecto acumulativo en el que repentinamente reparamos? He creado varios gráficos para responder a esta pregunta.

Gráficos

Horas de luz diurna

Resulta evidente que en primavera y otoño la duración del día varía más aceleradamente que en verano e invierno. Por ejemplo, de finales de enero a principios de mayo, tres meses, se incrementa en 4 horas (de 10 a 14). Mientras que en un periodo de prácticamente igual duración, de mayo a agosto, el número de horas se estabiliza en 14 horas llegando a un máximo de 15.

Amanecer, ocaso y duración del día

En el gráfico anterior vemos la hora del amanecer y del ocaso a lo largo del año. Los dos escalones reflejan el horario de verano. La línea verde es continua, idéntica a la del anterior gráfico, porque refleja las horas entre el amanecer y el ocaso. El horario de verano tan solo retrasa las horas de luz una hora, no altera obviamente el número de horas de luz.

Gráfico animado



Datos

En primer lugar, necesitamos obtener las horas del amanecer y del atardecer de todos los días del año. Una opción sería descargarlos para una población concreta. Otra más flexible sería crear una fórmula que nos calcule los mismos en función de la latitud y longitud que le indiquemos.

Por suerte, Greg Pelletier del Departamento de Ecología del Estado de Washington, ha adaptado a VBA los cálculos en Javascript de NOAA (National Oceanic and Atmospheric Administration). Nosotros solamente usaremos dos de sus funciones, sunrise (amanecer) y sunset (atardecer). Los argumentos de ambas son: latitud, longitud, año, mes, día, huso horario (zona horaria) y horario de verano (0 = no, 1 = sí).

Necesitamos determinar el inicio y el final del horario de verano, es decir, el último domingo de marzo y de octubre. Podríamos calcularlo con fórmulas disponibles en Excel pero recurrimos a una función definida por Chip Pearson. Hemos tenido que modificarla pues la transición en EE.UU. al Daylight Savings Time (DST) es distinta. 

Armados con dichas fórmulas, necesitamos saber la latitud y longitud (en grados decimales) de la población en cuestión. Pau Urquizu nos ha facilitado inmensamente la labor poniendo a nuestra disposición el listado completo de los municipios de España. También es posible acudir a Google maps y obtener las coordenadas de un punto del planeta:

Botón derecho en una ubicación del mapa > Selecciona ¿Qué hay aquí?

Tabla

Con todos los datos construimos una tabla con los 365 días del año.

NOAA Solar Calculator


Aquí podemos calcular el amanecer, ocaso y acimut para cualquier coordenada. Los cálculos de NOAA se basan a su vez en ecuaciones de los algoritmos astronómicos de Jean Meeus. Tienen una precisión de +/- 1 minuto para entre +/-72° de latitud y de 10 minutos fuera de esas latitudes. A su vez, la conversión de Greg Pelletier de Javascript a Excel VBA varía +/- 1 minuto respecto al código original de Javascript.

2014-03-20

Tablas dinámicas con origen de datos dinámico

Un elemento fundamental de las tablas dinámica es su origen de datos. Si el origen se amplia o disminuye tendremos que cerciorarnos de que al actualizar la tabla dinámica ésta refleje correctamente los datos. Aunque podemos cambiar el origen manualmente, en esta entrada trataremos tres opciones para crear un origen de datos dinámicos. Partimos del siguiente ejemplo:

Si añadimos un nuevo registro y actualizamos la tabla, ésta mostrará los mismo resultados. Sin embargo, tenemos distintas opciones para crear un rango autoajustable como origen de datos.

Tabla como origen de datos

1. Nos situamos sobre una celda del rango.

2. En el grupo Tablas de la ficha Insertar, clic en Tabla. O presionar Ctrl+T.

Por defecto Excel selecciona el área actual alrededor de la celda activa (el área de datos delimitada por filas en blanco y columnas en blanco). Activamos la casilla de verificación La tabla tiene encabezados, pues todas las tablas dinámicas deben tener encabezados de columna.

A continuación cambiamos el origen de datos de la tabla dinámica. En Tabla o rango, escribimos el nombre de la tabla. Así la tabla dinámica incluirá, al actualizarla, los registros añadidos a la tabla de origen de datos automáticamente.

Proceso:

Rango dinámico como origen de datos: DESREF

1. Definimos un nuevo nombre. En el grupo Nombres definidos de la ficha Fórmulas, clic en Asignar nombre.

=DESREF(Hoja1!$A$1;;;CONTARA(Hoja1!$A:$A);3)
'Si desconocemos el nº de columnas:
=DESREF(Hoja1!$A$1;;;CONTARA(Hoja1!$A:$A);CONTARA(Hoja1!$1:$1))
Sintaxis: DESREF(ref; filas; columnas; [alto]; [ancho])

- Ref: Hoja1!$A$1. Celda que anclamos.
- Filas: Ø
- Columnas: Ø
- Alto: CONTARA(Hoja1!$A:$A). Nº de filas.
- Ancho: 3. Nº de columnas.

Rango dinámico como origen de datos: INDICE

1. Definimos un nuevo nombre. En el grupo Nombres definidos de la ficha Fórmulas, clic en Asignar nombre o en Administrador de nombres y en Nuevo.

=Hoja1!$A$1:INDICE(Hoja1!$1:$65535;CONTARA(Hoja1!$A:$A);3)
'Si desconocemos el nº de columnas:
=Hoja1!$A$1:INDICE(Hoja1!$1:$65535;CONTARA(Hoja1!$A:$A);CONTARA(Hoja1!$1:$1))
Sintaxis: Ref:INDICE

- Ref:Hoja1!$A$1: Celda que anclamos.
- INDICE(matriz;núm_fila;núm_columna). Devuelve la referencia de la última celda del rango.
- Matriz: Hoja1!$1:$65535. Toda la hoja: 65535 en Excel 2003, 1048576 en 2007.
- Núm_fila: CONTARA(Hoja1!$A:$A). Nº de filas.
- Núm_columna: 3. Nº de columnas

Nota: funciones volátiles

La diferencia entre usar DESREF o Ref:INDICE estriba en que DESREF es una función volátil mientras que INDICE no. Una función volátil se debe actualizar siempre que se efectúe un cálculo en cualquier celda de la hoja de cálculo. Por tanto, si usamos funciones volátiles en demasía, se ralentizará el proceso de recálculo de Excel. Otras funciones volátiles son: AHORA, HOY, ALEATORIO, ALEATORIO.ENTRE, INDIRECTO, INFO (dependiendo de los argumentos y CELDA (dependiendo de los argumentos).

2014-03-16

Gráfico de anillos en Excel como en Google Analytics

Title En Google Analytics, en el apartado de informes (reporting) podemos ver el porcentaje de visitas de nuestra web por día o entrada. Utilizan el siguiente gráfico de anillo:

Sin entrar ahora a valorar la utilidad y la facilidad para interpretarlo adecuadamente (no deja de ser un gráfico de sectores o circular), vamos a crearlo en Excel.

Crear un gráfico de anillo en Excel


1. Escribimos en una celda por ejemplo 25% y en otra 75%.
2. Insertar> Gráficos> Otros Gráficos> Anillo
3. En cualquiera de las series, Formato de serie de datos:
     - Ángulo del primer sector: 90. El ángulo en el que comienza Google Analytics.
     - Tamaño del agujero del anillo: 70 aproximadamente.
4. Formato adicional. El relleno rojo lo cambiamos a azul celeste.Y en ambas series el color del borde en blanco y al estilo del borde un ancho de 2 puntos.

5. Reducimos el tamaño y, si lo deseamos, lo vinculamos a una barra de desplazamiento (control ActiveX). La barra de desplazamiento no permite que en propiedades especifiquemos porcentajes. Por tanto, escribimos un número entero y lo dividimos en la celda que sirve de origen al gráfico. Como queremos un pequeño espacio en blanco incluso con el 100%, escribimos 999 en lugar de 1.000 en Max.

Resultado final

2014-03-12

Actualizar datos de una consulta o formulario inmediatamente

En Access es frecuente que deseemos actualizar consultas o formularios abiertos. Por ejemplo, porque los datos de la tabla, otras consultas o formularios en los que están basados hayan sido modificados.

Podemos actualizar inmediatamente una consulta o un formulario abierto de dos formas:

    1. En la ficha Inicio, en el grupo Registros, clic en Actualizar todo.


    2. Presionar Mayús+F9

En el ejemplo anterior tenemos un cuadro combinado cuyo origen es el Campo1 de la Tabla1. Si añadimos un nuevo registro (Región 4) y queremos que el desplegable del cuadro combinado incorpore este nuevo registro presionamos Mayús+F9.

Son dos alternativas más rápidas que cerrar y abrir la consulta o el formulario, o que pasar a Vista de diseño y de nuevo a Vista Hoja de datos o Vista Formulario .

2014-03-09

Reemplazar carácter en un fichero de texto con VBA en Excel

Es frecuente encontrarnos con el problema de tener un fichero de texto delimitado por comas cuando necesitamos que el delimitador sea el punto y coma. En una entrada anterior vimos como reemplazar un carácter en un fichero de texto con VBA en Access.

En Excel tenemos dos alternativas:

1. Usar el mismo Excel, Bloc de notas, u otro editor de texto como Notepad++, para reemplazar un carácter por otro. Cuando el número de ocurrencias es muy grande, millones en el caso de fichero de tamaño considerable, el proceso puede ser algo lento.

2. Utilizar código de VBA acelerando el proceso notablemente, evitando tener que abrir otros programas, reduciendo la probabilidad de errores y pudiendo llamarlo desde una macro u otro módulo.

Copiamos el siguiente código en un módulo de Ms Excel:

Public Sub ReemplazarCaracteresExcel()

Dim folderPath As String
folderPath = ThisWorkbook.Path & "\" 'Ruta del Excel

Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(folderPath & "Inicial.csv") Then
    Set objStream = fso.OpenTextFile(folderPath & "Inicial.csv", 1, False, 0)
End If
    Set objCopy = fso.CreateTextFile(folderPath & "Final.csv")

For x = 1 To 5  'Se salta el nº de líneas indicadas: 5
    objStream.readline
Next x
 
Do While Not objStream.AtEndOfStream
    strOldLine = objStream.readline
    i = 1
    NewArray = Split(strOldLine, ",") 'Carácter reemplazado: ,
       strNewLine = NewArray(0)
       
    Do Until i = UBound(NewArray) + 1
         strNewLine = strNewLine & ";" & NewArray(i) 'Carácter nuevo: ;
         i = i + 1
    Loop
    objCopy.WriteLine strNewLine
Loop

End Sub
Notas: El fichero Inicial.csv debe de estar en la misma ruta del Excel. El fichero Final.csv se creará automáticamente. Borrar estas 3 líneas en el caso de que en el fichero de texto no haya que saltarse líneas en blanco y que provocarían un error:

For x = 1 To 5  'Se salta el nº de líneas indicadas 
    objStream.readline
Next x
También se puede usar este código para ficheros *txt. Ejemplo: Inicial.txt y Final.txt

Entradas relacionadas

2014-03-05

Distribución de frecuencias en R

Title

En dos entradas anteriores vimos como crear histogramas y tablas de frecuencias en Excel y Access. En esta entrada haremos lo mismo en R usando los mismos datos.

Manipulación de los datos

datos <- read.csv("datos.txt", sep = ";")  # Fichero en el directorio
hist(datos$año)  # Intentamos crear histograma
## Error in hist.default(datos$año) : 'x' must be numeric
names(datos)  # Genera error por la ñ en Año
## [1] "Id" "Nombre" "Año"
colnames(datos) <- c("id", "nombre", "fecha")  # Renombramos las columnas
names(datos)
## [1] "id" "nombre" "fecha"

Tabla de frecuencias

intervalos <- seq(from = 1913, to = 2013, by = 10) 
frecuencias <- cut(datos$fecha, # Usamos la nueva columna: fechas
                 breaks = intervalos,   
                 dig.lab = 4,   # Nº de dígitos de los intervalos
                 right = FALSE) # Intervalos [a, b). Por defecto: (a, b]
tabla.frec  <- table(frecuencias)   # Crea la tabla de frecuencias
as.data.frame(tabla.frec) # O cbind(tabla.frec) mejoramos el formato
##    frecuencias Freq
## 1  [1913,1923)   16
## 2  [1923,1933)    8
## 3  [1933,1943)   18
## 4  [1943,1953)    3
## 5  [1953,1963)    7
## 6  [1963,1973)   11
## 7  [1973,1983)    6
## 8  [1983,1993)    9
## 9  [1993,2003)   14
## 10 [2003,2013)    8

Histograma

# Creamos histograma por defecto
hist(datos$fecha) 

plot of chunk unnamed-chunk-1

Queremos el formato aproximado al gráfico que creamos en esta entrada.

#Formateamos el histograma
intervalos <- seq(from = 1913, to = 2013, by = 10) 
h <- hist(datos$fecha, 
          breaks = intervalos,  # Añadimos los intervalos
          freq = TRUE, # Representa frecuencias
          right = FALSE, # Intervalos [a, b). Por defecto: (a, b]
          col = rgb(79, 129, 189, max = 255), # Color de las columnas
          border = "white",     # Color del borde
          labels = TRUE,        # Etiquetas de las columnas
          main = "Frecuencias", # Título del gráfico
          xaxt = "n",           # Eliminamos eje x
          yaxt = "n",           # Eliminamos eje y
          xlab = "Años",        # Título del eje x
          ylab = NULL,          # Título del eje y
          ylim = c(0, 20))      # Escala de y (fijamos max en 20)
axis(side = 1, at = intervalos)  # Etiquetas del eje x 

Entradas relacionadas

2014-03-01

Cambiar origen de datos de múltiples tablas dinámicas con VBA

Una tarea bastante frecuente trabajando con tablas dinámicas es cambiar el origen de datos. La acción es bastante rápida para una sola tabla dinámica. En el caso de múltiples tablas dinámicas, el procedimiento se vuelve muy pesado. No es posible cambiar manualmente el origen de datos para varias tablas dinámicas simultáneamente. Sin embargo, podemos sortear esta limitación programáticamente:

1. Definimos un nombre (NuevoOrigen) para el rango de celdas que será el nuevo origen de datos.
2. Copiamos el siguiente código en un módulo. Nos aseguramos de que SourceData es igual al nombre definido.
Option Explicit
Sub Cambiar_Origen_Tbls_Dinamicas()
Dim n As Integer
Dim i As Integer
Dim pt As PivotTable
n = ActiveWorkbook.Worksheets.Count
    For i = 1 To n
        For Each pt In ActiveWorkbook.Worksheets(i).PivotTables
            pt.ChangePivotCache ActiveWorkbook.PivotCaches.Create _
            (SourceType:=xlDatabase, SourceData:="NuevoOrigen")
        Next pt
    Next i
End Sub
En lugar de un nombre, podemos indicar un rango de celdas, p. ej.: SourceData:="Hoja1!$A$1:$M$1000"

 3. Ejecutamos el código anterior. El origen de datos habrá cambiado para todas las tablas dinámicas del libro.
Nube de datos