2018-08-09

Seleccionar en R las filas que no contengan ningún NA

Problema

De un data frame deseamos seleccionar aquellas filas que no contengan ningún valor NA.

df <- structure(list(i3 = c(1, 1, 1, 1, 2, 2), i2 = c(NA, 1, 1, 1, 
2, 2), i1 = c(1, NA, 2, 4, 5, 3)), class = "data.frame", row.names = c(NA, 
-6L))
  i3 i2 i1
1  1 NA  1
2  1  1 NA
3  1  1  2
4  1  1  4
5  2  2  5
6  2  2  3

Solución

df[complete.cases(df), ]
  i3 i2 i1
3  1  1  2
4  1  1  4
5  2  2  5
6  2  2  3

Referencias

2018-07-29

Obtener el valor de la última expresión evaluada en R

Problema

Queremos obtener el último valor evaluado por R. Esto es algo especialmente útil cuando el cálculo es bastante intensivo o aleatorio, no lo hemos asignado a una variable y queremos rescatarlo. Como en el siguiente ejemplo:

rnorm(10)
 [1] -0.20315303  0.92079943  0.87606177  1.15655306  0.80243882
 [6]  0.90271608  0.52740736 -0.07408704  0.15659699  0.67013587

Solución

Empleamos la función .Last.value Esta función devuelve el valor de la última expresión evaluada no ejecuta el último comando de nuevo, de ser así, en nuestro caso generaría otros 10 números aleatorios diferentes.

.Last.value
  [1] -0.20315303  0.92079943  0.87606177  1.15655306  0.80243882
 [6]  0.90271608  0.52740736 -0.07408704  0.15659699  0.67013587
Podemos asignarlo a una variable u operar con él:

resultado <- .Last.value
max(.Last.value)

Entradas relacionadas

2018-06-25

Media aritmética ponderada en R

Problema

Deseamos calcular la media ponderada de un conjunto de datos con R

Solución

Utilizamos al función weighted.mean del paquete base.

  • Ejemplo de la documentación de R
  • wt <- c(5,  5,  4,  1)/15 # No es necesario dividir entre 15
    x <- c(3.7, 3.3, 3.5, 2.8)
    xm <- weighted.mean(x, wt)
    
    [1] 3.453333
    
  • Ejemplo por grupos
  • Utilizamos el paquete dplyr y el conjunto de datos ChickWeight para calcular la media ponderada por grupo. Pondero por la variable Time a modo ilustrativo. Añado la media aritmética sin ponderar para permitir la comparación.

    library(dplyr)
    # Si queremos calcular el total
    with(ChickWeight, weighted.mean(weight, Time))
    # Por grupo
    ChickWeight %>%
      group_by(Diet) %>% 
       summarise(mean =  mean(weight), wm = weighted.mean(weight, Time)) 
    
    # A tibble: 4 x 3
      Diet   mean    wm
        
    1 1      103.  132.
    2 2      123.  159.
    3 3      143.  191.
    4 4      135.  176.
    

    Entradas relacionadas

    2018-06-18

    Mapa coroplético de España con leaflet para R

    Problema

    Crear un mapa coroplético con leaflet es muy sencillo. En nuestro ejemplo, crearemos un mapa coroplético de España con el número de habitantes por provincia. El resultado final es este:

    Solución

    1. Obtener datos espaciales
    2. Necesitamos obtener datos espaciales (df_pol, un SpatialPolygonDataFrame) para añadir los polígonos con los bordes de las regiones al mapa.

      library(leaflet)
      library(dplyr)
      library(RColorBrewer)
      
      df_pol <- readRDS("ESP_adm2.rds")
      
    3. Obtener datos poblacionales
    4. Descargamos los datos poblacionales (df_pob) para colorear el mapa. Los descargamos del INE.

      df_pob <-  read.csv2("2852sc.csv", dec = ".", stringsAsFactors = FALSE)
      
    5. Unimos ambos
    6. Antes de unir df_pol y df_pob, tenemos que manipular los nombres de las provincias, pues los nombres de ambos ficheros no coinciden (omito este paso).

      df_spain <- merge(df_pol, df_pob, by.x = 'NAME_2', by.y = 'Provincia', all.x = TRUE)
      
    7. Paleta de colores y etiquetas
    8. Creamos una paleta dividiendo la población en 5 intervalos.

      # Paleta
      bins <-  quantile(df_spain$Población, probs = c(0, 0.2, 0.4, 0.6, 0.8, 1))) 
      pal <- colorBin("YlOrRd", domain = ~ Población, bins = bins)
      # Etiquetas
      labels <- sprintf(
        "<strong>%s</strong><br/>%s Habitantes",
        df_spain@data$NAME_2,
        format(
          df_spain@data$Población,
          big.mark = ".",
          decimal.mark = ","
        )
      ) %>% lapply(htmltools::HTML)
      
    9. Creamos el mapa
    10. Añadimos todos los elementos al mapa. Centramos el mapa, añadimos el color de la paleta en función de la población, controlamos la opacidad, y finalmente añadimos la leyenda.

      
      m <- leaflet(df_spain) %>%
        setView(lng = -3.7, lat = 40.4, zoom = 06) %>%
        addTiles() %>%
        addPolygons(fillColor = ~pal(Población),
                    weight = 2,
                    opacity = 0.2,
                    color = "#FD8D3C",
                    dashArray = "3",
                    fillOpacity = 0.6,
                    highlight = highlightOptions(
                      weight = 5,
                      color = "#666",
                      dashArray = "",
                      fillOpacity = 1,
                      bringToFront = TRUE),
                    label = labels,
                    labelOptions = labelOptions(
                      style = list("font-weight" = "normal", padding = "3px 8px"),
                      textsize = "15px",
                      direction = "auto"))  %>% 
        addLegend(pal = pal,values =  ~ Población,
                  position = "bottomright",
                  opacity = 1,
                  title = "Población")
      m
      

    Entradas relacionadas

    2018-06-12

    Mostrar fechas como días de la semana en otros idiomas

    Problema

    En Excel, queremos mostrar las fechas como los días de la semana en otros idiomas.

    Solución

    • Empleamos la función TEXTO especificando el identificador de idioma correspondiente precedido de "$-".

    • =TEXTO(A2;"[$-040a]dddd")  ' Español
      =TEXTO(A2;"[$-809]dddd")    ' Inglés
      =TEXTO(A2;"[$-040c]dddd")   ' Francés
      =TEXTO(A2;"[$-407]dddd")    ' Alemán
      

    Entradas relacionadas

    Referencias

    2018-06-10

    Mostrar la fecha como el día de la semana

    Problema

    En Excel, queremos mostrar las fechas como los días de la semana.

    Solución

    1. Seleccionamos las celdas y presionamos Ctrl+1 para acceder al Formato de celdas, pestaña de Número.
    2. En la categoría Personalizada tecleamos ddd para mostrar las abreviaturas de los nombres (lun, mar, mié, etc.), o dddd para mostrar el nombre completo (lunes, martes, etc.).
    • Otra alternativa es emplear la función TEXTO.
    • =TEXTO(A1;"ddd")
      =TEXTO(A1;"dddd")
      

    Entradas relacionadas

    2018-05-19

    Muestra aleatoria estratificada proporcional en R

    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

    Nube de datos