2018-01-25

Media móvil en R

Problema

¿Cómo podemos calcular la media móvil en R? Es decir, calcular la media aritmética de n datos anteriores. En el siguiente ejemplo, la media de los 4 datos anteriores. En el primer cálculo la media de los 4 primeros términos: del 1 al 4. En el segundo del 2 al 5, y así sucesivamente.

   num media_movil
1       1          NA
2       2          NA
3       3          NA
4       4         2.5
5       5         3.5
6       6         4.5

Solución

Muestro dos alternativas, con los paquetes zoo y RcppRoll, con sintáxis casi idéntica. En ambas utilizo dplyr para crear la nueva columna con la función mutate.

  • Alternativa 1: zoo
  • Con el argumento k (4 en este ejemplo) suministramos un número entero que indica el intervalo de la media móvil.

    library(zoo) 
    library(dplyr)
    df <- data.frame(num = 1:20)
      df %>% mutate(media_movil = rollmean(num, k = 4 , fill = NA, align = "right"))
    
  • Alternativa 2: RcppRoll
  • Con el argumento n (4 en este ejemplo) suministramos un número entero que indica el intervalo de la media móvil.

    library(RcppRoll)
    df %>% mutate(media_movil = roll_mean(num, n = 4, fill = NA, align = "right"))
    

Resultados

   num media_movil
1    1          NA
2    2          NA
3    3          NA
4    4         2.5
5    5         3.5
6    6         4.5
7    7         5.5
8    8         6.5
9    9         7.5
10  10         8.5
11  11         9.5
12  12        10.5
13  13        11.5
14  14        12.5
15  15        13.5
16  16        14.5
17  17        15.5
18  18        16.5
19  19        17.5
20  20        18.5

Referencias

2018-01-20

Rellenar área con teselas en ggplot2

Problema

Con ggplot2 queremos rellenar una región cuadrada con teselas cuadradas. El intento original del usuario que plantéo la pregunta fue:

  • Datos
set.seed(1)
library(ggplot2)
# Datos
l = 1000
a = seq(0, 1, 1 / (l - 1))
x = rep(a, each = length(a))
y = rep(a, length(a))
k = length(x)
c = sample(1:10, k, replace = TRUE)
data <- data.frame(x, y, c)
# Gráfico
ggplot(data, aes(x = x, y = y)) + geom_point(shape = 15, color = c)

Solución

  • Alternativa 1
  • Reducimos el tamaño del data frame, l = 10 en el código anterior para poder apreciar los cuadrados. Y usamos el argumento "white" como colour p para resaltar las teselas con un contorno blanco.

    ggplot(data, aes(x = x, y = y, fill = c)) + geom_tile(colour = "white")
    
  • Alternativa 2
  • Creamos manualmente una paleta, y empleamos coord_equal para generar cuadrados, forzando a que una unidad en el eje x tenga la misma longitud que una unidad en el eje y.

    colors<-c("peachpuff", "yellow", "orange", "orangered", "red", 
              "darkred","firebrick", "royalblue", "darkslategrey", "black")
    ggplot(data, aes(x = x, y = y)) +
      geom_tile(aes(fill = factor(c)), colour = "white") +
      scale_fill_manual(values = colors, name = "Colours") +
      coord_equal()
    

Notas

Para apreciar lo que sucede cuando creamos el gráfico original con geom_point, reducimos el tamaño del data frame, a 10 x 10. Lo representamos seguido de las dos alternativas propuestas.

  • Nuevo data frame
  • l = 100
    a = seq(0, 1, 1 / (l - 1))
    x = rep(a, each = length(a))
    y = rep(a, length(a))
    k = length(x)
    c = sample(1:10, k, replace = TRUE)
    data <- data.frame(x, y, c)
    
  • Gráfico original
  • ggplot(data, aes(x = x, y = y)) + geom_point(shape = 15, color = c)
    
  • Alternativa 1
  • ggplot(data, aes(x = x, y = y, fill = c)) + geom_tile(colour = "white")
    
  • Alternativa 2
  • colors<-c("peachpuff", "yellow", "orange", "orangered", "red", 
              "darkred","firebrick", "royalblue", "darkslategrey", "black")
    ggplot(data, aes(x = x, y = y)) +
      geom_tile(aes(fill = factor(c)), colour = "white") +
      scale_fill_manual(values = colors, name = "Colours") +
      coord_equal()
    

Referencias

2018-01-16

Abrir simultáneamente múltiples hipervículos en Excel

Problema

Queremos abrir simultáneamente múltiples hipervículos en Excel.

Solución

  1. Abrimos el Editor de Microsoft Visual Basic: Alt+F11.
  2. Creamos la siguiente función en un módulo.
    • Sub Abrir_Hipervinculos()
          On Error Resume Next
          Dim hl As Hyperlink
          For Each hl In Selection.Hyperlinks
              hl.Follow
          Next hl
      End Sub
      
  3. Seleccionamos el rango de celdas que contiene los enlaces y presionamos Alt+F8.
  4. Tecleamos Alt+F8 y presionamos Ejecutar.
  5. Los enlaces se abrirán en el navegador predeterminado. Si alguna celda está vacía, contiene texto no reconocido como hipervínculo, o un hipervínculo no válido, los enlaces no se abrirán y no generará error pues hemos especificado On Error Resume Next.

Entradas relacionadas

Referencias

2018-01-14

Gráfico y tabla subyacente en una misma página en R

Problema

Queremos mostrar un gráfico junto con su tabla subyacente en una misma página en R.

  • Datos y gráfico original
df <- data.frame(
  group = c("A", "A", "A", "B", "B", "B"),
  x = c(1, 2, 3, 1, 2, 3),
  y = c(2, 5, 7, 7, 5, 3)
)
library(ggplot2)
p <- ggplot(data = df, aes(
  x = x,
  y = y,
  group = group,
  color = group
)) +
  geom_line() +
  geom_point()

Solución

Empleamos el paquete gridExtra, con tableGrob creamos la tabla y con grid.arrange ordenamos los dos elementos, la tabla y el gráfico, en una misma página.

library(gridExtra)
tbl <- tableGrob(t(df), rows = NULL , theme = ttheme_minimal())
grid.arrange(p,
             tbl,
             nrow = 2,
             as.table = TRUE,
             heights = c(3, 1))

Referencias

2018-01-12

Filtrar entre dos fechas con dplyr

Problema

Queremos filtra entre dos fechas utilizando el paquete dplyr.

    Patch       Date Prod_DL
1    BVG1   9/4/2015    3.43
2   BVG11  9/11/2015    3.49
3   BVG12  9/18/2015    3.45
4   BVG13  12/6/2015    3.57
5   BVG14 12/13/2015    3.43
6   BVG15 12/20/2015    3.47
  • Datos
df <- read.table(
  text = "Patch,Date,Prod_DL
  BVG1,9/4/2015,3.43
  BVG11,9/11/2015,3.49
  BVG12,9/18/2015,3.45
  BVG13,12/6/2015,3.57
  BVG14,12/13/2015,3.43
  BVG15,12/20/2015,3.47",
  sep = ",",
  stringsAsFactors = FALSE,
  header = TRUE,
  row.names = NULL
)

Solución

  • Alternativa 1
  • Formateamos la fecha correctamente y filtramos entre las dos fechas deseadas.

    library("dplyr")
    df$Date <-as.Date(df$Date,"%m/%d/%Y")
    df %>%
      select(Patch, Date, Prod_DL) %>%
      filter(Date > "2015-09-04" & Date < "2015-09-18")
    
        Patch       Date Prod_DL
    1   BVG11 2015-09-11    3.49
    
  • Alternativa 2
  • Formateamos la fecha correctamente y empleamos la función between: 'This is a shortcut for x >= left & x <= right, implemented efficiently in C++ for local values, and translated to the appropriate SQL for remote tables.'. Por tanto es necesario ajustar las fechas pues incluye ambas fechas en los dos lados. Necesitamos usar as.Date, explicación aquí.

    df$Date <- as.Date(df$Date, "%m/%d/%Y")
    df %>% 
      select(Patch, Date, Prod_DL) %>%
      filter(between(Date, as.Date("2015-09-05"), as.Date("2015-09-17")))
    
        Patch       Date Prod_DL
    1   BVG11 2015-09-11    3.49
    

    Referencias

    Nube de datos