2018-05-19

Muestra aleatoria estratificada proporcional en R

Title

Problema

Necesitamos crear una muestra estratificada en R. Nuestro data frame contiene dos estratos con un 60% y 40% respectivamente del total de la población. Deseamos estraer una muestra de 10 en la que cada estrato esté representado proporcionalmente: 60% (6 elementos) del estrato 1 y un 40% (4 elementos) del estrato 2.

id <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
estrato<- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2)
df <- data.frame(id, estrato)
df %>%
  group_by(estrato) %>%
  summarise (cuenta = n()) %>%
  mutate(porcentaje = cuenta / sum (cuenta ))
# A tibble: 2 x 3
  estrato cuenta porcentaje
            
1      1.     12      0.600
2      2.      8      0.400

Solución

Muestro tres soluciones diferentes. Las dos primeras son muy similares entre sí — con dplyr encadenamos las expresiones con el operador %>% — y arrojan el mismo resultado. Finalmente empleamos el paquete caret.

  1. Paquete splitstackshape
  2. library(splitstackshape)
    set.seed(1)
    stratified(df, "status", 10 / nrow(df))
    
        id estrato
     1:  4       1
     2:  5       1
     3:  6       1
     4:  9       1
     5:  2       1
     6:  7       1
     7: 20       2
     8: 17       2
     9: 16       2
    10: 13       2
    
  3. Paquete dplyr
  4. library(dplyr)
    set.seed(1)
    df %>%
      group_by(estrato) %>%
      sample_frac(10 / nrow(df))
    
    # A tibble: 10 x 2
    # Groups:   estrato [2]
          id estrato
          
     1    4.      1.
     2    5.      1.
     3    6.      1.
     4    9.      1.
     5    2.      1.
     6    7.      1.
     7   20.      2.
     8   17.      2.
     9   16.      2.
    10   13.      2.
    
  5. Paquete caret
  6. library(caret)
    set.seed(1)
    train.index <- createDataPartition(df$estrato,
                                       p = .5,
                                       list = FALSE)
    df[train.index, ]
    
       id estrato
    1   1       1
    4   4       1
    6   6       1
    8   8       1
    9   9       1
    11 11       1
    14 14       2
    15 15       2
    16 16       2
    19 19       2
    

Referencias

2018-04-25

Calcular la diferencia entre filas alternas en R

Title

Problema

Queremos calcular la diferencia entre filas alternas en R.

df <- 
structure(list(MemId = c(1, 2, 3, 4, 5,6), ET = structure(c(1506829256,
 1506829319, 1506843096,1506843226, 1506850144, 1506853708), class = 
c("POSIXct", "POSIXt"))), .Names = c("MemId", "ET"), row.names = c("1",
 "2", "14", "15", "37", "38"), class = "data.frame")
  MemId                  ET
1      1 2017-10-01 05:40:56
2      2 2017-10-01 05:41:59
14     3 2017-10-01 09:31:36
15     4 2017-10-01 09:33:46
37     5 2017-10-01 11:29:04
38     6 2017-10-01 12:28:28

Solución

Creamos una columna auxiliar con ceros y unos. Y con la función difftime, calculamos para los unos la diferencia entre un momento en el tiempo (ET) y el anterior (lag(ET)).

library(dplyr)
df %>%
  mutate(id = rep_len(0:1, nrow(df))) %>%
  mutate(dif = ifelse(id == 1, difftime(ET, lag(ET), units = "secs"), NA))
  MemId                  ET id  dif
1     1 2017-10-01 05:40:56  0   NA
2     2 2017-10-01 05:41:59  1   63
3     3 2017-10-01 09:31:36  0   NA
4     4 2017-10-01 09:33:46  1  130
5     5 2017-10-01 11:29:04  0   NA
6     6 2017-10-01 12:28:28  1 3564

Entradas relacionadas

Referencias

2018-04-15

Recrear un objeto con la función dput en R

Title

Problema

Deseamos recrear un objeto en R. Es decir, queremos el código que nos permite crear dicho objeto, en lugar de importarlo. En nuestro ejemplo un data frame cargado en nuestro directorio de trabajo, del que mostramos la parte inicial y final.

library(psych)
headTail(df)
    time group value
1      1     A     3
2      2     A     3
3      3     A     8
4      4     A     5
...  ...     ...
47     7     E     7
48     8     E     8
49     9     E    10
50    10     E     3

Solución

La función dput nos permite recrear dicho objeto.

dput(df)
 structure(list(time = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 
6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L), group = c("A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", "C", 
"C", "C", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "E", 
"E", "E", "E", "E", "E", "E", "E", "E", "E"), value = c(3L, 3L, 
8L, 5L, 4L, 4L, 9L, 6L, 7L, 4L, 5L, 2L, 6L, 8L, 6L, 7L, 6L, 2L, 
4L, 10L, 3L, 7L, 3L, 2L, 8L, 6L, 5L, 3L, 1L, 7L, 6L, 9L, 7L, 
4L, 6L, 4L, 7L, 6L, 7L, 7L, 3L, 4L, 10L, 2L, 7L, 10L, 7L, 8L, 
10L, 3L)), .Names = c("time", "group", "value"), row.names = c(NA, 
-50L), class = "data.frame")
Si quisiéramos crear de nuevo el objeto.

df <- structure(list(time = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 
6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L), group = c("A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", "C", 
"C", "C", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "E", 
"E", "E", "E", "E", "E", "E", "E", "E", "E"), value = c(3L, 3L, 
8L, 5L, 4L, 4L, 9L, 6L, 7L, 4L, 5L, 2L, 6L, 8L, 6L, 7L, 6L, 2L, 
4L, 10L, 3L, 7L, 3L, 2L, 8L, 6L, 5L, 3L, 1L, 7L, 6L, 9L, 7L, 
4L, 6L, 4L, 7L, 6L, 7L, 7L, 3L, 4L, 10L, 2L, 7L, 10L, 7L, 8L, 
10L, 3L)), .Names = c("time", "group", "value"), row.names = c(NA, 
-50L), class = "data.frame")
Si en lugar de recrear el código, quremos guardar el objeto en el directorio para acceder a él posteriormente:

# Guardarmos objeto en el directorio de trabajo
dput(df. "df")
# Volvemos a traerlo al directorio de trabajo
df_nuevo <- dget("df")

Referencias

2018-03-31

Mostrar las primeras y últimas n filas de un data frame en R

Title

Problema

Deseamos mostrar simultáneamente las primeras n y últimas n filas de una matriz o data frame. Es decir, combinar las funciones head y tail.

Solución

La función headTail del paquete psych nos permite visualizar simultáneamente las n primeras filas (head) y las últimas n filas (tail).

  1. Opciones por defecto
  2. Por defecto headTail muestra las 4 primeras y últimas filas del objeto separadas por puntos.

    library(psych)
    headTail(ToothGrowth)
    
         len supp dose
    1    4.2   VC  0.5
    2   11.5   VC  0.5
    3    7.3   VC  0.5
    4    5.8   VC  0.5
    ...  ...   ...
    57  26.4   OJ    2
    58  27.3   OJ    2
    59  29.4   OJ    2
    60    23   OJ    2
    
  3. Más opciones
  4. La función headTail nos permite controlar el número de filas de la parte superior e inferior, la separación entre ambas, las columnas a mostrar y redondear el número dígitos. Veamos algunos ejemplos:

    #Primeras y últimas dos filas sin separación
    headTail(ToothGrowth, top = 2, bottom = 2, ellipsis = FALSE)
    
        len supp dose
    1   4.2   VC  0.5
    2  11.5   VC  0.5
    59 29.4   OJ  2.0
    60 23.0   OJ  2.0
    
    #Primeras y últimas tres filas, las columnas 4 y 5, con separación y sin decimales.
    headTail(iris, top = 3, bottom = 3, digits = 0 , from = 4, to = 5)
    
       Petal.Width   Species
    1             0    setosa
    2             0    setosa
    3             0    setosa
    ...         ...      
    148           2 virginica
    149           2 virginica
    150           2 virginica
    

Entradas relacionadas

2018-03-29

Traducir celdas en hojas de cálculo de Google

Title

Problema

Deseamos traducir rápidamente un rango de celdas en hojas de cálculo de Google.

Solución

  1. Utilizamos la función GOOGLETRANSLATE. Consta de 3 argumentos: texto a traducir, idioma de origen e idioma de destino. Solamente el primero es obligatorio.
  2. En nuestro ejemplo:

    =GOOGLETRANSLATE(A2,"en","es")
    
  3. Arrastramos hacia abajo el cuadro azul en la esquina inferior derecha.

Resultado

Notas

  1. Si queremos detectar automáticamente los idiomas podemos utilizar el argumento "auto" en lugar de los argumentos de idiomas. Esto es especialmene útil si nuestras celdas mezclan varios idiomas.
  2. =GOOGLETRANSLATE(A2,"auto", "es")
    
    o bien
    =GOOGLETRANSLATE(A3,DETECTLANGUAGE(A3), "es")
    
  3. Si estamos traduciéndo al inglés, no necesitamos indicar ni argumento de origen ni de destino, simplemente:

  4. =GOOGLETRANSLATE(A3, "auto")
    
    o tan solo:
    =GOOGLETRANSLATE(A3)
    

Entradas relacionadas

En una próxima entrada trataremos en detalle las transformaciones de formato ancho a largo y viceversa. Un tema ya tratado anteriormente, directa o indirectamente, en las siguientes entradas:

2018-03-26

Gráficos de 'Credit Card Default Data' en ggplot2

Title

Problema

Queremos crear con ggplot2 los siguientes dos gráficos del libro 'An Introduction to Statistical Learning'. Nos servirá para practicar algunos conceptos de ggplot2.

Solución

  1. Gráfico 1: diagrama de dispersión.
  2. Al contrario que en el libro, representamos todos los puntos (10.000). Para evitar un gráfico sobrecargado de puntos —overplotting— añadimos transparencia a los mismos con el argumento alpha. Adicionalmente, cambiamos la forma de los puntos con el argumento shape (el 1 es un círculo y el 2 una cruz). Finalmente, en lugar de dejar un panel de fondo totalmente blanco, dejo líneas de cuadrícula grises (theme_bw) para identificar mejor la ubicación de los puntos.

    library(ISLR)
    library(ggplot2)
    
    ggplot(data = Default, aes(x = balance, y = income)) +
      geom_point(aes(color = default, shape = default),
                 alpha = .5,
                 size = 2) +
      scale_shape_manual(values = c(1, 3)) +
      scale_colour_manual(values = c("royalblue", "orangered")) +
      scale_x_continuous(breaks = seq(0, 2500, 500)) +
      theme_bw()
    
  3. Gráfico 2: diagramas de caja.
  4. Como queremos representar en un único panel dos gráficos, uno para balance y otro para income, necesitamos transformar el data frame de formato ancho a largo con la función melt del paquete reshape2. Posteriormente, usamos face_wrap para generar los dos gráficos e indicamos las escalas de los ejes free para que se adapten automáticamente para cada gráfico.

    library(reshape2)  
    ggplot(data = melt(Default), aes(x = default, y = value)) +
      stat_boxplot(geom = 'errorbar', width = 0.5) +
      geom_boxplot(aes(fill = default)) +
      facet_wrap(~ variable, scales = "free") +
      scale_fill_manual(values = c("Dodgerblue", "orangered"))
    
    • De formato ancho a largo.
    • Dentro de facet_wrap usamos variable pues es el nombre de la columna clave (key) que recoge el nombre de las dos columnas: balance e income.

      melt(Default)[c(1:5, 19996:20000), ]
      
      Using default, student as id variables
            default student variable      value
      1          No      No  balance   729.5265
      2          No     Yes  balance   817.1804
      3          No      No  balance  1073.5492
      4          No      No  balance   529.2506
      5          No      No  balance   785.6559
      19996      No      No   income 52992.3789
      19997      No      No   income 19660.7218
      19998      No      No   income 58636.1570
      19999      No      No   income 36669.1124
      20000      No     Yes   income 16862.9523
      

Entradas relacionadas

En una próxima entrada trataremos en detalle las transformaciones de formato ancho a largo y viceversa. Un tema ya tratado anteriormente, directa o indirectamente, en las siguientes entradas:

2018-03-19

Insertar fila de tolales en una tabla de Excel

Title

Problema

En Excel, queremos resumir rápidamente una tabla añadiendo una fila total en la última fila, pudiendo elegir entre diferentes funciones para cada columna.

Solución

  1. Partimos de un rango de datos
  2. Hacemos clic en cualquier celda y presionamos Ctrl+T
  3. La tabla se habrá formateado automáticamente y mostrará un autofiltro.

  4. En Herramientas de tabla, Diseño seleccionamos la casilla de verificación de la Fila de totales.
  5. Una fila Total se habrá insertado en la última fila de la tabla.
  6. Para cada columna podemos elegir entre diferentes funciones para resumir los datos. Como se puede apreciar en la barra de fórmulas Excel utiliza la función subtotales, por defecto la suma: =SUBTOTALES(109,[Año 3])

Resultados

Entradas relacionadas

Nube de datos