Mostrando entradas con la etiqueta reshape2. Mostrar todas las entradas
Mostrando entradas con la etiqueta reshape2. Mostrar todas las entradas

2018-03-26

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

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:

2016-04-29

Análisis de tendencia en formato tabular en R

Title

Problema

Tenemos unos datos que representamos gráficamente. Deseamos crear una tabla con los datos agrupados por site y parameter, y añadir una columna que nos indique la tendencia.

# Ver apartado inferior Datos para crea el data frame df
library(ggplot2)
ggplot(df, aes(x = YEAR, y = value, col = parameter)) + geom_line(aes(group = parameter)) + facet_wrap(~siteID)

Solución

Una solución básica es transformar el data frame en un formato ancho (wide) y luego añadir una columna en la que establecemos las condiciones para: creciente, decreciente o sin tendencia. En nuestro ejemplo, establecemos que no hay tendencia si la variación es de +-2.


df <- dcast(df, siteID + parameter ~ YEAR, value.var="value")
df$trend <- ifelse(df$`2014`-df$`2011`>2, "creciente", 
                    ifelse(df$`2014`-df$`2011`< -2, "decreciente", "sin tendencia"))
df
   siteID parameter 2011 2012 2013 2014         trend
1   site1         A    1    2    3    4     creciente
2   site1         B   10   20   30   40     creciente
3   site1         C   12   14   16   18     creciente
4   site1         D    5   10   15   20     creciente
5   site2         A    3    6    9   12     creciente
6   site2         B   17   16   13   18 sin tendencia
7   site2         C   16   18   22   15 sin tendencia
8   site2         D   17   16   10   11   decreciente
9   site3         A    7    5    3    1   decreciente
10  site3         B   15   17   20   19     creciente
11  site3         C   15   17   16   18     creciente
12  site3         D   13   16   19   11 sin tendencia
13  site4         A    8    7    6    5   decreciente
14  site4         B   50   40   30   20   decreciente
15  site4         C   16   14   12   10   decreciente
16  site4         D   20   15   10    5   decreciente

Datos

df <- structure(list(siteID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L), .Label = c("site1", "site2", 
"site3", "site4"), class = "factor"), YEAR = structure(c(1L, 
2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 
2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 
2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 
2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), .Label = c("2011", 
"2012", "2013", "2014"), class = "factor"), parameter = structure(c(1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L), .Label = c("A", 
"B", "C", "D"), class = "factor"), value = c(1, 2, 3, 4, 10, 
20, 30, 40, 12, 14, 16, 18, 5, 10, 15, 20, 3, 6, 9, 12, 17, 16, 
13, 18, 16, 18, 22, 15, 17, 16, 10, 11, 7, 5, 3, 1, 15, 17, 20, 
19, 15, 17, 16, 18, 13, 16, 19, 11, 8, 7, 6, 5, 50, 40, 30, 20, 
16, 14, 12, 10, 20, 15, 10, 5)), .Names = c("siteID", "YEAR", 
"parameter", "value"), row.names = c(NA, -64L), class = "data.frame")

Entradas relacionadas

Referencias

2015-11-11

Convertir de formato largo a ancho usando una función de agregación en R

Title

Problema

Deseamos transformar un data frame de formato largo a ancho agrupando por la suma de los valores de una de las variables. Es decir pasar de esta tabla,

 V1 V3     V2
1  5 10    low
2  5  3    low
3  5  6 medium
4 45 10    low
5 45  3    low
6 77  1   high

A esta otra, donde mantenemos la columna V1, la columna V2 contiene los nombres de las nuevas columnas, y la columna V3 será la variable que almacenará los valores y que agregaremos sumando.

  V1 low medium high
1  5  13      6    0
2 45  13      0    0
3 77   0      0    1

  • Datos originales
  • V1 <- c(5,5,5,45,45,77)  
    V2 <- c("low", "low", "medium", "low", "low", "high")  
    V3 <- c(10,3,6,10,3,1)  
    df <- as.data.frame(cbind(V1,V3,V2))
    

    Soluciones

    Primero examinamos el data frame que nos dieron.

    str(df)
    'data.frame': 6 obs. of  3 variables:
     $ V1: Factor w/ 3 levels "45","5","77": 2 2 2 1 1 3
     $ V3: Factor w/ 4 levels "1","10","3","6": 2 3 4 2 3 1
     $ V2: Factor w/ 3 levels "high","low","medium": 2 2 3 2 2 1
    

    Las columnas V1 y V3 se han convertido en factores, cuando deberían ser númericas. Si utilizáramos cualquier código obtendríamos el error: Error: ‘sum’ not meaningful for factors. Para solucionarlo, empleamos el siguiente código:

    df <- cbind.data.frame(V1,V3,V2)
    str(df)
    'data.frame': 6 obs. of  3 variables:
     $ V1: num  5 5 5 45 45 77
     $ V3: num  10 3 6 10 3 1
     $ V2: Factor w/ 3 levels "high","low","medium": 2 2 3 2 2 1
    

  • reshape2
  • Empleamos dcast para crear un data frame, usando V3 como la variable valores, e indicamos como función de agregación la suma (sum).

    library(reshape2)
    dcast(df, V1  ~ V2, value.var="V3", fun = sum)
    
      V1 high low medium
    1  5    0  13      6
    2 45    0  13      0
    3 77    1   0      0
    

    Como se puede observar, ordenado las columnas alfabéticamente (high, low y medium) en lugar de respetar el orden de ocurrencia original: low, medium, high.

    dcast(df, V1  ~ factor(V2, levels = unique(V2)), value.var = "V3", sum)
    
    'data.frame': 6 obs. of  3 variables:
     $ V1: num  5 5 5 45 45 77
     $ V3: num  10 3 6 10 3 1
     $ V2: Factor w/ 3 levels "high","low","medium": 2 2 3 2 2 1
    

  • paquete base
  • Empleamos la función xtabs para crear una tabla de contingencia mediante el formato fórmula.

    xtabs(V3 ~ V1 + V2, df)
    
        V2
    V1   high low medium
      5     0  13      6
      45    0  13      0
      77    1   0      0
    

    xtabs(V3 ~ V1 + factor(V2, c("low", "medium", "high")), df)
    
       factor(V2, c("low", "medium", "high"))
    V1   low medium high
      5   13      6    0
      45  13      0    0
      77   0      0    1
    

  • dplyr y tidyr
  • Con dplyr con la función spread, el equivalente a dcast en reshape2.

    df$V2 <- factor(df$V2, levels = c("low", "medium", "high"))
    
    library(tidyr)# Función spread
    library(dplyr)
    
    df %>%
      group_by(V1, V2) %>%
      summarise(sum = sum(V3)) %>%
      spread(V2, sum, fill = 0)
    
    Source: local data frame [3 x 4]
    
         V1   low medium  high
      (dbl) (dbl)  (dbl) (dbl)
    1     5    13      6     0
    2    45    13      0     0
    3    77     0      0     1
    

    Entradas relacionadas

    Referencias

    2014-07-09

    Múltiples valores y funciones de agregación con reshape2 y plyr

    Title Anteriormente tratamos de la agregación de datos con reshape2. En esta ocasión examinaremos dos aspectos: la creación de múltiples variables de medida y de varias funciones de agregación al agrupar los datos.

    Puedes descargar el fichero Análisis de ventas2.csv y copiarlo en tu directorio de trabajo. He añadido la columna margen que utilizaremos junto con las ventas y eliminado los separadores de miles de las ventas.

    Múltiples variables de medida

    1. Importamos nuestros datos

    require(plyr)  # Para usar la función . de plyr
    require(reshape2)
    data <- read.csv("Análisis de ventas2.csv", sep = ";") # O bien
    data <- read.csv2("Análisis de ventas2.csv")
    
    2. Formateamos los datos importados.

    names(data) <- tolower(names(data))  # Nombres de columnas en minúsculas
    data$ventas <- sub(",", ".", data$ventas)  # Separador decimal el punto
    data$ventas <- as.numeric(data$ventas)  # Ventas tipo de variable numérica
    data$margen <- sub(",", ".", data$margen)  # Separador decimal el punto
    data$margen <- as.numeric(data$margen)  # Margen tipo de variable numérica
    data$fecha.de.pedido <- as.Date(data$fecha.de.pedido, "%d/%m/%Y") # Fechas
    
    3. Definimos identifiers (id.vars) y measured variables (measure.vars) con melt. Identificadores o nombres de columna y variables de medida o valores. Para añadir más variables, las especificamos en el argumento measure.vars.

    # Por posición, nº de columna.
    data.m <- melt(data, id.vars = c(1:20), measure.vars = c(6, 20))
    # Por nombre
    data.m <- melt(data, id.vars = c(1:20), measure.vars = c("ventas", "margen")) 
    
    A la derecha de la última id.vars (mesdetrimestre en este caso) crea dos columnas, con los nombres variable y value. Bajo variable incluirá aquellas definidas como measure.vars: las ventas y el margen. Bajo value, su valor correspondiente.
    4. Comenzamos a agregar datos usando dcast.

    # Por empleado ventas y margen. Función de agregación: sum.
    data.c <- dcast(data.m, empleado ~ variable, sum, margins = "empleado")
    data.c # Resultado:
    
                   empleado   ventas   margen
    1      Francisco Chaves 19974.25 12614.81
    2      Humberto Acevedo  3786.50  3041.46
    3         Jesús Escolar  2617.50  1629.45
    4     Juan Carlos Rivas  6378.00  3862.80
    5          Luis Bonifaz   680.00   571.20
    6        María González  6561.00  4548.92
    7    María Jesús Cuesta  6278.00  4518.62
    8 Pilar Pinilla Gallego  5787.50  3919.55
    9                 (all) 52062.75 34706.81
    
    Más ejemplos:

    Para cada agrupación dcast devolverá una columna por cada una de las variables (measure.vars) creadas, como en la tabla anterior. Para que sume ambas variables usamos "~ ." en lugar de "~ variable". A modo ilustrativo sumamos ventas y margen.

    # Por empleado suma de ventas y margen
    data.c <- dcast(data.m, empleado ~ ., sum, margins = "empleado")
    
                  empleado        .
    1      Francisco Chaves 32589.06
    2      Humberto Acevedo  6827.96
    3         Jesús Escolar  4246.95
    4     Juan Carlos Rivas 10240.80
    5          Luis Bonifaz  1251.20
    6        María González 11109.92
    7    María Jesús Cuesta 10796.62
    8 Pilar Pinilla Gallego  9707.05
    9                 (all) 86769.56
    
    # Total de ventas y margen separados
    data.c <- dcast(data.m, . ~ variable, sum) 
    
      .   ventas   margen
    1 . 52062.75 34706.81
    
    # Total de ventas y margen sumados
    data.c <- dcast(data.m, . ~ ., sum) 
    
      .        .
    1 . 86769.56
    
    Otras funciones de agregación, usando el ejemplo anterior:

    # Media
    data.c <- dcast(data.m, empleado ~ variable, mean, margins = "empleado")
    # Contar número de ocurrencias
    data.c <- dcast(data.m, empleado ~ variable, length, margins = "empleado")
    
    Mínimo y máximo generan un error. Es necesario usar la función suppressWarnings.

    Warning message:
    In .fun(.value[0], ...) : no non-missing arguments to min; returning Inf
    
    # Mínimo
    data.c <- suppressWarnings(dcast(data.m, empleado ~ variable, min, margins = "nombre.del.cliente"))
    # Máximo
    data.c <- suppressWarnings(dcast(data.m, empleado ~ variable, max, margins = "nombre.del.cliente"))
    

    Múltiples funciones de agregación

    Ahora explicamos cómo usar varias funciones de agregación al mismo tiempo. En la entrada y apartados anteriores usábamos solamente una función en cada agregación.

    1. Seguimos los pasos 1, 2 y 3 del punto anterior.

    2. Empleamos la función ddply del paquete plyr para presentar varias funciones de agregación en la misma tabla. En nuestro ejemplo, mínimo, media, máximo y desviación típica.

    resumen <- ddply(data.m, .(mes, empleado), summarise, min = min(value),
                                                         mean = mean(value),
                                                          max = max(value),
                                                           sd = sd(value))
    head(resumen)
    
      mes              empleado     min      mean  max        sd
    1   1      Francisco Chaves   68.25  620.8125 1400 648.62686
    2   1     Juan Carlos Rivas  231.84  253.9200  276  31.22584
    3   1    María Jesús Cuesta  175.50  490.8750  920 338.56126
    4   1 Pilar Pinilla Gallego   29.40  254.2000  530 199.75753
    5   2      Francisco Chaves  139.84  161.9200  184  31.22584
    6   2    María Jesús Cuesta 1621.20 1775.6000 1930 218.35457
    
    Los resultados consideran conjuntamente ventas y margen, se agrupan como si fueran una única variable. Para separar nuestras variables, en el argumento variables de la función ddply, especificamos mes, empleado y variable:

    resumen <- ddply(data.m, .(mes, empleado, variable), summarise,
                                                  min = min(value),
                                                mean = mean(value),
                                                  max = max(value),
                                                     sd = sd(value))
    head(resumen)
    
      mes           empleado variable    min    mean     max       sd
    1   1   Francisco Chaves   ventas 105.00 752.500 1400.00 915.7033
    2   1   Francisco Chaves   margen  68.25 489.125  910.00 595.2071
    3   1  Juan Carlos Rivas   ventas 276.00 276.000  276.00       NA
    4   1  Juan Carlos Rivas   margen 231.84 231.840  231.84       NA
    5   1 María Jesús Cuesta   ventas 270.00 595.000  920.00 459.6194
    6   1 María Jesús Cuesta   margen 175.50 386.750  598.00 298.7526
    
    Se puede observar como separa correctamente por fila los resultados por ventas y margen.

    ddply frente a dcast

    Compara la concisión con ddply frente a dcast. Además, ddply resume los datos en un único data.frame.

    resumen <- ddply(data.m, .(empleado, variable), summarise,
                                                  min = min(value),
                                                mean = mean(value),
                                                  max = max(value),
                                                    sd = sd(value),
                                            length = length(value))
    
    data.min <- suppressWarnings(dcast(data.m, empleado ~ variable, min, margins = "empleado"))
    data.mean <- dcast(data.m, empleado ~ variable, mean, margins = "empleado")
    data.max <- suppressWarnings(dcast(data.m, empleado ~ variable, max, margins = "empleado"))
    data.sd <- dcast(data.m, empleado ~ variable, sd, margins = "empleado")
    data.length <- dcast(data.m, empleado ~ variable, length, margins = "empleado")
    
    Referencias:
    Stackoverflow

    Entradas relacionadas:
    Agregar datos en R con el paquete reshape2

    2014-06-06

    Agregar datos en R con el paquete reshape2

    Title El paquete reshape2, creado por Hadley Wickham permite transformar y agregar datos con dos funciones: melt y cast. En esta entrada nos vamos a centrar en la agregación de datos para obtener resultados similares a los obtenidos con las tablas dinámicas en Excel. El objetivo de la agregación es ordenar, reducir y mostrar la información resumida de manera que nos facilite responder a preguntas planteadas sobre nuestros datos.

    Partimos de la base de datos Northwind. Exportamos la consulta Análisis de ventas a Excel y creamos una tabla dinámica con la que iremos comparando los resultados que deseamos obtener en R. Desde Excel guardamos la hoja de datos como fichero CSV que importaremos en R.

    Puedes descargar el fichero Análisis de ventas.csv y copiarlo en tu directorio de trabajo.

    Importación y formato

    1. Importamos el fichero CSV. Es importante observar el formato de la columna con valores. El símbolo de moneda si lo hubiera, los separadores decimal y de miles. Previamente instalamos los paquetes necesarios.

    require(plyr)  # Para usar la función . de plyr
    require(reshape2)
    data <- read.csv("Análisis de ventas.csv", sep = ";") 
    
    2. Formateamos los datos importados.

    names(data) <- tolower(names(data))  # Nombres de columnas en minúsculas
    data$ventas <- sub("([.])", "", data$ventas)  # Separador de miles la coma
    data$ventas <- sub(",", ".", data$ventas)  # Separador decimal el punto
    data$ventas <- as.numeric(data$ventas)  # Ventas tipo de variable numérica
    data$fecha.de.pedido <- as.Date(data$fecha.de.pedido, "%d/%m/%Y") # Fechas
    

    reshape2

    3. Definimos identifiers (id.vars) y measured variables (measure.vars) con melt. Identificadores y valores, el equivalente en las tablas dinámicas de Excel a etiquetas o rótulos de filas y valores.

    data.m <- melt(data, id.vars = c(1:19), measure.vars = 6)
    data.m # Resultado: 
    
          cliente mesdetrimestre variable value
    1 Compañía AA              1   ventas  1400
    2 Compañía AA              1   ventas   105
    3  Compañía D              1   ventas   300
    4  Compañía D              1   ventas   530
    5  Compañía D              1   ventas    35
    6  Compañía L              1   ventas   270
    
    A la derecha de la última id.vars (mesdetrimestre en este caso) crea dos columnas, con los nombres variable y value. Bajo variable sólo incluirá la variable ventas pues es la única definida como measured variable.

    4. Comenzamos a agregar datos usando dcast.

    a. Agrupando por empleado. Queremos el siguiente resultado.

    data.c <- dcast(data.m, empleado ~ variable, sum, margins = "empleado")
    data.c # Resultado:
    
                   empleado   ventas
    1      Francisco Chaves 19974.25
    2      Humberto Acevedo  3786.50
    3         Jesús Escolar  2617.50
    4     Juan Carlos Rivas  6378.00
    5          Luis Bonifaz   680.00
    6        María González  6561.00
    7    María Jesús Cuesta  6278.00
    8 Pilar Pinilla Gallego  5787.50
    9                 (all) 52062.75 
    

    Argumentos de dcast:

    data: molten data frame. El data frame obtenido con melt anteriormente.
    formula: especificamos las variables que deseamos incluir, en este caso empleado. Hay un par de caracteres especiales: "..." representa todas las otras variables no usadas en la fórmula y "." representa a ninguna variable.
    fun.aggregate: la función de agregación de la función, en ese caso sum.
    margins: para añadir los subtotales, margins = TRUE devolverá todos los subtotales disponibles.
    fill: valor que sustituirá a aquellos que faltan cuando fun.aggregate se aplica sobre un vector de longitud 0.

    Más ejemplos:

    # Total de ventas
    data.c <- dcast(data.m, . ~ variable, sum) 
    # Agrupar por otra variable, nombre de cliente
    data.c <- dcast(data.m, nombre.del.cliente ~ variable, sum, margins = "nombre.del.cliente") 
    

    Función . de plyr para filtrar

    5. Agrupamos por nombre de cliente y filtramos por el empleado Francisco Chaves. Queremos el siguiente resultado.

    data.c <- dcast(data.m, nombre.del.cliente ~ variable, sum, margins = "nombre.del.cliente", subset = .(empleado == "Francisco Chaves")) 
    data.c
    
      nombre.del.cliente   ventas
    1        Compañía AA  1505.00
    2        Compañía BB 13800.00
    3         Compañía D   184.00
    4         Compañía Y   860.00
    5         Compañía Z  3625.25
    6              (all) 19974.25
    

    Más consultas

    Jugamos con los elementos anteriores, tomados de reshape2, plyr, y los operadores lógicos. Practicamos la sintaxis e interrogamos nuestros datos hasta que confiesen.1

    6. Queremos saber las ventas de los empleados Francisco Chaves y Humberto Acevedo, agrupadas por categoría con su correspondiente subtotal por empleado. El resultado sería:

    Añadimos dos identifiers (rótulos de fila), agrupamos por el total de categoría de cada empleado y filtramos por dos empleados, Francisco Chaves o Humberto Acevedo.

    data.c <- dcast(data.m, empleado + categoría ~ variable, sum, margins = "categoría", subset = .(empleado == "Francisco Chaves" | empleado == "Humberto Acevedo")) 
    
                     empleado                   categoría   ventas
    1       Francisco Chaves                      Aceite   533.75
    2       Francisco Chaves                     Bebidas 15200.00
    3       Francisco Chaves              Carne enlatada   552.00
    4       Francisco Chaves                 Condimentos   660.00
    5       Francisco Chaves                Frutos secos   105.00
    6       Francisco Chaves     Mermeladas y confituras  2250.00
    7       Francisco Chaves         Productos horneados   384.00
    8       Francisco Chaves                       Sopas   289.50
    9       Francisco Chaves                       (all) 19974.25
    10      Humberto Acevedo                       Pasta  1950.00
    11      Humberto Acevedo           Productos lácteos  1740.00
    12      Humberto Acevedo                       Sopas    96.50
    13      Humberto Acevedo                       (all)  3786.50
    
    Más ejemplos:

    # Por empleado y categoría, excluyendo la Compañía H de los clientes
    data.c <- dcast(data.m, empleado + categoría ~ variable, sum, margins = c("categoría", "empleado"), subset = .(nombre.del.cliente != "Compañía H")) 
    
    # Otras funciones de agregación: mínimo, media y máximo
    # Ventas por nombre del cliente
    data.c <- dcast(data.m, nombre.del.cliente ~ variable, min, fill = 0) 
    data.c <- dcast(data.m, nombre.del.cliente ~ variable, mean, fill = 0)
    data.c <- dcast(data.m, nombre.del.cliente ~ variable, max, fill = 0) 
    

    Introducimos el argumento fill para evitar el mensaje de advertencia.

    Fechas

    7. La venta del empleado María Jesús Cuesta por producto entre dos fechas.

    Opción 1

    # Genera un error
    data.c <- dcast(data.m, fecha.de.pedido + producto ~ variable, margins = c("fecha.de.pedido", "producto"), sum, subset = .(fecha.de.pedido > "2006-03-01" & fecha.de.pedido < "2006-05-01" & empleado == "María Jesús Cuesta")) 
    str(data.c) # Estructura de un objeto
    
    La inclusión de la fecha para los subtotales (margins) y del filtro por fecha genera un error. Y transforma fecha.de.pedido de Date a Factor. Se comprueba con la función str que muestra la estructura interna del objeto.

    Warning messages:
    1: In Ops.factor(fecha.de.pedido, "2006-03-01") :
      > not meaningful for factors
    2: In Ops.factor(fecha.de.pedido, "2006-05-01") :
      < not meaningful for factors 
    
    > str(data.c)
    'data.frame': 1 obs. of  3 variables:
     $ fecha.de.pedido: Factor w/ 24 levels "2006-01-15","2006-01-20",..: NA
     $ producto       : Factor w/ 24 levels "Aceite de oliva Northwind Traders",..: NA
     $ NA             : num NA
    
    Opción 2

    # Subtotales incompletos
    data.c <- dcast(data.m, as.Date(fecha.de.pedido) + producto ~ variable, sum, margins =c("fecha.de.pedido", "producto"), subset = .(fecha.de.pedido > "2006-03-01" & fecha.de.pedido < "2006-05-01" & empleado == "María Jesús Cuesta"))
    data.c 
    
    No genera un error pero presenta uno subtotales incompletos, solamente por producto.

      as.Date(fecha.de.pedido)                                 producto ventas
    1       2006-03-24                       Té verde Northwind Traders    598
    2       2006-03-24                                            (all)    598
    3       2006-04-05 Galletas de chocolate surtidas Northwind Traders    230
    4       2006-04-05                    Salsa curry Northwind Traders   1000
    5       2006-04-05                                            (all)   1230
    6       2006-04-25                        Almíbar Northwind Traders    500
    7       2006-04-25                    Salsa curry Northwind Traders    120
    8       2006-04-25                                            (all)    620
    
    Opción 3

    # Resultado correcto
    fecha <- data.m$fecha.de.pedido
    data.d <- data.m[fecha > "2006-03-01" & fecha < "2006-05-01", ]
    data.c <- dcast(data.d, fecha.de.pedido + producto ~ variable, sum, margins = c("fecha.de.pedido", "producto"), subset = .(empleado == "María Jesús Cuesta"))
    data.c
    
    Filtramos previamente el molten data frame creado anteriormente con melt (punto 4).

      fecha.de.pedido                                         producto ventas
    1      2006-03-24                       Té verde Northwind Traders    598
    2      2006-03-24                                            (all)    598
    3      2006-04-05 Galletas de chocolate surtidas Northwind Traders    230
    4      2006-04-05                    Salsa curry Northwind Traders   1000
    5      2006-04-05                                            (all)   1230
    6      2006-04-25                        Almíbar Northwind Traders    500
    7      2006-04-25                    Salsa curry Northwind Traders    120
    8      2006-04-25                                            (all)    620
    9           (all)                                            (all)   2448
    
    Referencias:
    Introducción y manual


    1 Ronald Coase: "If you torture the data enough, nature will always confess."

    Nube de datos