Curso de Introducción a R (I edición)

SevillaR
Alberto Torrejón Valenzuela
08 Mar. 2023

Lea atentamente el prospecto antes de tomar el curso…

Este es un curso introductorio en el que se repasarán conceptos básicos de programación del lenguaje R.

Si eres un usuario adelantado o pretendes serlo después de este curso, en SevillaR empezaremos dentro de poco con los TalleRes en los que podréis seguir aprendiendo de la mano de excelentes ponentes.

Diapositivas hechas con Quarto.

Opinión no popular: (ahora mismo)

rmarkdown + xaringan >>> quarto + revealjs

Organiza: SevillaR

@albertorrejval

@frod_san

@RosanaFerrero

@JeronimoCarranz
library(qrcode)
web <- qr_code("https://sevillarusers.netlify.com/")
cat("Enlace web:")
Enlace web:
plot(web)

twitter <- qr_code("https://twitter.com/_SevillaR")
cat("Enlace a Twitter:")
Enlace a Twitter:
plot(twitter)

Agenda


  • Lunes 6 de marzo de 18:00-19:30h: Primeros pasos, instalación, R base, importación/exportación de datos, etc.
  • Martes 7 de marzo de 19:30-20:30h: Dataframe vs tibble, el Tidyverse.
  • Miércoles 8 de marzo de 18:00-19:30h: Introducción a la visualización de datos.


📍 Aula TIC7, 3ª planta del CRAI Antonio de Ulloa Universidad de Sevilla (Avenida Reina Mercedes).


Enlace repositorio Github: SevillaR/CursoR

Día 1: Primeros pasos

R es muy versátil

  • Programación (estadística): library(baseR), …
  • Tratamiento, depuración, análisis de datos: library(tidyverse), …
  • Informes, páginas webs, presentaciones: library(rmarkdown), library(quarto), …
  • Visualización de datos library(ggplot), …
  • Cuadros de mando: library(shiny), …
  • Modelos de aprendizaje: library(tidymodels), …

Pero para llegar a ese punto, antes hay que pasar por… instalarlo

Proceso:

  1. Instalar R: https://www.r-project.org/
  2. Instalar R Studio IDE: https://posit.co/download/rstudio-desktop/

RStudio, nuestro amigo

Primeros pasos: directorio de trabajo, primer script, definir una variable, leer salida del script, instalar paquete, help,…

R como calculadora

3+4
[1] 7
log(10)
[1] 2.302585
abs(-2) == abs(2)
[1] TRUE
6<5
[1] FALSE
x <- 3+4  
x  
[1] 7
y = 2+6
y
[1] 8
x+y
[1] 15
z <- c(x,y)
z
[1] 7 8
mean(z)
[1] 7.5
w <- mean(z)
w
[1] 7.5
round(w, digits=0)
[1] 8

Vectores

v1 <- 1:5
v2 <- c(2,3,4,5,6,5,5,5,4,3,2,2)
length(v1)
[1] 5
length(v2)
[1] 12
# Acceder a elementos del vector
v1[1];v1[length(v1)]
[1] 1
[1] 5
v2[1];v2[length(v2)]
[1] 2
[1] 2
# min, max, range, mean...
v3 <- c(2,3,4,5,6,5,5,5,4,3,2,2)
max(v3)
[1] 6
which.max(v3)
[1] 5
min(v3)
[1] 2
which.min(v3)
[1] 1
which(v1<3)
[1] 1 2
summary(v3)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  2.000   2.750   4.000   3.833   5.000   6.000 

Tipos de elementos

Cuando trabajamos con vectores solo podemos concatenar elementos del mismo tipo. Los elementos más comunes son:

numeric, integer, character, logical
x <- c(1,2,3,4)    
class(x)   
[1] "numeric"
y <- c(1L,2L,3L)   
class(y)
[1] "integer"
z <- c("a","b")
class(z)
[1] "character"
w <- c(TRUE, F) 
class(w) 
[1] "logical"
# Existen otros
t <- c(1+2i, 1+3i)
class(t)
[1] "complex"
# Cuidado, si combinamos R lo convierte todo a la clase más general
o <- c(1,"a",T)
o
[1] "1"    "a"    "TRUE"
class(o) 
[1] "character"

Factores

Variable númerica vs variable de caracteres vs variable factor
v1 <- c(2,3,4,5,6,5,5,5,4,3,2,2)
f1 <- factor(v1);f1
 [1] 2 3 4 5 6 5 5 5 4 3 2 2
Levels: 2 3 4 5 6
f2 <- factor(c(rep("T",5),rep("F",7),rep("NS/NC",3))); f2
 [1] T     T     T     T     T     F     F     F     F     F     F     F    
[13] NS/NC NS/NC NS/NC
Levels: F NS/NC T
f2 <- factor(c(rep("T",5),rep("F",7),rep("NS/NC",3)), 
             levels = c("Si","No","A lo mejor")); f2 
 [1] <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
Levels: Si No A lo mejor
f2 <- factor(c(rep("T",5),rep("F",7),rep("NS/NC",3)), 
             labels = c("Si","No","A lo mejor")); f2
 [1] A lo mejor A lo mejor A lo mejor A lo mejor A lo mejor Si        
 [7] Si         Si         Si         Si         Si         Si        
[13] No         No         No        
Levels: Si No A lo mejor
f2 <- factor(c(rep("T",5),rep("F",7),rep("NS/NC",3)), 
             levels = c("T","F", "NS/NC"),
             labels = c("Si","No","A lo mejor")); f2
 [1] Si         Si         Si         Si         Si         No        
 [7] No         No         No         No         No         No        
[13] A lo mejor A lo mejor A lo mejor
Levels: Si No A lo mejor
table(f2)
f2
        Si         No A lo mejor 
         5          7          3 

Factores

# ?cut
num <- c(10, 0, 4, 8, 5, 22)
interv <- cut(num, breaks = c(0, 5, 10, 30), right=F); interv
[1] [10,30) [0,5)   [0,5)   [5,10)  [5,10)  [10,30)
Levels: [0,5) [5,10) [10,30)
interv <- cut(num, breaks = 4); interv
[1] (5.5,11]     (-0.022,5.5] (-0.022,5.5] (5.5,11]     (-0.022,5.5]
[6] (16.5,22]   
Levels: (-0.022,5.5] (5.5,11] (11,16.5] (16.5,22]
interv <- cut(num, breaks = 4, include.lowest = TRUE); interv
[1] (5.5,11]     [-0.022,5.5] [-0.022,5.5] (5.5,11]     [-0.022,5.5]
[6] (16.5,22]   
Levels: [-0.022,5.5] (5.5,11] (11,16.5] (16.5,22]
interv <- cut(num, breaks = c(0, 5, 10, 30), order=T,
              labels = c("Poco","Bastante","Mucho")) ; interv
[1] Bastante <NA>     Poco     Bastante Poco     Mucho   
Levels: Poco < Bastante < Mucho
interv <- cut(num, breaks = c(0, 5, 10, 30), order=T,
              labels = c("Poco","Bastante","Mucho"), 
              include.lowest = TRUE) ; interv
[1] Bastante Poco     Poco     Bastante Poco     Mucho   
Levels: Poco < Bastante < Mucho
which("Poco" < interv )
[1] 1 4 6


Factores

v1 <- factor( c(2,3,4,5,6,5,5,5,4,3,2,2) )
v2 <- factor( c(1:6,1:6) )
table(v1,v2)
   v2
v1  1 2 3 4 5 6
  2 1 0 0 0 1 1
  3 0 1 0 1 0 0
  4 0 0 2 0 0 0
  5 1 1 0 1 0 1
  6 0 0 0 0 1 0

fc <- factor(c("Muchos", "Pocos", "Pocos", "Bastantes"),
             levels = c("Pocos", "Bastantes", "Muchos"),
             ordered = TRUE) ; fc
[1] Muchos    Pocos     Pocos     Bastantes
Levels: Pocos < Bastantes < Muchos
ordered(c("Muchos", "Pocos", "Pocos", "Bastantes"),
        levels = c("Pocos", "Bastantes", "Muchos"))
[1] Muchos    Pocos     Pocos     Bastantes
Levels: Pocos < Bastantes < Muchos
sum(fc < "Muchos")
[1] 3

Muchos otros tipos de objetos

  • matrix()
  • list()
  • function(){}
    • if(){}
    • for(){}
    • while(){}
  • data.frame() ó tibble()

Importación de datos

Dos formas:

  • Usando RStudio (no aconsejable, no automatizable)
  • Llamando a funciones de lectura desde el script

Ejemplo

Datos IPC obtenidos del INE
Grupos ECOICOP Tipo de dato Periodo Total
Índice general Índice 2023M01 109668
Índice general Índice 2022M12 109899
Índice general Índice 2022M11 109734
Índice general Índice 2022M10 109866
Índice general Índice 2022M09 109498
Índice general Índice 2022M08 110265
https://www.ine.es/index.htm

Importación de datos

Importación de datos

# install.packages("readr")
library(readr)
IPC <- read_delim("ipc.csv", delim = ";",
    col_types = cols(
      `Grupos ECOICOP` = col_character(), 
      `Tipo de dato`   = col_character(), 
      Periodo          = col_character(), 
      Total            = col_number()))
IPC
# A tibble: 13,208 × 4
   `Grupos ECOICOP` `Tipo de dato` Periodo  Total
   <chr>            <chr>          <chr>    <dbl>
 1 Índice general   Índice         2023M02     NA
 2 Índice general   Índice         2023M01 109668
 3 Índice general   Índice         2022M12 109899
 4 Índice general   Índice         2022M11 109734
 5 Índice general   Índice         2022M10 109866
 6 Índice general   Índice         2022M09 109498
 7 Índice general   Índice         2022M08 110265
 8 Índice general   Índice         2022M07 109986
 9 Índice general   Índice         2022M06 110267
10 Índice general   Índice         2022M05 108262
# … with 13,198 more rows

Suficiente por hoy



@SevillaR_

Día 2: ¿Cansado de las hojas de cálculo?

Etapas del análisis de datos

R for Data Science

Etapas del análisis de datos

R for Data Science

Mundo Tidyverse, mundo ordenado

tidyverse.org

Datos ordenados

R for Data Science

data.frame()

altura <- c(150, 135, 210, 140)
peso   <- c(65, 61, 100, 65)
sexo   <- c("F", "F", "M", "F")
datos.muestra <- data.frame(altura, peso, sexo)
datos.muestra
  altura peso sexo
1    150   65    F
2    135   61    F
3    210  100    M
4    140   65    F
nrow(datos.muestra)
[1] 4
ncol(datos.muestra)
[1] 3
length(datos.muestra$altura)
[1] 4
datos.muestra$altura
[1] 150 135 210 140
datos.muestra[,"altura"]
[1] 150 135 210 140
datos.muestra[,1]
[1] 150 135 210 140
names(datos.muestra) 
[1] "altura" "peso"   "sexo"  
colnames(datos.muestra)
[1] "altura" "peso"   "sexo"  

data.frame()

rownames(datos.muestra) <- c("Marta", "Inés", "Juan", "Carmen")
datos.muestra
       altura peso sexo
Marta     150   65    F
Inés      135   61    F
Juan      210  100    M
Carmen    140   65    F
datos.muestra["Juan", "altura"] <- 205
datos.muestra
       altura peso sexo
Marta     150   65    F
Inés      135   61    F
Juan      205  100    M
Carmen    140   65    F
df <- datos.muestra[,-3]
df
       altura peso
Marta     150   65
Inés      135   61
Juan      205  100
Carmen    140   65
# Medias
apply(df, 2, mean) 
altura   peso 
157.50  72.75 
# admite cualquier función
# IMC
apply(df, 1, function(ind){ind["peso"]/(ind["altura"]/100)^2})
   Marta     Inés     Juan   Carmen 
28.88889 33.47051 23.79536 33.16327 

Encadenar operaciones con el operador tubería (pipe)

x %>% f(y) \(\equiv\) f(x,y)
NUEVOS DATOS <- ANTIGUOS DATOS %>%
  select( VARS ) %>%
  filter( CONDICIÓN ) %>%
  slice( POSICIÓN ) %>%
  mutate( VARS NUEVAS) %>%
  group_by( VARS ) %>%
  summarise( NUEVAS VARS GROUP ) %>%
  arrange( VARS ) %>%
  count( VARS )

Ejemplo películas más valoradas según imDB

Enlace al dataset:

https://www.kaggle.com/datasets/georgescutelnicu/top-100-popular-movies-from-2003-to-2022-imdb
library(tidyverse)
movies <- read_csv("movies.csv")
names(movies)
 [1] "Title"             "Rating"            "Year"             
 [4] "Month"             "Certificate"       "Runtime"          
 [7] "Directors"         "Stars"             "Genre"            
[10] "Filming_location"  "Budget"            "Income"           
[13] "Country_of_origin"
movies_nuestro <- movies %>% 
  select(Title, Rating, Year, Runtime, Filming_location, Budget, Income)
movies_nuestro %>% head()
# A tibble: 6 × 7
  Title                          Rating  Year Runtime Filming_lo…¹ Budget Income
  <chr>                           <dbl> <dbl> <chr>   <chr>        <chr>  <chr> 
1 Avatar: The Way of Water          7.8  2022 192     New Zealand  $350,… $2,26…
2 Guillermo del Toro's Pinocchio    7.6  2022 117     USA          $35,0… $108,…
3 Bullet Train                      7.3  2022 127     Japan        $85,9… $239,…
4 The Banshees of Inisherin         7.8  2022 114     Ireland      Unkno… $19,7…
5 M3gan                             6.4  2022 102     New Zealand  $12,0… $171,…
6 Emancipation                      6.1  2022 132     Unknown      $120,… Unkno…
# … with abbreviated variable name ¹​Filming_location

Ejemplo películas más valoradas según imDB

library(skimr)
movies_nuestro %>% skim()  
Data summary
Name Piped data
Number of rows 2000
Number of columns 7
_______________________
Column type frequency:
character 5
numeric 2
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
Title 0 1 1 62 0 1989 0
Runtime 0 1 2 7 0 113 0
Filming_location 0 1 2 29 0 97 0
Budget 0 1 3 15 0 305 0
Income 0 1 4 14 0 1856 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
Rating 1 1 6.67 0.91 1.9 6.15 6.7 7.30 9.6 ▁▁▆▇▁
Year 0 1 2012.50 5.77 2003.0 2007.75 2012.5 2017.25 2022.0 ▇▇▇▇▇

Tranformación de datos

Cuidado: Runtime, budget, income son caracteres

movies_nuestro %>% 
  mutate(Runtime = as.numeric(Runtime), Budget  = as.numeric(Budget), Income  = as.numeric(Income))
# A tibble: 2,000 × 7
   Title                          Rating  Year Runtime Filming_l…¹ Budget Income
   <chr>                           <dbl> <dbl>   <dbl> <chr>        <dbl>  <dbl>
 1 Avatar: The Way of Water          7.8  2022     192 New Zealand     NA     NA
 2 Guillermo del Toro's Pinocchio    7.6  2022     117 USA             NA     NA
 3 Bullet Train                      7.3  2022     127 Japan           NA     NA
 4 The Banshees of Inisherin         7.8  2022     114 Ireland         NA     NA
 5 M3gan                             6.4  2022     102 New Zealand     NA     NA
 6 Emancipation                      6.1  2022     132 Unknown         NA     NA
 7 Amsterdam                         6.1  2022     134 USA             NA     NA
 8 Violent Night                     6.9  2022     112 Canada          NA     NA
 9 The Whale                         7.8  2022     117 USA             NA     NA
10 The Fabelmans                     7.6  2022     151 USA             NA     NA
# … with 1,990 more rows, and abbreviated variable name ¹​Filming_location
# problemas porque mezcla caracteres con números
movies_nuestro <- movies_nuestro %>% 
  mutate(Runtime = extract_numeric(Runtime), Budget  = extract_numeric(Budget), Income  = extract_numeric(Income))
movies_nuestro
# A tibble: 2,000 × 7
   Title                          Rating  Year Runtime Filming…¹  Budget  Income
   <chr>                           <dbl> <dbl>   <dbl> <chr>       <dbl>   <dbl>
 1 Avatar: The Way of Water          7.8  2022     192 New Zeal…  3.5 e8  2.27e9
 2 Guillermo del Toro's Pinocchio    7.6  2022     117 USA        3.5 e7  1.09e5
 3 Bullet Train                      7.3  2022     127 Japan      8.59e7  2.39e8
 4 The Banshees of Inisherin         7.8  2022     114 Ireland   NA       1.97e7
 5 M3gan                             6.4  2022     102 New Zeal…  1.2 e7  1.71e8
 6 Emancipation                      6.1  2022     132 Unknown    1.2 e8 NA     
 7 Amsterdam                         6.1  2022     134 USA        8   e7  3.12e7
 8 Violent Night                     6.9  2022     112 Canada     2   e7  5.96e7
 9 The Whale                         7.8  2022     117 USA        1   e7  3.11e7
10 The Fabelmans                     7.6  2022     151 USA        4   e7  9.50e6
# … with 1,990 more rows, and abbreviated variable name ¹​Filming_location

Películas suspensas y aprobadas

movies_nuestro %>% 
  filter( Rating >= 5) %>% 
  count()
# A tibble: 1 × 1
      n
  <int>
1  1931
movies_nuestro %>% 
  filter( Rating < 5) %>% 
  count()
# A tibble: 1 × 1
      n
  <int>
1    68
movies_nuestro %>% 
  filter( Rating < 5) %>% 
  arrange( Rating )
# A tibble: 68 × 7
   Title                Rating  Year Runtime Filming_location    Budget   Income
   <chr>                 <dbl> <dbl>   <dbl> <chr>                <dbl>    <dbl>
 1 Disaster Movie          1.9  2008      87 USA               20000000 34816824
 2 Mantus                  2.1  2014      NA USA                 250000       NA
 3 Son of the Mask         2.2  2005      94 Australia         84000000 59981548
 4 Epic Movie              2.4  2007      86 USA               20000000 87238158
 5 Dragonball Evolution    2.6  2009      85 Mexico            30000000 55720772
 6 Cats                    2.8  2019     110 UK                95000000 75558925
 7 Meet the Spartans       2.8  2008      87 USA               30000000 85897593
 8 365 Days                3.3  2020     114 Poland                  NA  9458590
 9 Picture of Beauty       3.4  2017      70 Poland              100000       NA
10 Catwoman                3.4  2004     104 USA              100000000 82102379
# … with 58 more rows

¿Películas con mayor beneficio?

movies_nuestro %>% 
  drop_na() %>% 
  mutate(Benefit = Income - Budget) %>% 
  arrange( desc(Benefit) ) %>% 
  select(Title, Rating, Benefit)
# A tibble: 1,651 × 3
   Title                                      Rating    Benefit
   <chr>                                       <dbl>      <dbl>
 1 Avatar                                        7.8 2685917914
 2 Avengers: Endgame                             8.4 2441501328
 3 Avatar: The Way of Water                      7.8 1917946983
 4 Star Wars: Episode VII - The Force Awakens    7.8 1824521700
 5 Avengers: Infinity War                        8.4 1727359754
 6 Spider-Man: No Way Home                       8.3 1717430023
 7 Jurassic World                                6.9 1521537444
 8 The Lion King                                 6.8 1403250487
 9 Furious 7                                     7.1 1325341399
10 Top Gun: Maverick                             8.4 1318732821
# … with 1,641 more rows

¿Número de pelícuas y duración media de las películas por año?

movies_nuestro %>% 
  drop_na() %>% 
  group_by(Year) %>% 
  summarise(mean_Runtime  = mean(Runtime),
            number_movies = n() )
# A tibble: 20 × 3
    Year mean_Runtime number_movies
   <dbl>        <dbl>         <int>
 1  2003         112.            93
 2  2004         111.            98
 3  2005         112.            94
 4  2006         112.            92
 5  2007         113.            88
 6  2008         108.            96
 7  2009         113.            93
 8  2010         109.            91
 9  2011         112.            92
10  2012         113.            95
11  2013         115.            94
12  2014         115.            89
13  2015         117.            87
14  2016         116.            91
15  2017         118.            77
16  2018         120.            76
17  2019         122.            74
18  2020         109.            32
19  2021         125.            50
20  2022         130.            49

Suficiente por hoy



@SevillaR_

Día 3: Que bonito que se ve

Visualización de datos

Dos filosofías:

  • plot() de library(baseR)
  • ggplot() de library(ggplot2)

plot(x,y)

  • x: las coordenadas x de los puntos en la gráfica.
  • y: las coordenadas y de los puntos en la gráfica, opcional si x es una estructura apropiada.

Argumentos que se pasarán a métodos como parámetros gráficos

Muchos métodos aceptarán los siguientes argumentos:

  • type: qué tipo de trama se debe dibujar. Los posibles tipos son:
    • "p" para puntos
    • "l" para líneas
    • "b" para ambos
    • "c" para las líneas que solo forman parte de "b"
    • "o" para ambos superpuestos
    • "h" para histograma como líneas verticales (o “alta densidad”)
    • "s" para escalones
    • "S" para otros pasos
    • "n" para no trazar
  • main: un título general para el gráfico
  • sub: un subtítulo para el gráfico
  • xlab: un título para el eje x
  • ylab: un título para el eje y

Controlar el layout:

par(mfrow = c(1,2))

plot...

par(mfrow = c(1,1))

Ejemplo plot()

Datos pressure

pressure %>% summary()
  temperature     pressure       
 Min.   :  0   Min.   :  0.0002  
 1st Qu.: 90   1st Qu.:  0.1800  
 Median :180   Median :  8.8000  
 Mean   :180   Mean   :124.3367  
 3rd Qu.:270   3rd Qu.:126.5000  
 Max.   :360   Max.   :806.0000  


plot(x = pressure$temperature, y = pressure$pressure)

pairs(pressure)

Datos pressure

plot(pressure, 
     pch=21, 
     col="blue", 
     bg="lightblue")

Datos pressure

plot(pressure, type = "b", ylim=c(-50,600), xlim=c(0,500), bty  = "n",
     xlab = "Temperatura (Cº)", ylab = "Presión (mm)",
     main = "Presión de vapor del Mercurio",)
grid()
abline(h= 247, v=300, col="red", lty=2)
text(pressure, labels=1:nrow(pressure), cex=0.6, pos=1, col="blue")

ggplot()

Los elementos necesarios para representar un gráfico con ggplot son los siguientes:

  • Un tibble que contiene los datos que se quieren visualizar.
  • Los aesthetics, es decir, una lista de relaciones entre las variables del fichero de datos y determinados aspectos del gráfico (como por ejemplo coordenadas, formas o colores).
    • coordenadas (x e y)
    • color exterior (color)
    • color de relleno (fill)
    • forma de puntos (shape)
    • tipo de línea (linetype)
    • tamaño (size)
  • Los geoms, que especifican los elementos geométricos (puntos, líneas, círculos,…) que se van a representar.
    • geom_point (para puntos)
    • geom_lines (para lineas)
    • geom_histogram (para histograma)
    • geom_boxplot (para boxplot)
    • geom_bar (para barras)
    • geom_smooth (líneas suavizadas)
    • geom_polygons (para polígonos en un mapa)
    • etc. (si ejecutáis el comando help.search("geom_", package = "ggplot2") podéis ver el listado de objetos geométricos)

Nuevos elementos se van añadiendo de forma consecutiva en distintas capas (layers). Para añadir una nueva capa se usa el signo +.

La estructura general del código para obtener un gráfico es la siguiente:

 ggplot(data = DATOS, aes()) +
 geom_nombre(aes(aesthetics1=var1, aesthetics2=var2, ...)) +
 geom_nombre(...)
Ejemplos con código: R Graph gallery

Ejemplo ggplot()

Datos pressure

pressure %>% 
  ggplot(aes(x=temperature, y=pressure)) +
  geom_point() + geom_line() + 
  theme_light()

Datos pressure

# install.packages("hrbrthemes")
library(hrbrthemes)
pressure %>% 
  ggplot(aes(x=temperature, y=pressure)) +
  geom_line(color="grey") +
  geom_point(shape=21, color="black", fill="#69b3a2", size=3) +
  theme_ipsum() + labs(title = "Presión del vapor de Mercurio",
       x = "Temperatura (Cº)",
       y = "Presión (mm)") 

¿Qué ciudades españolas te gustaría visitar?

Enlace a cuestionario: ¿Qué ciudades españolas te gustaría visitar?

Preferencias de ciudades españolas

Importación de datos

ciudades <- read_csv("ciudades.csv")
ciudades %>% head()
# A tibble: 6 × 13
  Timestamp      Ciuda…¹ Ciuda…² Ciuda…³ Ciuda…⁴ Ciuda…⁵ Ciuda…⁶ Ciuda…⁷ Ciuda…⁸
  <chr>          <chr>   <chr>   <chr>   <chr>   <chr>   <chr>   <chr>   <chr>  
1 3/7/2023 15:0… Sevilla Cadiz   Madrid  Barcel… San Se… Almeria Malaga  Santia…
2 3/7/2023 20:4… Asturi… Zurgena Yeles   Viveiro Vicedo  Vegadeo Valver… Vallde…
3 3/7/2023 20:5… Valenc… Barcel… San Se… Segovia Santia… Toledo  Salama… Asturi…
4 3/7/2023 21:3… La Cor… Huesca  Baiona  San Se… Ecija   Sahagun Salama… Merida 
5 3/7/2023 23:1… Salama… Malaga  Sevilla Cadiz   Huesca  Zarago… Oviedo  Santia…
6 3/8/2023 3:57… Madrid  Barcel… Sevilla Mallor… Teneri… Valenc… Ibiza   Granada
# … with 4 more variables: `Ciudad 9` <chr>, `Ciudad 10` <chr>,
#   `Ciudad 11` <chr>, `Ciudad 12` <chr>, and abbreviated variable names
#   ¹​`Ciudad 1`, ²​`Ciudad 2`, ³​`Ciudad 3`, ⁴​`Ciudad 4`, ⁵​`Ciudad 5`,
#   ⁶​`Ciudad 6`, ⁷​`Ciudad 7`, ⁸​`Ciudad 8`
ciudades %>% summary()
  Timestamp           Ciudad 1           Ciudad 2           Ciudad 3        
 Length:7           Length:7           Length:7           Length:7          
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
   Ciudad 4           Ciudad 5           Ciudad 6           Ciudad 7        
 Length:7           Length:7           Length:7           Length:7          
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
   Ciudad 8           Ciudad 9          Ciudad 10          Ciudad 11        
 Length:7           Length:7           Length:7           Length:7          
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
  Ciudad 12        
 Length:7          
 Class :character  
 Mode  :character  

Preferencias de ciudades españolas

Transformación de datos

library(janitor) #para clean_names()
preferencia_ciudades <- ciudades %>%
  select(-Timestamp) %>% 
  mutate(ID = 1:nrow(ciudades)) %>% 
  clean_names() %>% 
  pivot_longer(starts_with("ciudad")) %>% 
  mutate(puntos = rep(12:1, nrow(ciudades))) %>% 
  group_by(value) %>% 
  summarise(total = sum(puntos)) %>% 
  arrange(desc(total))
preferencia_ciudades
# A tibble: 54 × 2
   value                  total
   <chr>                  <int>
 1 Sevilla                   41
 2 Barcelona                 34
 3 Cadiz                     31
 4 Malaga                    29
 5 Madrid                    24
 6 Salamanca                 24
 7 Santiago de Compostela    21
 8 Huesca                    19
 9 Valencia                  19
10 Asturias                  17
# … with 44 more rows

Preferencias de ciudades españolas

Visualización de los datos


color_barra_in  <- "orange"
color_barra_out <- "red"
preferencia_ciudades %>%
  ggplot() +
  geom_col(aes(total, value), 
    fill  = color_barra_in, 
    color = color_barra_out,
    width = 0.5)

Preferencias de ciudades españolas

Filtrar ciudades y ordenar las barras


library(forcats)
preferencia_ciudades %>%
  filter(total>10) %>% 
  ggplot() +
  geom_col(
    aes(total, 
        fct_reorder(value, total, 
                    .desc = FALSE)), 
          fill  = color_barra_in, 
          color = color_barra_out,
          width = 0.5) +
  labs(
    title = "Preferencias de ciudades por puntuación",
    subtitle = "1 a 12 puntos",
    x = "Puntos",
    y = "Ciudad") +
  theme_minimal()

Y muchas más visualizaciones…



Muchas gracias a todos



library(qrcode)
telegram <- qr_code("https://t.me/+HE3IBL13swTfZwYI")
cat("Enlace grupo de Telegram:")
Enlace grupo de Telegram:
plot(telegram)

meetup <- qr_code("https://www.meetup.com/es-ES/Sevilla-R-users/?_locale=es-ES")
cat("Enlace grupo de Meetup:")
Enlace grupo de Meetup:
plot(meetup)