2017-06-07

Obtener el nombre de usuario de Windows con VBA en Excel

Title

Problema

Necesitamos conocer el nombre de usuario de Windows en Excel. Por ejemplo, porque en función del mismo, mostraremos una información distinta al usuario que abra el fichero de Excel.

Solución

  1. Abrimos el Editor de Microsoft Visual Basic: Alt+F11.
  2. Copiamos la siguiente subrutina en un módulo.
    • Sub usuario()
      MsgBox Environ("UserName")
      End Sub
      
  3. Ejecutamos la subrutina: F5.
  4. Aparecerá un mensaje emergente con el nombre de usuario de Windows.
También podemos simplemente teclear en la ventana de inmediato:

?Environ("Username")
O capturar el nombre en una celda para personalizar la hoja en función de la misma.

Sub usuario()
Sheets("Hoja1").Range("A1") = Environ("UserName")
End Sub

Referencias

2017-06-04

Eliminar separador de miles de una columna en R

Title

Problema

Queremos eliminar el separador de miles del siguiente data frame

    a          b
1   1 16,244,600
2   2  8,227,103
3   3  5,959,718
4   4  3,428,131
5   5  2,612,878
6   6  2,471,784
7   7  2,252,664
8   8  2,014,775
9   9  2,014,670
10 10  1,841,710

  • Datos originales
  • structure(list(a = 1:10, b = structure(c(2L, 10L, 9L, 8L, 7L, 
    6L, 5L, 4L, 3L, 1L), .Label = c("1,841,710", "16,244,600", "2,014,670", 
    "2,014,775", "2,252,664", "2,471,784", "2,612,878", "3,428,131", 
    "5,959,718", "8,227,103"), class = "factor")), .Names = c("a", 
    "b"), class = "data.frame", row.names = c(NA, -10L))
    

    Solución

    Empleamos la función gsub para encontrar y reemplazar la coma, y as.numeric para converir la columna en número.

    data$b <- as.numeric(gsub(",", "", data$b))
    data
    
        a        b
    1   1 16244600
    2   2  8227103
    3   3  5959718
    4   4  3428131
    5   5  2612878
    6   6  2471784
    7   7  2252664
    8   8  2014775
    9   9  2014670
    10 10  1841710
    

    Entradas relacionadas

    Referencias

    2017-05-31

    Unir todos los ficheros de texto de una carpeta con VBA en Excel

    Title

    Problema

    Deseamos unir y consolidar todos los ficheros de texto guardados en una carpeta en un fichero de texto único. Por ejemplo, como paso previo para importar el mismo en Excel, Access u otros programa.

    Solución

    El siguiente código unirá todos los ficheros con la extensión txt presentes en la ruta donde se ubica el fichero Excel ThisWorkbook.Path, con independencia del formato, columnas o encabezados. Insertamos un salto de línea vbCrLf delante de cada fichero.

    1. Abrimos el Editor de Microsoft Visual Basic: Alt+F11.
    2. Copiamos la siguiente subrutina en un módulo.
      • Sub Unir_Ficheros()
            Dim t As Single
            t = Timer
                c00 = ThisWorkbook.Path & "\" ' the path
                c01 = Dir(c00 & "*.txt")
                    Do Until c01 = ""
                        c02 = c02 & vbCrLf & CreateObject("scripting.filesystemobject").opentextfile(c00 & c01).readall
                        c01 = Dir
                    Loop
                CreateObject("scripting.filesystemobject").createtextfile(c00 & "nuevo_fichero.txt").write c02
            MsgBox Timer - t
        End Sub
        
    3. Ejecutamos la subrutina, F5.
    4. Aparecerá un cuadro de diálogo mostrando el tiempo de ejecución de la subrutina.
    5. En la carpeta en la que se ubica el Excel se habrá creado un fichero con el nombre: nuevo_fichero.txt.

    Referencias

    2017-05-26

    Convertir de formato largo a ancho con sqldf en R

    Title

    Problema

    Deseamos transformar un data frame de formato largo a ancho. Partimos del siguiente data frame:

            name numbers      value
    1  firstName       1 -0.3016990
    2  firstName       2  0.4782982
    3  firstName       3 -0.3274221
    4  firstName       4  0.8950889
    5 secondName       1 -1.3476795
    6 secondName       2 -0.4671124
    7 secondName       3 -1.0883609
    8 secondName       4  1.8702156
    

    Y queremos llegar a este otro. Con name como nombres de filas, cuatro columnas basadas en numbers y como valores, values.

                      X1         X2         X3        X4
    firstName  -0.301699  0.4782982 -0.3274221 0.8950889
    secondName -1.347680 -0.4671124 -1.0883609 1.8702156
    

  • Datos originales
  • dat1 <- structure(list(name = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
    2L), .Label = c("firstName", "secondName"), class = "factor"), 
        numbers = c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), value = c(-0.301698990300544, 
        0.47829821507312, -0.327422119821659, 0.895088877410118, 
        -1.3476795169412, -0.467112422933039, -1.08836089961649, 
        1.87021564288651)), .Names = c("name", "numbers", "value"
    ), row.names = c(NA, -8L), class = "data.frame")
    

    Solución

  • Paquete sqldf
  • Empleamos la sintaxis de SQL de sqldf para transformar o pivotar de formato largo a ancho. Empleamos MAX(CASE WHEN.

    library(sqldf)
    sqldf('SELECT name,
          MAX(CASE WHEN numbers = 1 THEN value ELSE NULL END) x1, 
          MAX(CASE WHEN numbers = 2 THEN value ELSE NULL END) x2,
          MAX(CASE WHEN numbers = 3 THEN value ELSE NULL END) x3,
          MAX(CASE WHEN numbers = 4 THEN value ELSE NULL END) x4
          FROM dat1
          GROUP BY name')
    
                      X1         X2         X3        X4
    firstName  -0.301699  0.4782982 -0.3274221 0.8950889
    secondName -1.347680 -0.4671124 -1.0883609 1.8702156
    

    Entradas relacionadas

    Referencias

    2017-05-24

    Cambiar el orden de un diagrama de barras apiladas con ggplot2

    Title

    Problema

    Deseamos controlar el orden en el que se apilan las barras de un diagrama de barras en ggplot2.

    • Gráfico original
    • Por defecto las barras se apilan alfabéticamente en función de la variable usada en el argumento fill.

      library(reshape2)
      library(ggplot2)
      ra.melt <- melt(ra)
      p <- ggplot(ra.melt, aes(x = variable, y = value))
      p + geom_bar(aes(fill = quality), stat = "identity") + 
        labs(x = "group", y = "percentage (%)")
      
      Comprobamos los niveles de la variable quality.

      levels(ra.melt$quality)
      
       [1] "A"     "B"     "C"     "D"     "E"     "F"    
       [7] "G"     "H"     "I"     "J"     "K"     "L"    
      [13] "M"     "other"
      
    • Datos originales
    • ra <- structure(list(quality = structure(c(2L, 6L, 13L, 1L, 7L, 5L, 
      10L, 4L, 3L, 9L, 11L, 12L, 8L, 14L), .Label = c("A", "B", "C", 
      "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "other"), class = "factor"), GY = c(25.5932389, 13.9567819, 11.7333, 8.6439, 7.8351008, 
          8.29, 6.059643, 3.8608517, 4.3277, 3.1710598, 1.2021144, 
          1.0986329, 0.9369271, 3.2907496), TH = c(23.0215577, 15.8975387, 
          10.5075, 7.8888, 8.8121504, 8.276, 6.4356378, 3.9147685, 
          5.4838, 3.9339386, 1.3921565, 0.742406, 0.8795013, 2.8142444
          ), SZ = c(21.217152, 16.0363831, 11.154, 8.5094, 7.945884, 
          10.2717, 5.4962929, 4.1381946, 5.1141, 3.4053352, 1.8472827, 
          1.0648934, 0.9792861, 2.820096), DZ = c(23.7548859, 14.4732136, 
          12.1292, 10.4722, 8.0838209, 7.0575, 5.144598, 4.174118, 
          5.4004, 3.1940577, 1.4427867, 1.1323864, 0.8986281, 2.6422047
          ), FP = c(19.9848602, 16.420735, 12.9683, 11.2059, 7.5143706, 
          6.8747, 5.8653262, 5.5412901, 4.182, 3.5347168, 1.3838249, 
          0.8811604, 0.8585596, 2.7842562)), .Names = c("quality", 
      "GY", "TH", "SZ", "DZ", "FP"), class = "data.frame", row.names = c("1", 
      "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
      "14"))
      

    Solución

    • En el orden original del data frame
    • ra.melt$quality <- factor(ra.melt$quality, levels = ra$quality)
      p <- ggplot(ra.melt, aes(x = variable, y = value))
      p + geom_bar(aes(fill = quality), stat = "identity") + 
          labs(x = "group", y = "percentage (%)")
      
      factor(ra.melt$quality, levels = ra$quality)
      
       [1] B     F     M     A     G     E     J     D    
       [9] C     I     K     L     H     other B     F    
      [17] M     A     G     E     J     D     C     I    
      [25] K     L     H     other B     F     M     A    
      [33] G     E     J     D     C     I     K     L    
      [41] H     other B     F     M     A     G     E    
      [49] J     D     C     I     K     L     H     other
      [57] B     F     M     A     G     E     J     D    
      [65] C     I     K     L     H     other
      Levels: B F M A G E J D C I K L H other
      
    • En el orden reverso del original
    • ra.melt$quality <- factor(ra.melt$quality, levels = rev(ra$quality))
      p <- ggplot(ra.melt, aes(x = variable, y = value))
      p + geom_bar(aes(fill = quality), stat = "identity") +  
          labs(x = "group", y = "percentage (%)")
      
      factor(ra.melt$quality, levels = rev(ra$quality))
      
       [1] B     F     M     A     G     E     J     D    
       [9] C     I     K     L     H     other B     F    
      [17] M     A     G     E     J     D     C     I    
      [25] K     L     H     other B     F     M     A    
      [33] G     E     J     D     C     I     K     L    
      [41] H     other B     F     M     A     G     E    
      [49] J     D     C     I     K     L     H     other
      [57] B     F     M     A     G     E     J     D    
      [65] C     I     K     L     H     other
      Levels: other H L K I C D J E G A M F B
      
      O alternativamente, usamos la función fct_rev

      library(forcats)
      p <- ggplot(ra.melt, aes(x = variable, y = value))
      p + geom_bar(aes(fill = fct_rev(quality)), stat = "identity") + 
        labs(x = "group", y = "percentage (%)")
      
    • Si deseamos invertir el orden de las barras pero no de la leyenda, usamos el position_stack(reverse = TRUE)
    • p <- ggplot(ra.melt, aes(x = variable, y = value))
      p + geom_bar(aes(fill = fct_rev(quality)), stat = "identity", position = position_stack(reverse = TRUE)) + labs(x = "group", y = "percentage (%)")
      

    Referencias

    Entradas relacionadas

    2017-05-22

    Crear diagramas de dispersión dinámicos con manipulate en R

    Title

    Problema

    El paquete manipulate nos permite modificar gráficos interactivamente en RStudio mediante controles deslizantes, selectores, casillas y botones. En este ejemplo, crearemos un diagrama de dispersión en el que podremos seleccionar dinámicamente las columnas del data frame a representar en cada eje.

    Solución

    • Creamos la función
    • Dentro de plot utilizamos los argumentos de cada eje seleccionado: xaxis y yaxis. Usamos controles deslizantes (sliders) para manipular el gráfico. Fijamos los valores iniciales en 1 y 2.

      library(manipulate)
      scatterplot <- function(dataset){
        vars <- as.list(names(dataset))
        name <- sys.call()[[2]]
      manipulate(
        plot(dataset[, xaxis] ~ dataset[, yaxis], 
             xlab = colnames(dataset)[xaxis],
             ylab = colnames(dataset)[yaxis], 
             main = as.character(name)),   
        xaxis = slider(1, as.numeric(dim(dataset)[2]), initial = 1), 
        yaxis = slider(1, as.numeric(dim(dataset)[2]), initial = 2)  
        )
      }
      
    • Indicamos data frame a representar
    • scatterplot(mtcars)
      

    Resultado

    En los controles deslizantes aparecen las 11 columnas del data frame mtcars. Al seleccionar una columna en el control deslizante se actualizarán las datos representados, el título principal y los títulos de los ejes. Si la columna seleccionada no fuera numérica, no se representará un diagrama de dispersión.

    Entradas relacionadas

    Referencias

    2017-05-16

    Filtrar una tabla de contingencia en R

    Title

    Problema

    Deseamos filtrar una tabla de contigencia. En nuestro ejemplo con el conjunto de datos chickwts, aquellos que tengan un factor de feed mayor que 11.

    table(chickwts$feed)
    
       casein horsebean   linseed  meatmeal   soybean sunflower 
           12        10        12        11        14        12
    

    Solución

    • Paquete base
    • Utilizando la función subset.

      subset(data.frame(table(chickwts$feed)), Freq > 11)
      
    • dplyr
    • library(dplyr)
      chickwts %>% 
        count(feed) %>%
        filter(n > 11) 
      
      

    Resultado

     # base
          Var1 Freq
    1    casein   12
    3   linseed   12
    5   soybean   14
    6 sunflower   12
    
    # dplyr
    
    # A tibble: 4 × 2
           feed     n
          
    1    casein    12
    2   linseed    12
    3   soybean    14
    4 sunflower    12
    

    Entradas relacionadas

    Referencias

    2017-05-02

    Cómo dividir un data frame en partes iguales y quedarnos con una de ellas

    Title

    Problema

    Queremos dividir un data frame en 5 partes iguales y quedarnos con una de ellas, en nuestro ejemplo la tercera.

    df<- data.frame(data=(1:100))
    
    library(tibble)
    as_tible(df)
    
    # A tibble: 100 × 1
        data
       
    1      1
    2      2
    3      3
    4      4
    5      5
    6      6
    7      7
    8      8
    9      9
    10    10
    # ... with 90 more rows
    

    Solución

    Creamos una columna con la función ntile que nos indica cada una de las 5 partes del data frame. Filtramos el data frame quedándonos con la tercera parte.

    library(dplyr)
    df[ntile(df$data, 5) == 3, ]
    df %>% 
      mutate(n = ntile(data, 5)) %>% 
      filter(n == 3) %>% 
      select(data)
    

    Resultado

       data
    1    41
    2    42
    3    43
    4    44
    5    45
    6    46
    7    47
    8    48
    9    49
    10   50
    11   51
    12   52
    13   53
    14   54
    15   55
    16   56
    17   57
    18   58
    19   59
    20   60
    

    Entradas relacionadas

    Referencias

    Nube de datos