Visualización de datos en R - Fundación Sadosky ... · Visualización de datos en R Ernesto...

Preview:

Citation preview

Visualización de datos en RErnesto Mislej

December 12, 2016

Previously. . .

Para los que vienen hoy :) este taller está basado en R, si no lo tienen instalado, descarguenlo desde acá:http://cran.r-project.org

También les recomiendo instalar RStudio, el sitio de descarga es: http://rstudio.com

Continuaremos con el dataset breast-cancer que estuvimos trabajando la semana pasada. Recordemos queestuvimos realizando algunas transformaciones sobre el dataset crudo, así como lo descargamos, para podertrabajarlo en R. Lo fuimos trabajando y lo guardamos en el file datos_limpios_1.RDS. Lo levantamos paraverlo. . .df1 <- readRDS("datos_limpios_1.RDS")

dim(df1)

## [1] 286 10str(df1)

## 'data.frame': 286 obs. of 10 variables:## $ edad : num 3 4 4 3 3 4 4 3 3 3 ...## $ menopausia : Factor w/ 3 levels "ge40","lt40",..: 3 1 1 3 3 3 1 3 3 1 ...## $ tamano : num 17 17 37 37 32 27 42 12 2 42 ...## $ nodulos : num 1 1 1 1 4 4 1 1 1 16 ...## $ capsula : logi TRUE FALSE FALSE TRUE TRUE FALSE ...## $ grado : int 3 1 2 3 2 2 3 2 2 2 ...## $ mama : Factor w/ 2 levels "left","right": 2 2 1 2 1 2 1 1 2 2 ...## $ cuadrante : Factor w/ 5 levels "central","left_low",..: 3 1 2 2 5 3 3 3 4 3 ...## $ radiot : logi FALSE FALSE FALSE TRUE FALSE TRUE ...## $ recurrencia: logi TRUE FALSE TRUE FALSE TRUE FALSE ...

Gráficos básicos

Veamos cómo hacer un histograma de una varible numérica como es el tamaño.hist(df1$tamano)

1

Histogram of df1$tamano

df1$tamano

Fre

quen

cy

0 10 20 30 40 50

010

2030

4050

60

Flojito. . .

Llegaremos?

Mi intención es lograr reproducir gráficas complejas (o no tanto) como la siguiente

Sobre ggplot2

Nos centraremos en el uso de la librería ggplot2.install.packages("ggplot2")

ggplot2 es una librería gráfica montada sobre R.

Toma como referencia una metodología de visualización de datos llamada The Grammar of Graphics,(Wilkinson, 2005), vamos a verla a medida que presentemos los ejemplos. La idea es describir los mapeosvisuales para poder armar visualizaciones complejas sin preocuparnos por la parte dificil.

Algunas ventajas:

• consistente con la metodología grammar of graphics• permite especificar los gráficos con un nivel alto de abstracción• sumamente flexible• mantiene una estética elegante y profesional• cuenta con una gran comunidad de usuarios y muy activa

Por otro lado, con ggplot2 no podremos

• realizar gráficas en 3D (odio los gráficos en 3D, me parecen horribles y muy fácilmente caés en problemasde ocultamiento)

• grafos, metáfora de nodos y aristas

2

Figure 1:

• gráficos interactivos

En qué consiste The Grammar Of Graphics?

La idea básica consiste en especificar de manera independiente las componentes del gráfico, como si fuesenbloques y luego combinarlas. Las componenetes que define The Grammar Of Graphics son:

• los datos (obvio! sin ellos no somos nada)• los mapeos estéticos (ejes, posición, colores, tamaños, etc.)• objetos (como el caso de los boxplots. . . )• transformaciones (log, sqrt, exp)• escalas• sistema de coordenadas (cartesianas, polares)• facetado (muy útil para sumar variables al análisis)

La estructura del ggplot

La función ggplot() se usa para inicializar la estructura básica de los gráficos. Se ve algo así:ggplot(data = <default data set>,

aes(x = <default x axis variable>,y = <default y axis variable>,... <other default aesthetic mappings>),

... <other plot defaults>) +

3

Figure 2:

geom_<geom type>(aes(size = <size variable for this geom>,... <other aesthetic mappings>),

data = <data for this point geom>,stat = <statistic string or function>,position = <position string or function>,color = <"fixed color specification">,<other arguments, possibly passed to the _stat_ function) +

scale_<aesthetic>_<type>(name = <"scale label">,breaks = <where to put tick marks>,labels = <labels for tick marks>,... <other options for the scale>) +

theme(plot.background = element_rect(fill = "gray"),... <other theme elements>)

No teman!

(Espero) Se va a entender a medida que vayamos transcurriendo el taller. Además existe una manera máscómoda de especificar las componentes de los gráficos y es utilizando el operador +.

ggplot2 vs. la librería básica de R

Comparada con la librería básica de R, el ggplot2:

• es más dificil para gráficas enlatadas

4

• es más simple para gráficas complejas• los datos tienen que estar siempre en dataframes

Versión R:hist(df1$tamano)

Histogram of df1$tamano

df1$tamano

Fre

quen

cy

0 10 20 30 40 50

010

2030

4050

60

Versión ggplot2:library(ggplot2)ggplot(df1, aes(x = tamano)) +

geom_histogram()

## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

5

0

20

40

60

0 10 20 30 40 50

tamano

coun

t

La librería básica es un poco más simple (aunque más fea)

Veamos un gráfico más complejo:plot(tamano ~ edad,

col="black",data=subset(df1,recurrencia))

points(tamano ~ edad,col="red",data=subset(df1,!recurrencia))

6

2 3 4 5 6

010

2030

4050

edad

tam

ano

ggplot(df1, aes(x=edad, y=tamano, color=recurrencia)) +geom_point()

0

10

20

30

40

50

2 4 6

edad

tam

ano recurrencia

FALSE

TRUE

ggplot(df1, aes(x=edad, y=tamano, color=recurrencia)) +geom_point() +geom_jitter()

7

0

20

40

2 4 6

edad

tam

ano recurrencia

FALSE

TRUE

Fijensé qué fácil fue incluir la categoría recurrencia como color. Y un jitter para evitar el solapamiento

ggplot2 wins!

Aes & Geom

Las variables visuales que maneja ggplot2 son las siguientes:

• posición espacial• color• relleno• forma del objeto• tamaño• tipo de linea

No todas las variables visuales tienen sentido en todas las visualizaciones. Los mapeos visuales se describencon la función aes().

Los objetos se definen con el grupo de funciones geom_(). Los más clásicos son los siguientes:

• puntos geom_point, usados en los scatter plots.• líneas geom_line, para series de tiempo.• barras geom_bar, para gráficos de barras.• boxplot geom_boxplot, para idem!• . . .

Para ver la lista completa de objetos se puede ir a la documentación:

8

help.search("geom_", package = "ggplot2")

También comenzar a tipear geom_<tab> en el Rstudio y ver el listado.

Figure 3:

Las visualizaciones pueden tener más de una geom. Se pueden ir agregando fácilmente usando el operador +.ggplot(df1, aes(x=edad, y=tamano, color=recurrencia)) +

geom_point() +geom_jitter() +geom_smooth(method=lm)

0

20

40

2 4 6

edad

tam

ano recurrencia

FALSE

TRUE

9

Scatterplots

Los scatterplots son tipos de gráficas donde objetos serán puntos que se disponen en un diagrama de ejes.Mayormente utilizamos coordenadas cartesianas y una escala lineal, pero sabemos que podemos usar ejesradiales y escala logaritmicas, entre otros. La manera de invocar estos gráficos es mediante la funcióngeom_point; lo que obligatoriamente necesitamos es indicar cuáles son las variables que irán a los ejes x e y.

ggplot(df1, aes(x=tamano, y=nodulos)) +geom_point()

0

5

10

15

20

25

0 10 20 30 40 50

tamano

nodu

los

Líneas

ggplot nos permite sumar elementos al gráfico, como por ejemplo la línea de regresión:df1$reg_line <- predict(lm(nodulos ~ tamano, data=df1))

p1 <- ggplot(df1, aes(x=tamano, y=nodulos)) +geom_point() +geom_line(aes(y=reg_line))

p1

10

0

5

10

15

20

25

0 10 20 30 40 50

tamano

nodu

los

Smoothers

Algunos de los geom como los scatterplots tienen el problema del overplotting o solapamiento y no podemosconocer realmente la dispersión de los puntos. El método geom_smooth nos ayuda en este sentido mostrandouna cinta sobre los puntos.

p1 + geom_smooth()

## `geom_smooth()` using method = 'loess'

11

0

10

20

0 10 20 30 40 50

tamano

nodu

los

Etiquetas sobre los puntos

De esta manera se incluyen etiquetas sobre los puntos. No parece ser una buena ideap1 + geom_text(aes(label=grado))

12

31 23

22

322

2

22 1223

1

2 231

2

21

3

2

21

3

3

3

1

33 112

3

31 3

2

2

3

1 32 3 23

1

33 12

3

1

3

12

3

23

3

21 22

2

1

31

1

33

1 1 23

2

2 2 122 3 1

2

1 11

3

12 2 211 3 1

2

2 321

22

2 121 22

3

1 1

3

1

2

1 322

3

2 12222 2 232 3111 31

3

2

22

23

2

1 2

3

22

23

21 2

2

1 3

3

2

23

3

2

2

22 22

3

21

3

2

2

3

21 2

3

1

3

1 1 332 222

3

22

2

11

3

32 3311

3

2 3

3

1

3

12 12 132 12 13

2

23 13 22222 2 12 23

3

2

3

32 22122 11 1

3

2 11 33 23

2

23 1 2

2

3

2 3 311

3

3

2

2

322 2

2

23

2

2

2

2 30

5

10

15

20

25

0 10 20 30 40 50

tamano

nodu

los

Existe un paquete que (intenta) ayudarnos con este problema#install.packages("ggrepel")library("ggrepel")

p1 + geom_text_repel(aes(label=grado))

13

3

1

2

3

22

3

2

2

2

2

21

223

1

2 2

3

12

21

3

22

1

3

3

3

1

3

31

1

2 3

3

1

3

2

2

3

13

2

3

2

3

1

3

3

1

2

3

1

3

1

2

3

2

3

3

21

2

2

21

3

11

33

1

1

2

3

2

2

2

122

3

1

2

1

1

1

3

1

2

22

1

1

3

1

2

2

3

2

1

2

2

2121

2

2

3

1

1

3

1

2

1 322

3

2 122

2

2

2

2

323

11

1 3

1

3

22

2

2

3

2

12

3

2

2

23

2

1

2

2

1

3

3

2

2

3

322

2

2

2

2

3

21

3

2

2

3

2

1

2

3

13

1

1

3

3

2

2

2

2

3

22

2

1

1

3

3

2

3

3

1

1

3

2

3

3

1

3

1

2 1

2

1

3

2

12

13

2

2

313

2

2

2

22

2

1

2

2

3

3

2

33

2

2

2

1

2

2

1

1

1

3

2

1

1

3 32

3

22

31

2

2

3

2

3

3

11

3

3

2

2

3 22

2

2

2

3

22 2

2

3

0

5

10

15

20

25

0 10 20 30 40 50

tamano

nodu

los

No es un buen ejemplo. . . Pero si solo queremos marcar algún subconjunto. . .p1 +

geom_text_repel(aes(label=grado),data = subset(df1, grado==3 & edad>=5))

14

3

3

3

3 3

3

3

3 3

33

33 3

333

0

5

10

15

20

25

0 10 20 30 40 50

tamano

nodu

los

Otros mapeos visuales

Sumemos color y forma a este lío!ggplot(df1, aes(x=tamano, y=nodulos, shape=capsula, color=recurrencia)) +

geom_point() +geom_jitter()

## Warning: Removed 8 rows containing missing values (geom_point).

## Warning: Removed 8 rows containing missing values (geom_point).

15

0

5

10

15

20

25

0 20 40

tamano

nodu

los

recurrencia

FALSE

TRUE

capsula

FALSE

TRUE

NA

Ejercitación

1. Crear un scatterplot con 2 variables numéricas.

2. Incluir jitter.

3. Utilizar el color según la recurrencia.

4. Crear boxplots del tamaño según la recurrencia.

5. Sumar una nube de puntos sobre los boxplots.

6. Crear un scatterplot con 2 variables numéricas.ggplot(df1, aes(x=tamano, y=nodulos)) +

geom_point()

16

0

5

10

15

20

25

0 10 20 30 40 50

tamano

nodu

los

2. Incluir jitter.ggplot(df1, aes(x=tamano, y=nodulos)) +

geom_point() +geom_jitter()

17

0

5

10

15

20

25

0 20 40

tamano

nodu

los

3. Utilizar el color según la recurrenciaggplot(df1, aes(x=tamano, y=nodulos,color=recurrencia)) +

geom_point() +geom_jitter()

18

0

10

20

0 20 40

tamano

nodu

los recurrencia

FALSE

TRUE

4. Crear boxplots del tamaño según la recurrencia.ggplot(df1, aes(x=recurrencia, y=tamano)) +

geom_boxplot()

19

0

10

20

30

40

50

FALSE TRUE

recurrencia

tam

ano

5. Sumar una nube de puntos sobre los boxplots.ggplot(df1, aes(x=recurrencia, y=tamano)) +

geom_boxplot() +geom_point() +geom_jitter(width = 0)

20

0

20

40

FALSE TRUE

recurrencia

tam

ano

Histogramas y diagramas de densidad

Los histogramas y diagramas de densidad muestran la distribución de una sóla variable. Veamos cómo seresuelve.

ggplot(df1, aes(x=tamano)) +geom_histogram(bins=10)

21

0

20

40

60

0 20 40

tamano

coun

t

ggplot(df1, aes(x=tamano)) +geom_histogram(bins=10)

22

0

20

40

60

0 20 40

tamano

coun

t

ggplot(df1, aes(x=tamano)) +geom_density()

23

0.00

0.01

0.02

0.03

0.04

0 10 20 30 40 50

tamano

dens

ity

Facetado

Una de las transformaciones más interesantes para facilitar la comparación es el facetado. En la literaturatambién se lo conoce como mínimos múltiplos. La función a usar es facet_grid(VARIABLE ~ .)

ggplot(df1, aes(x=tamano)) +geom_histogram(bins=10) +facet_grid(. ~ recurrencia)

24

FALSE TRUE

0 20 40 0 20 40

0

10

20

30

tamano

coun

t

Transformaciones

Algunos datasets requieren que realicemos algunas transformaciones sobre las variables. Veamos cómorealizarlo, para esto usemos un dataset con estas características. El ggplot2 viene con el dataset diamondsque consiste en un :

set.seed(1410)dsmall <- diamonds[sample(nrow(diamonds), 500), ]

ggplot(dsmall, aes(x=carat, y=price)) +geom_point()

25

0

5000

10000

15000

1 2 3

carat

pric

e

La relación tiene pinta de ser exponencial, veamos cómo se ve transformando las variables.ggplot(dsmall, aes(x=log(carat), y=log(price))) +

geom_point()

26

6

7

8

9

10

−1.5 −1.0 −0.5 0.0 0.5 1.0

log(carat)

log(

pric

e)

Pero nosotros no queremos saber el log del precio, sino queremos hacer que la escala del gráfico sea logarítmica.Para eso sumamos la siguiente función. Noten el argumento labels para indicar que se trata de un precio.

ggplot(dsmall, aes(x=carat, y=price)) +geom_point() +scale_y_log10(labels = scales::dollar) +scale_x_log10("peso", breaks = 0:5, limits=c(-1,5))

## Warning in trans$transform(limits): NaNs produced

27

$1,000

$10,000

1 2 3 4 5

peso

pric

e

Y si queremos ponerle una línea de regresión? Se los dejo como ejercicio!

Referencias

• http://www.cookbook-r.com/Graphs/• http://ggplot2.org/book/qplot.pdf• http://docs.ggplot2.org/current/• http://www.ats.ucla.edu/stat/r/seminars/ggplot2_intro/ggplot2_intro.htm• https://github.com/izahn/workshops/tree/master/R/Rgraphics

28

Recommended