3/4/2018

Componentes

  • Lenguaje
  • Entorno de Desarrollo
  • Base R
  • Librerías

Bibliografía

  • R in a Nutshell:

  • \OwnCloud\sntpc\EyM\Bibliografía\R: Parte 2 (Caps 5-10)

Expresiones

Pueden ser asignaciones, condicionales o aritméticos.

x <- 1
if (x > 2) "mayor que dos" else "menor que dos"
## [1] "menor que dos"

Objetos

  • Los objetos son cosas
  • El código manipula objetos
c(1, 2, 3)
## [1] 1 2 3
"Esto es un objeto"
## [1] "Esto es un objeto"

Objetos (2)

list(c(1, 2, 3), "esto es otro objeto", "adentro de otro")
## [[1]]
## [1] 1 2 3
## 
## [[2]]
## [1] "esto es otro objeto"
## 
## [[3]]
## [1] "adentro de otro"

Símbolos y enviroment

Un environment es un conjunto de símbolos asignados a objetos.

Funciones

  • Son objetos que toman objetos como inputs (argumentos) y devuelven objetos como outputs

  • Algunas vienen predefinidas:

sum(c(1, 2, 3))
## [1] 6
  • Otras son definidas por el usuario:
sumar <- function(a, b) { a + b }
sumar(1, 2)
## [1] 3

Valores Especiales

#NA (not available/missing)
vec <- c(1, 2, 3)
vec[4]
## [1] NA
#Inf
1/0
## [1] Inf

Valores especiales (2)

#Inf
-1/0
## [1] -Inf
#NaN
Inf-Inf
## [1] NaN
#NULL

Coerción

A veces R espera un argumento de un tipo y recibe otro, trata de transformarlo.

if (2) "verdadero" else "falso"
## [1] "verdadero"

Esto puede llevar a resultados inesperados si no lo tenemos en cuenta.

Números

1.1
## [1] 1.1
2^1023
## [1] 8.988466e+307
1+2i
## [1] 1+2i
# La precisión es limitada
2^1024
## [1] Inf

Tipos

typeof(1)
## [1] "double"
typeof(1:1)
## [1] "integer"
typeof(1+1i)
## [1] "complex"

Operadores Binarios

# Suma
1+1
## [1] 2
# Coerción a `float`
10/3
## [1] 3.333333

Operadores Binarios (2)

# Integer División
10%/%3
## [1] 3
# Módulo
10 %% 3
## [1] 1
# Exponenciales
2^3
## [1] 8

Operadores Unarios

# Suma
-3
## [1] -3
!FALSE
## [1] TRUE
!4
## [1] FALSE

Tipos

La función sqrt devuelve el mismo tipo que recibe:

sqrt(-1)
## Warning in sqrt(-1): NaNs produced
## [1] NaN
sqrt(-1+0i)
## [1] 0+1i

Estructuras de control

Controlan el flujo del programa.

# Conditionals
x <- 1
if (x > 1) "algo" else "nada"
## [1] "nada"
# Conditionals (2)
x <- 1
if (x > 1) "algo" else "nada"
## [1] "nada"

¡Cuidado!

x <- 1:10
if (x %% 2 == 0) "par" else "impar" # Warning!
## Warning in if (x%%2 == 0) "par" else "impar": the condition has length > 1
## and only the first element will be used
## [1] "impar"
# Lo que quiero es esto:
x <- 1:10
ifelse(x %% 2 == 0, "par", "impar") 
##  [1] "impar" "par"   "impar" "par"   "impar" "par"   "impar" "par"  
##  [9] "impar" "par"

Condicionales

x <- 1
if (x==1) {
   "Uno"
} else if (x==2) {
   "Dos"
} else {
   "Mayor que dos"
 }
## [1] "Uno"

Condicionales

x <- "a"
switch(x,
         a="alligator",
         b="bear",
         c="camel",
         "moose")
## [1] "alligator"

Switch Vectorial

dplyr tiene una versión para vectores de switch (cuidado si tienen una versión anterior a 0.7).

suppressMessages(library(dplyr))

x <- c("a", "a", "c", "c", "b", "b", "z", "z")

case_when(x == "a" ~ "alligator",
          x == "b" ~ "bear",
          x == "c" ~ "camel",
         TRUE      ~ "moose")
## [1] "alligator" "alligator" "camel"     "camel"     "bear"      "bear"     
## [7] "moose"     "moose"

Loops

for (i in seq(from=5, to=25, by=5)) print(i)
## [1] 5
## [1] 10
## [1] 15
## [1] 20
## [1] 25

Estructuras de datos

Guardan datos y permiten acceder a la información.

x <- c(1, 2, 3, 4)
x[2]   # devuelve el elemento 2 del objeto x
## [1] 2
x[[2]] # devuelve siempre un vector de largo 1
## [1] 2

Indexando un vector

x <- c(1, 2, 3, 4)
x[2:4] # es igual a
## [1] 2 3 4
x[c(2, 3, 4)]
## [1] 2 3 4
x <- c(1, 2, 3, 4)
x[-4] # es igual a
## [1] 1 2 3

Indexando una lista

l <- list(a=1, b=2, c=3, d=4, e=5, f=6)

l[1:3]   
## $a
## [1] 1
## 
## $b
## [1] 2
## 
## $c
## [1] 3
l$a
## [1] 1

Indexando una lista (2)

l[-1]
## $b
## [1] 2
## 
## $c
## [1] 3
## 
## $d
## [1] 4
## 
## $e
## [1] 5
## 
## $f
## [1] 6

Indexar con un vector lógico

x <- c(1, 2, 3, 4)
x[c(TRUE, FALSE, TRUE, FALSE)] # me quedo solo con los impares
## [1] 1 3
x[x %% 2 != 0] # me quedo solo con los impares
## [1] 1 3

Ejercicios: Swirl

  1. Instalar swirl
install.packages("swirl")
  1. Cargar librería
library(swirl)
  1. Instalar curso
install_course_github("ifunam", "programacion-estadistica-r")
swirl()

Objetos

Todos los valores (entidades) en R son objetos de cierto tipo (o clase).

Vectores

c(.295, .300, .250, .215) # vector numérico
## [1] 0.295 0.300 0.250 0.215
# Coerción
c(.295, .300, .250, "hola!") # vector de characters
## [1] "0.295" "0.3"   "0.25"  "hola!"
# Con una lista
c(.295, .300, .250, list(.102, .303), recursive=TRUE)
## [1] 0.295 0.300 0.250 0.102 0.303

Vectores (2)

# Con una lista
c(.295, .300, .250, list(.102, .303), recursive=FALSE)
## [[1]]
## [1] 0.295
## 
## [[2]]
## [1] 0.3
## 
## [[3]]
## [1] 0.25
## 
## [[4]]
## [1] 0.102
## 
## [[5]]
## [1] 0.303

Indexando estructuras multidimensionales

Los data frames y las matrices tienen múltiples dimensiones (las listas no -> Serafín).

x <- data_frame(x=c(1, 2, 3), y=c("a","b", "c"))
x
## # A tibble: 3 x 2
##       x y    
##   <dbl> <chr>
## 1  1.00 a    
## 2  2.00 b    
## 3  3.00 c

Indexando estructuras multidimensionales (2)

# x[[]]Devuelve un  vector de largo 1
x[[2,1]] # Fila 2, Columna 1 
## [1] 2
# x[] Devuelve un objeto del mismo tipo que x (data_frame)
x[1,2] # Fila 1, Columna 2 
## # A tibble: 1 x 1
##   y    
##   <chr>
## 1 a
x[1,] # Fila 1, todas las columnas
## # A tibble: 1 x 2
##       x y    
##   <dbl> <chr>
## 1  1.00 a
x[, 2] # Todas las filas, la segunda columna 
## # A tibble: 3 x 1
##   y    
##   <chr>
## 1 a    
## 2 b    
## 3 c

No hay objetos "sueltos"

1 + 1
## [1] 2

Es lo mismo que:

c(1) + c(1)
## [1] 2

No hay objetos "sueltos" (2)

En general, nos interesa operar sobre vectores:

1:10 + 1:10
##  [1]  2  4  6  8 10 12 14 16 18 20
1:3 * 1:3
## [1] 1 4 9
sqrt(c(1, 2, 3, 4))
## [1] 1.000000 1.414214 1.732051 2.000000

Reciclando vectores

Algunos operadores "reciclan" vectores

c(1, 2, 3, 4) / 2
## [1] 0.5 1.0 1.5 2.0

Listas

Pueden ser heterogéneas.

paquete <- list(destino="Montevideo", 
                dimensiones=c(2, 6, 9), precio=12.95)
paquete$precio
## [1] 12.95
paquete[["precio"]]
## [1] 12.95
paquete["precio"] # ¿cuál es la diferencia?
## $precio
## [1] 12.95

Listas (2) - agregar elementos

z <- list(a="abc")
z
## $a
## [1] "abc"
z$c <- "hola"
z
## $a
## [1] "abc"
## 
## $c
## [1] "hola"

Listas (3)

z[[4]] <- c(28, 30)
z[[4]]
## [1] 28 30
z[5:7] <- c("uno", "dos", "tres")
z[5:7]
## [[1]]
## [1] "uno"
## 
## [[2]]
## [1] "dos"
## 
## [[3]]
## [1] "tres"

Componentes

Los nombres de los campos:

names(z)
## [1] "a" "c" ""  ""  ""  ""  ""

Convertirla a un vector (con nombres):

unlist(z)
##      a      c                                    
##  "abc" "hola"   "28"   "30"  "uno"  "dos" "tres"

Componentes (2)

class(z)
## [1] "list"
class(unlist(z))
## [1] "character"

Listas

¡Cuidado con el tamaño!

length(z)
## [1] 7

lapply

Si quiero saber el tamaño de cada elemento:

lst <- list(a=c("algo", "nada", "todo"), b=1:3, c=c(TRUE, FALSE))
lapply(lst, length)
## $a
## [1] 3
## 
## $b
## [1] 3
## 
## $c
## [1] 2

lapply (2)

Si quiero saber el tipo:

lst <- list(a=c("algo", "nada", "todo"), b=1:3, c=c(TRUE, FALSE))
lapply(lst, class)
## $a
## [1] "character"
## 
## $b
## [1] "integer"
## 
## $c
## [1] "logical"

Factores

Sirven para representar información categórica.

# Vector de characters
deptos <- c("Montevideo", "Canelones", "Montevideo", "San José",
            "Montevideo", "Montevideo", "Rivera")
typeof(deptos)
## [1] "character"

Factores (2)

Alternativa:

deptos <- factor(deptos)
levels(deptos)
## [1] "Canelones"  "Montevideo" "Rivera"     "San José"
deptos
## [1] Montevideo Canelones  Montevideo San José   Montevideo Montevideo
## [7] Rivera    
## Levels: Canelones Montevideo Rivera San José

Factores (3)

La implementación usa integers (más eficiente):

class(deptos)
## [1] "factor"

Uso la función unclass para "sacarle la clase":

deptos.int.vec <- unclass(deptos)
deptos.int.vec
## [1] 2 1 2 4 2 2 3
## attr(,"levels")
## [1] "Canelones"  "Montevideo" "Rivera"     "San José"
class(deptos.int.vec) <- "factor" # assignment?

Data Frames

Es la implementación básica de un dataset (como una planilla de Excel).

df <- data_frame(x=c(1, 2, 3), y=c("a","b", "c"))
typeof(df)
## [1] "list"

Son listas. Cada variable es un elemento de la lista.

df$x
## [1] 1 2 3

Fechas

En general vienen como texto: hay varias funciones para convertirlas de texto a fechas.

Cuando están como fechas podemos hacer cosas con ella:

  • Sacar componentes (año, mes, día)
  • Calcular períodos (entre fecha y fecha)
nac.texto <- "29/05/1984"
nac.fecha <- as.Date(nac.texto, "%d/%m/%Y")
hoy <- Sys.Date()
vida <- hoy-nac.fecha
as.numeric(vida, units="weeks") / 52 # mi edad
## [1] 33.96978

Atributos

Sirven para almacenar metadata.

m <- matrix(data=1:12, nrow=4, ncol=3,
 dimnames=list(c("r1", "r2", "r3", "r4"),
 c("c1", "c2", "c3")))
attributes(m)
## $dim
## [1] 4 3
## 
## $dimnames
## $dimnames[[1]]
## [1] "r1" "r2" "r3" "r4"
## 
## $dimnames[[2]]
## [1] "c1" "c2" "c3"
class(m)
## [1] "matrix"

Atributos (2)

dim(m) <- NULL
m
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12
class(m)
## [1] "integer"

Símbolos y environments

Los nombres de las variables son símbolos

x <- 1
class(x) # la función class evalúa su argumento antes de 
## [1] "numeric"
class(quote(x))
## [1] "name"

Environments

  • Son el contexto en el que se evalúan las expresiones.
  • Hay una tabla de correspondencia entre el símbolo y el valor

Error

Si un símbolo no está definido en el current environment, R lo busca en su "padre".

num <- 1
f <- function() {
  num
}
f()
## [1] 1

num <- 1
f <- function() {
  num <- 2
  num
}
f()
## [1] 2
num
## [1] 1

Error (2)

Si el nombre no está definido en ningun environment.

foo <- function() {
  xyz +1
}
foo() # Error
## Error in foo(): object 'xyz' not found

Error (3)

¡Esto no da error!

df <- data_frame(x=c(1, 2, 3), y = c(3, 2, 1))
mutate(df, z=x+y)
## # A tibble: 3 x 3
##       x     y     z
##   <dbl> <dbl> <dbl>
## 1  1.00  3.00  4.00
## 2  2.00  2.00  4.00
## 3  3.00  1.00  4.00

¿En qué environment se evalúa z=x+y?

Dplyr

Las funciones de dplyr evalúan sus argumentos en environments distintos que las funciones "normales".

Otros ejemplos

  • subset:

Lleva un data frame y un vector lógico como argumento.

subset(mtcars, c(TRUE, FALSE, TRUE, FALSE))
##                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4          21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Datsun 710         22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Hornet Sportabout  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Duster 360         14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Merc 230           22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Merc 280C          17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SL         17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Cadillac Fleetwood 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Chrysler Imperial  14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Honda Civic        30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Toyota Corona      21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## AMC Javelin        15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Pontiac Firebird   19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Porsche 914-2      26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Ford Pantera L     15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Maserati Bora      15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
subset(mtcars, mtcars$cyl == 6)
##                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4      21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Valiant        18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Merc 280       19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C      17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Ferrari Dino   19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
# es lo mismo que
subset(mtcars, cyl==6)
##                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4      21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Valiant        18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Merc 280       19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C      17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Ferrari Dino   19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
filter(mtcars, cyl ==6)
##    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## 1 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## 2 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## 3 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## 4 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## 5 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## 6 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## 7 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6

Otros ejemplos: lm

lm(mtcars$mpg ~ mtcars$cyl + mtcars$disp + mtcars$wt)
## 
## Call:
## lm(formula = mtcars$mpg ~ mtcars$cyl + mtcars$disp + mtcars$wt)
## 
## Coefficients:
## (Intercept)   mtcars$cyl  mtcars$disp    mtcars$wt  
##   41.107678    -1.784944     0.007473    -3.635677

# o
with(mtcars, lm(mpg ~ cyl + disp + wt))
## 
## Call:
## lm(formula = mpg ~ cyl + disp + wt)
## 
## Coefficients:
## (Intercept)          cyl         disp           wt  
##   41.107678    -1.784944     0.007473    -3.635677

Otro: lm

Especifcamos un data frame como argumento:

lm(mpg~cyl+disp+wt, data=mtcars)
## 
## Call:
## lm(formula = mpg ~ cyl + disp + wt, data = mtcars)
## 
## Coefficients:
## (Intercept)          cyl         disp           wt  
##   41.107678    -1.784944     0.007473    -3.635677

Ejercicio (2)

Una función que reemplace los NAS por valores. Por defecto los reemplaza por 0, si no por un valor.

reemplazar <- function(x, val=0) {
  x[is.na(x)] <- val
  x
}

Ejercicio

Una función que abra un archivo RDS (data_frame.RDS):

  • Si no le ponemos argumentos, abre todo.
  • Si le ponemos argumentos trae solo esas variables
## # A tibble: 10 x 2
##        a b    
##    <int> <chr>
##  1     1 a    
##  2     2 b    
##  3     3 c    
##  4     4 d    
##  5     5 e    
##  6     6 f    
##  7     7 g    
##  8     8 h    
##  9     9 i    
## 10    10 j
## # A tibble: 10 x 3
##        a b     c    
##    <int> <chr> <chr>
##  1     1 a     K    
##  2     2 b     L    
##  3     3 c     M    
##  4     4 d     N    
##  5     5 e     O    
##  6     6 f     P    
##  7     7 g     Q    
##  8     8 h     R    
##  9     9 i     S    
## 10    10 j     T