2015-02-06

Campo calculado devuelve totales incorrectos en Excel

Title En ocasiones Excel devuelve totales y subtotales incorrectos para campos calculados de una tabla dinámica.

Ejemplo

Imaginemos que tenemos el siguiente origen de datos.

Creamos el campo calculado Venta dentro de la siguiente tabla dinámica.

Como se puede observar los subtotales por categoría no son iguales a la suma de productos. El total tampoco es igual a la suma de subtotales. Básicamente, Excel calcula primero lo subtotales o totales y luego la operación aritmética. Multiplica 60x500 para los subtotales y 120x1.000 para el total.

Solución

Creamos una nueva columna en nuestro origen de datos con el cálculo necesario. Cambiamos el origen de datos de la tabla dinámica para incluir esa columna y actualizamos la tabla.

La última columna refleja los cálculos de los subtotales y totales correctamente.

Referencias

2015-02-04

Introducción al diagrama de caja (box plot) en R

Title El diagrama de caja —box plot— es un tipo de gráfico que utiliza los cuartiles para representar un conjunto de datos. Fue introducido por John W. Tukey en 1969. Permite observar de un vistazo la distribución de los datos y sus principales características: centralidad, dispersión, simetría y tamaño de las colas. La mejor manera de entender un diagrama de caja es gráficamente.

Explicación gráfica

Elementos y propiedades

  • Elementos
- Línea, dentro de la caja, es la mediana de los datos: Q2
- Caja, representa el rango intercuartílico: Q3 - Q1.
- Bigotes, las líneas sólidas al final de las líneas de guiones que se extienden desde la caja. Definen los límites más allá de los cuales consideramos los valores como atípicos. Existen diferentes modos de calcularlos D.
- Valores atípicos, aquellos puntos fuera de los bigotes. Se representan como puntos o pequeños círculos.

  • Propiedades
- Centralidad y localización, representada por la mediana que es la línea que corta la caja
- Dispersión, proporcionada por la altura o longitud —si es horizontal— de la caja. También por la amplitud de los bigotes.
- Simetría, por la mediana en el interior de la caja y de la caja dentro de los bigotes.
- Tamaño de las colas, se observa por la amplitud de los bigotes en relación a la caja y por los valores atípicos representados.

Sin valores atípicos

# Sin valores atípicos
boxplot(iris$Sepal.Width, range = 0)
En el caso de no querer mostrar valores atípicos, especificamos range = 0. Los bigotes se extenderán hasta los extremos de los datos.

  • Datos
  • Para obtener los valores de los diferentes elementos del gráfico tenemos varias opciones:

    Resumen con los 5 números de Tukey: mínimo, bigote inferior, mediana, bigote superior, máximo

    fivenum(iris$Sepal.Width)
    
    [1] 2.0 2.8 3.0 3.3 4.4
    
    Mediante la función summary que proporciona además la media.

    summary(iris$Sepal.Width)  
    
     Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      2.000   2.800   3.000   3.057   3.300   4.400 
    

    Con valores atípicos

    # Con valores atípicos
    boxplot(iris$Sepal.Width) 
    
    El cálculo de los bigotes en R se especifica en el argumento range. Por defecto es 1.5, lo que implica:
    • Inferior: el mayor de los siguientes dos valores, el mínimo o Q1 - 1,5*RIC.
    • Superior: el menor de los siguientes dos valores, el máximo o Q3 + 1,5*RIC.<(li>
  • Datos
  • Podríamos emplear las funciones summary y fivenum como hicimos anteriormente, pero los valores de los bigotes serían erróneos pues nos devuelven el mínimo y el máximo. Empleamos la función boxplot.stats que es utilizada por boxplot para producir el gráfico con el cálculo.

    boxplot.stats(iris$Sepal.Width)$stats
    
    [1] 2.2 2.8 3.0 3.3 4.0
    
    Si en lugar de 1,5 empleamos otro coeficiente en boxplot, lo especificamos con el argumento coef en boxplot.stats.

    boxplot(iris$Sepal.Width, range = 2) 
    boxplot.stats(iris$Sepal.Width, coef = 2)$stats 
    

    Orientación y formato

    Existen muchas opciones para formatear el gráfico disponibles en la ayuda de la función. A continuación, simplemente lo orientamos horizontalmente, le cambiamos el color y añadimos un título al eje.

    boxplot(iris$Sepal.Width,
            col = 'palegreen',
            xlab = "Sepal Width",
            horizontal = TRUE)
    

    Entradas relacionadas

    Referencias

    2015-02-02

    Atajo para rellenar el contenido de celdas adyacentes en Excel

    Title En Excel podemos rellenar los contenidos adyacentes a una celda mediante el controlador de relleno, o bien mediante el cuadro de diálogo series. En esta entrada veremos este segundo modo usando atajos, ilustrado en la siguiente imagen:

    Duplicar celdas

    En español:

    Ctrl+J: duplica el contenido de la celda superior en el rango seleccionado .
    Ctrl+D: duplica el contenido de la celda a la izquierda en el rango seleccionado.
    Ctrl+D y Ctrl+J: duplica el contenido de la celda superior izquierda en el rango seleccionado.

    En inglés:

    Ctrl+D: duplica el contenido de la celda superior del rango seleccionado.
    Ctrl+R: duplica el contenido de la celda a la izquierda del rango seleccionado.
    Ctrl+D y Ctrl+R: duplica el contenido de la celda superior izquierda en el rango seleccionado.

    No existen atajos para rellenar hacia arriba o hacia la izquierda.

    Cuadro de diálogo series

    En español:

    Alt+O seguido de FL y S.

    En inglés:

    Alt+H seguido de FI y S.

    Sin métodos abreviados de teclado

    Para duplicar, rellenar, en las diferentes direcciones:

    • En la ficha Inicio, en el grupo Modificar, clic en Rellenar y en la opción Hacia abajo, Hacia la derecha, Hacia arriba o Hacia la izquierda deseada.

    Para acceder al cuadro de diálogo series y seleccionar las diferentes opciones:

    • En la ficha Inicio, en el grupo Modificar, clic en Rellenar y luego en Series.

    Referencias

    2015-01-28

    Ley de Benford en Ms Access

    Title La ley de Benford, también conocida como la ley del primer dígito, se refiere a la frecuencia de distribución del primer dígito en muchos de los números que aparecen en la vida real. En esta distribución, el 1 aparece con una frecuencia aproximada del 30% mientras que el 9 aparece con una frecuencia menor del 5%. Por primer dígito se refiere al primer dígito no nulo o significativo.

    Esta ley se puede aplicar a una gran variedad de fuentes de datos: facturas de electricidad, direcciones de calles, precios de acciones, cifras de población, tasas de mortalidad, longitud de los ríos o constantes físicas y matemáticas. Se ha aplicado en la detección de fraudes en contabilidad, resultados electorales y científicos.

    Ejemplo

    Queremos calcular la frecuencia relativa del campo Cargo de la tabla Pedidos de la base de datos Neptuno. El resultado final es una tabla con los dígitos, su frecuencia absoluta, el total de registros y la frecuencia porcentual.

    Solución 1

    En dos pasos:

    1. Consulta intermedia (qry_Total): calcula el total de registros de la tabla cuyo último dígito del campo Cargo es mayor que cero.
    2. SELECT COUNT(Pedidos.Cargo) AS Total
      FROM Pedidos
      WHERE (((Mid([Cargo],1,1))>0));
      
    3. Consulta final (qry_BenfordLaw) que calcula la frecuencia relativa usando el total de la consulta anterior.

    SELECT Mid([Cargo],1,1) AS Dígito, 
    COUNT(Pedidos.Cargo) AS Frecuencia, 
    qry_Total.Total, 
    COUNT([Pedidos]![Cargo])/[Total] AS Porcentaje
    FROM Pedidos, qry_Total
    GROUP BY Mid([Cargo],1,1), qry_Total.Total
    HAVING (((Mid([Cargo],1,1))>0));
    

    Solución 2

    Creando una subconsulta evitando la consulta intermedia.

    SELECT Mid([Cargo],1,1) AS Dígito, 
    COUNT(Pedidos.Cargo) AS Frecuencia, 
    (select count([Cargo]) FROM Pedidos WHERE (((Mid([Cargo],1,1))>0))) AS Total, 
    Count([Pedidos]![Cargo])/[Total] AS Porcentaje
    FROM Pedidos
    GROUP BY Mid([Cargo],1,1)
    HAVING (((Mid([Cargo],1,1))>0));
    
    La subconsulta es idéntica a la consulta intermedia (qry_Total) que realizamos en la solución 1.

    (SELECT COUNT([Cargo]) FROM Pedidos WHERE (((Mid([Cargo],1,1))>0))) AS Total
    

    Referencias

    2015-01-26

    Compactar y reparar Access cada cierto tiempo

    Title

    Problema

    Ms Access permite compactar y reparar automáticamente nuestra base de datos al cerrarla. Aunque así nos aseguramos de compactar la base de datos regularmente, esta opción presenta ciertas limitaciones. La principal es que incrementa el tiempo que tarda en cerrarse la base de datos. Además, si ésta es de gran tamaño y entramos en ella frecuentemente la acción es aún más lenta y redundante.

    Solución

    En lugar de compactar y reparar cada vez que salgamos de la base de datos, programamos Access para que compacte y repare nuestra base de datos cada cierto tiempo.

    1. Creamos la siguiente función en un módulo.
    2. ' Benjamín Martín-Palanco
      Public Function Compactar()
      
          Dim fs As Object, f As Object, s As String
          Dim i As Date, j As Date
          
          Set fs = CreateObject("Scripting.FileSystemObject")
          Set f = fs.GetFile(CurrentDb.Name)
           
           i = f.DateLastModified 
           j = Now - i
           
          Set fs = Nothing: Set f = Nothing
           
           If j > 8 / 24 Then  ' Cada 8 horas. 1 = 24 horas.
              Application.SetOption "Auto compact", True
              Else
              Application.SetOption "Auto compact", False
           End If
           
      End Function
      
      
    3. Creamos una macro que ejecute la función.
    4. Guardamos la macro como Autoexec para que se ejecute automáticamente al abrir la base de datos.

    Notas

    Creamos una función que se ejecutará automáticamente cada vez que abramos la base de datos. Ésta comprobará si hemos sobrepasado el tiempo definido. En caso afirmativo compactará al cerrar, en caso negativo nos permitirá salir sin compactar.

    • Utilizamos FileSystemObject (FSO) para acceder a la propiedad última fecha de modificación (DateLastModified) de la base de datos actual (CurrentDb.Name). Restamos la fecha actual de la fecha de última modificación y si es mayor que el tiempo especificado —ochos horas en nuestro ejemplo— activará la opción compactar al cerrar con Application.SetOption "Auto compact".
    • Al nombrar como Autoexec la macro que ejecuta la función, nos aseguramos de que al abrir la base de datos se ejecute automáticamente. En este caso no será necesario cerrar y volver a abrir la base de datos para que la opción tenga efecto, lo que sucedería si seleccionamos manualmente dicha opción en la base de datos actual. Si deseamos que al abrir la base de datos la macro no se ejecute, mantenemos presionada la tecla MAYÚS.

    Referencias

    2015-01-22

    Medidas de tendencia central en histogramas en R: moda

    Title En esta entrada añadiremos a los histogramas otra medida de tendencia central: la moda. Completamos así una entrada anterior en la que añadimos la media y la mediana.

    Asimétrica negativa o a la izquierda

    media < mediana < moda

      rbeta(n, 5, 2)

    Simétrica

    media = mediana = moda

      rbeta(n, 5, 5)

    Asimétrica positiva o a la derecha

    media > mediana > moda

      rbeta(n, 2, 5)
      parámetro x de legend = "topright"

    Código

    Instalamos y cargamos el paquete modeest, para calcular la moda de las distribuciones con las funciones betaMode y normMode.

    install.packages("modeest")
    library(modeest)
    
    Empleamos la función de densidad de beta:

    dbeta(x, shape1, shape2, ncp = 0, log = FALSE)

    Modificaremos los parámetros de la distribución beta a (shape1) y b (shape2) para alterar la forma de la distribución y que sea asimétrica negativa, simétrica o asimétrica positiva.

    Asimétrica negativa: shape1 = 5, shape2 =2
    Simétrica: shape1 = 5, shape2 =5
    Asimétrica positiva: shape1 = 2, shape2 =5

    # Ejemplo: asimétrica negativa
    set.seed(2014)
    vble  <- rbeta(1000000, 5, 2) # Parametros a modificar
    
    # Histograma
    hist(vble, 
         prob = TRUE,
         xlim = c(0, 1),
         col = "slategray2",
         border = "white",
         main = "Asimetría negativa", 
         xlab = "", 
         las = 1) 
    
    # Función de densidad
    lines(density(vble), # density plot
          lwd = 2, # thickness of line
          col = "darkblue")
    
    # Líneas
      # Media
    mean  <- mean(vble)
    segments(x0 = mean, y0 = 0, 
             x1 = mean, y1 = dbeta(mean, 5, 2), # Parametros a modificar
             col = "blue", lwd = 2) # lty = 3 dotted line
      # Mediana
    median <-  median(vble)
    segments(x0 = median, y0 = 0, 
             x1 = median, y1 = dbeta(median, 5, 2), # Parametros a modificar
             col = "red", lwd = 2)
      # Moda
    mode <- betaMode(5, 2)
    segments(x0 = mode, y0 = 0, x1 = mode, 
             y1 = dbeta(mode, 5, 2), 
             col = "orange", lwd = 2)
    
    # Leyenda
    legend(x = "topleft", # Ubicación de la leyenda
           c("Función de densidad", "Media", "Mediana"),
           col = c("darkblue", "blue", "red"),
           lwd = c(2, 2, 2),
           bty = "n")
    

    Alternativa

    Podemos añadir las líneas de la media y mediana mediante la función abline. La diferencia respecto al ejemplo anterior con segments es que la línea cortará a la función de densidad pues es infinita.

    set.seed(2014)
    vble  <- rnorm(n = 1000000) 
    hist(vble, 
         prob = TRUE,
         xlim = c(-3,3), 
         ylim = c(0, .4),
         col = "slategray2",
         border = "white",
         main = "Simétrica", 
         xlab = "", 
         las = 1) 
    
    # Función de densidad
    lines(density(vble), # density plot
          lwd = 2, # thickness of line
          col = "darkblue")
    # Media
    abline(v = mean(vble),
           col = "blue",
           lwd = 2)
    # Mediana
    abline(v = median(vble),
           col = "red",
           lwd = 2)
    # Mode
    abline(v = normMode(),
           col = "orange",
           lwd = 2)
    

    Entradas relacionadas

  • Calcular la moda en R usando el paquete modeest
  • Medidas de tendencia central en histogramas en R: media y mediana
  • Generar una distribución normal aleatoria en R
  • Operaciones básicas con la distribución normal en R
  • 2015-01-20

    Calcular la moda en R usando el paquete modeest

    Title R no dispone de una función en su paquete base que nos permita calcular la moda. La función mode devuelve el tipo o modo de almacenamiento de un objeto. Hay múltiples formas de calcular la moda haciendo uso de otras funciones de R. Sin embargo, ahora optamos por cargar el paquete modeest y usar la función mlv que devuelve el valor de un vector numérico.

    # Si modeest no está instalado y cargado
    install.packages("modeest") 
    library(modeest)
    
    Usamos como ejemplo el data frame trees.

    mlv(trees$Volume, method = "mfv") # O mlv(trees$Volume, method = "discrete")
    
    Mode (most frequent value): 10.3 
    Bickel's modal skewness: 0.8709677 
    Call: mlv.default(x = trees$Volume, method = "discrete") 
    
    Si tan sólo queremos el valor más frecuente:

    mlv(trees$Volume, method = "mfv")[1]
    

    Calcular la moda de múltiples columnas

    apply(trees, 2, mlv,  method = "mfv")
    
    $Girth
    Mode (most frequent value): 13.325 
    Bickel's modal skewness: -0.1612903 
    Call: mlv.default(x = newX[, i], method = "discrete") 
    
    $Height
    Mode (most frequent value): 80 
    Bickel's modal skewness: -0.3870968 
    Call: mlv.default(x = newX[, i], method = "discrete") 
    
    $Volume
    Mode (most frequent value): 10.3 
    Bickel's modal skewness: 0.8709677 
    Call: mlv.default(x = newX[, i], method = "discrete") 
    

    Entradas relacionadas

    2015-01-18

    Mensaje de error en Access: no se pudo eliminar nada en las tablas especificadas

    Title Cuando queremos realizar una consulta de eliminación que emplea varias tablas puede aparecer el siguiente mensaje de error: No se pudo eliminar nada en las tablas especificadas.

    Ejemplo

    Empleamos la base de datos Neptuno y creamos una consulta de eliminación con las tablas Detalles de pedidos y Pedidos. Queremos eliminar todos aquellos pedidos, y sus detalles, que contengan al menos un producto con descuento.

    Al ejecutar la consulta Access muestra el mensaje:

    Solución

    1. Abrimos la hoja de propiedades de la consulta.
    2. Establecemos la propiedad Registros únicos en Sí.
    3. Ejecutamos la consulta de nuevo

    Resultado

    Elimina 380 registros de la tabla Pedidos y quedan 450 pedidos con productos sin ningún descuento. Además, habremos eliminado 1.045 registros de la tabla Detalles de pedidos. Esto es debido a que en las relaciones entre ambas tablas están activadas la casillas Exigir integridad referencial y Eliminar en cascada los registros relacionados. Access elimina automáticamente todos los registros que hacen referencia a la clave principal (IdPedido) al eliminarse el registro que contiene la clave principal.

    En la tabla Detalles de pedidos quedan 1.110 productos. Cuando mostramos la consulta en modo Ver nos muestra los 838 registros que tienen algún descuento. Pero al ejecutar la consulta también borra aquellos productos de pedidos que contienen algún producto descontado (comparten el mismo IdPedido): 1.045.

    Explicación

    Instrucción SQL de la consulta antes de cambiar la propiedad de Registros únicos a No.

    DELETE Pedidos.*, [Detalles de pedidos].Descuento
    FROM Pedidos INNER JOIN [Detalles de pedidos] ON Pedidos.IdPedido = [Detalles de pedidos].IdPedido
    WHERE ((([Detalles de pedidos].Descuento)>0));
    Instrucción SQL de la consulta antes de cambiar la propiedad de Registros únicos a Sí.

    DELETE DISTINCTROW Pedidos.*, [Detalles de pedidos].Descuento
    FROM Pedidos INNER JOIN [Detalles de pedidos] ON Pedidos.IdPedido = [Detalles de pedidos].IdPedido
    WHERE ((([Detalles de pedidos].Descuento)>0));
    Al establecer la propiedad Registros únicos en Sí, Access añade DISTINCTROW al predicado de la consulta SQL. En nuestro ejemplo, la tabla Pedidos no contiene registros duplicados de IdPedido, pero la tabla Detalles de pedidos sí, pues cada pedido incluye diferentes productos. Al indicar DISTINCTROW genera una lista de pedidos única con al menos un registro en Detalles de pedidos. Si omitimos DISTINCTROW genera varias filas para cada una de los pedidos que tengan más de un registro en Detalles de pedido.

    Referencias

    Nube de datos