2017-10-16

Eliminar columnas con nombres duplicados de un data frame en R

Title

Problema

Queremos eliminar las columnas con nombres duplicados de un data frame en R.

df <- data.frame(a = 1:2, b = 1:2, 
                 c = 1:2, a = 2:3, 
                 a = 2:3, b = 2:3, 
                 check.names = F)
  a b c a a b
1 1 1 1 2 2 2
2 2 2 2 3 3 3

Solución

  • Base
  • df[, !duplicated(df)] # o bien
    df[, unique(df)]
    
     a b c
    1 1 1 1
    2 2 2 2
    
  • dplyr
  • Empleamos funciones del paquete base pero evitamos los corchetes para hacerla más legible.

    library(dplyr)
    df %>% subset(select = !duplicated(names(.))) # o bien
    df %>% subset(select = unique(names(.)))
    

2017-10-14

Comprobar si una celda contiene un hipevínculo


Title

Problema

Necesitamos comprobar mediante una fórmula si unas celdas contienen un hipervínculo.

Solución

  1. Abrimos el Editor de Microsoft Visual Basic: Alt+F11.
  2. Creamos la siguiente función en un módulo.
    • Function ESHIPERVINCULO(r As Range) As Boolean
        ESHIPERVINCULO = r.Hyperlinks.Count
      End Function
      
  3. Usamos la función recién creada ESHIPERVINCULO en cualquier celda.
Es importante recalcar que la fórmula nos indica si hay un hipervínculo, no si éste es válido.

Entradas relacionadas

Referencias

2017-09-25

Mínimo común múltiplo y máximo común divisor en R

Title

Problema

Deseamos calcular el mínimo común múltiplo y el máximo común divisor de un vector en R.

Solución

Usamos el paquete numbers. Las funciones mLCM(x) y mGCD(x) computan el mínimo común múltiplo y el máximo común divisor de todos los números de un vector x de números enteros:

library(numbers)
    mGCD(c(4, 8, 12, 16, 20))
[1] 4
    mLCM(c(8,9,21))
[1] 504
    # Sequences
    mLCM(1:20)
[1] 232792560

Referencias

2017-08-31

Eliminar los niveles no usados de un factor en R

Title

Problema

Cuando filtramos un data frame que contiene un factor, y creamos por ejemplo una tabla de contingencia, R nos muestra también aquellos niveles del factor no usados.

df <- data.frame(name = c("a", "a", "a", "b", "b", "c", "c", "c", "c"), x = 1:9)
library(dplyr)
aa <-  df %>%
  group_by(name) %>%
  filter(n() < 4) %>% 
  droplevels()
table(aa$name)
En este ejemplo muestra c, cuando queremos que muestre solamente a y b.

# Resultado
a b c 
3 2 0
# Resultado deseado
a b 
3 2

Solución

Usamos la función droplevels o factor.

table(droplevels(aa$name))
table(factor(aa$name))
O como estamos empleando el paquete dplyr.

aa <-  df %>%
  group_by(name) %>%
  filter(n() < 4) %>% 
  droplevels()
table(aa$name)

Referencias

2017-08-16

Cómo comparar varias distribuciones de frecuencias con ggplot2

Title

Problema

Como vimos anteriormente con ggplot2 podemos crear un histograma fácilmente.

library(ggplot2)
ggplot(diamonds, aes(price)) +
  geom_histogram(binwidth = 500)
Pero si queremos comparar por calidad de tallado (quality of the cut), podríamos:
  • Filtrar por tipo de tallado

  • library(dplyr)
    ggplot(filter(diamonds, cut == "Ideal"), aes(price)) +
      geom_histogram(binwidth = 500)
    

  • Apilar por tipo de tallado

  • ggplot(diamonds, aes(price, fill = cut)) +
      geom_histogram(binwidth = 500)
    
  • Sin apilar aplicando transparencia
  • 
    ggplot(diamonds, aes(price, fill = cut)) +
    +     geom_histogram(binwidth = 500, position = "identity", alpha = 0.2)
    

Solución

Una alternativa más clara es utilizar la función geom_freqpoly que muestra líneas en lugar de barras para representar las frecuencias. Cuando se solapan es más sencillo interpretar líneas que barras.

ggplot(diamonds, aes(price, colour = cut)) +
  geom_freqpoly(binwidth = 500)
Si deseamos representar solamente un tipo de tallado:

ggplot(filter(diamonds, cut == "Ideal"), aes(price, colour = cut)) + geom_freqpoly(binwidth = 500)

Referencias

2017-08-14

Reemplazar múltiples palabras simultáneamente con Notepad++

Title

Problema

Queremos reemplazar múltiples palabras simultáneamente con Notepad++ dentro de la función buscar y reemplazar. En este ejemplo deseamos reemplazar las siguientes 4 cadenas de texto a la izquierda de la flecha por las de la derecha.

Beaker -> Felix
Pants -> Ace
Quijote -> Quesada
3 -> 5551
Beaker
Quijote
Pants
Smarty
Beaker
Pants
Quijote
Smarty
3

Solución

En Find what: introducimos cada cadena de texto entre paréntesis y separada por |:

(Beaker)|(Smarty)|(Quijote)
En Replace with introducimos cada cadena de texto entre paréntesis, precedida de ? y del número del orden de la sustitución(entre corchetes en el caso de que reemplacemos un número):

(?1Felix)(?2Ace)(?3Quesada)(?{4}5551)
Nos aseguramos de que está marcada la opción Regular expression. Situamos el cursor al inicio del documento y presionamos Replace All.

Resultado

Felix
Quesada
Pants
Ace
Felix
Pants
Quesada
Ace
5551

Entradas relacionadas

2017-08-03

Añadir un cuadro de texto a un gráfico en R

Title

Problema

Queremos añadir un cuadro de texto a un gráfico en R. A continuación, podemos ver una primera solución, pero el código es demasiado verboso y alambicado.

# Un gráfico
plot(x = runif(1000), y = runif(1000), type = "p", pch = 16, col = "#40404050")

## Parámetros para el texto
myText <- "some Text"
posCoordsVec <- c(0.5, 0.5)
cex <- 2

# Rectángulo
textHeight <- graphics::strheight(myText, cex = cex)
textWidth <- graphics::strwidth(myText, cex = cex)
pad <- textHeight*0.3
rect(xleft = posCoordsVec[1] - textWidth/2 - pad, 
        ybottom = posCoordsVec[2] - textHeight/2 - pad, 
        xright = posCoordsVec[1] + textWidth/2 + pad, 
        ytop = posCoordsVec[2] + textHeight/2 + pad,
        col = "lightblue", border = NA)

# Ubicación del texto
text(posCoordsVec[1], posCoordsVec[2], myText, cex = cex)

Solución

  • Base graphics
  • Empleamos la función legend, con el mismo color en los bordes y relleno que en la solución inicial, y ajustamos el texto en el interior con el argumento adj.

    plot(x = runif(1000), y = runif(1000), type = "p", pch = 16, col = "#40404050")
    legend(0.4, 0.5, "Some text", box.col = "lightblue", bg = "lightblue", adj = 0.2)
    
  • ggpplot2
  • Con ggplot2 usamos la función geom_label. A diferencia de legend en base graphcis, el texto se centra automáticamente dentro del cuadro, con label.size = NA eliminamos los bordes

    library(ggplot2)
    df <- data.frame(x = runif(1000), y = runif(1000))
    ggplot(data = df, aes(x = x , y = y))+ 
      geom_point(alpha = 0.2)+
      geom_label(aes(x = 0.5, y = 0.5, label = "Some text"), 
                 fill = "lightblue", label.size = NA, size = 5)
    

Referencias

Nube de datos