R Base

Objetos

Se crean variables básicas (a, b, c) y se les asignan valores numéricos para usarlas posteriormente en cálculos.

a <- 1
b <- 1
c <- -1

El espacio de trabajo

Se utiliza ls() para mostrar todos los objetos (variables) que existen actualmente en la memoria de R.

ls()
## [1] "a" "b" "c"

Funciones

Se exploran funciones como log(), su ayuda (help, ?), sus argumentos (args) y distintas formas de llamarlas. También se prueban operadores básicos como suma y comparación.

log(8)
## [1] 2.079442
log(a)
## [1] 0
help("log")
?log
args(log)
## function (x, base = exp(1)) 
## NULL
log(8, base = 2)
## [1] 3
log(x = 8, base = 2)
## [1] 3
log(8,2)
## [1] 3
log(base = 2, x = 8)
## [1] 3
2^3
## [1] 8
help("+")
?"+"
help(">")
?">"

Objetos predefinidos

Se accede a datos y constantes ya incluidas en R, como pi, Inf y conjuntos de datos disponibles con data().

data()
pi
## [1] 3.141593
Inf+1
## [1] Inf

Nombres de variables

Se calculan las soluciones de una ecuación cuadrática usando variables con nombres claros (solution_1, solution_2).

solution_1 <- (-b + sqrt(b^2 - 4*a*c))/ (2*a)
solution_1
## [1] 0.618034
solution_2 <- (-b - sqrt(b^2 - 4*a*c))/ (2*a)
solution_2
## [1] -1.618034

Scripts

Se muestra cómo escribir un bloque de código completo para resolver un problema (ecuación cuadrática) paso a paso.

## Código para calcular la solución a la
## ecuación cuadrática de la forma ax^2 + bx + c
## definir las variables
a <- 3
b <- 2
c <- -1

## ahora calcule la solución
(-b + sqrt(b^2 - 4*a*c)) / (2*a)
## [1] 0.3333333

Tipos de Datos

Clases

Se usa class() para identificar el tipo de dato de una variable.

a <- 2
class(a)
## [1] "numeric"

Data frames

Se carga un dataset (murders) y se explora su estructura con funciones como str() y head().

library(dslabs)
data(murders)
class(murders)
## [1] "data.frame"
str(murders)
## 'data.frame':    51 obs. of  5 variables:
##  $ state     : chr  "Alabama" "Alaska" "Arizona" "Arkansas" ...
##  $ abb       : chr  "AL" "AK" "AZ" "AR" ...
##  $ region    : Factor w/ 4 levels "Northeast","South",..: 2 4 4 2 4 4 1 2 2 2 ...
##  $ population: num  4779736 710231 6392017 2915918 37253956 ...
##  $ total     : num  135 19 232 93 1257 ...
head(murders)
##        state abb region population total
## 1    Alabama  AL  South    4779736   135
## 2     Alaska  AK   West     710231    19
## 3    Arizona  AZ   West    6392017   232
## 4   Arkansas  AR  South    2915918    93
## 5 California  CA   West   37253956  1257
## 6   Colorado  CO   West    5029196    65

El operador de acceso: $

Permite acceder a columnas específicas de un data frame y analizar sus propiedades (tipo, longitud, etc.).

murders$population
##  [1]  4779736   710231  6392017  2915918 37253956  5029196  3574097   897934
##  [9]   601723 19687653  9920000  1360301  1567582 12830632  6483802  3046355
## [17]  2853118  4339367  4533372  1328361  5773552  6547629  9883640  5303925
## [25]  2967297  5988927   989415  1826341  2700551  1316470  8791894  2059179
## [33] 19378102  9535483   672591 11536504  3751351  3831074 12702379  1052567
## [41]  4625364   814180  6346105 25145561  2763885   625741  8001024  6724540
## [49]  1852994  5686986   563626
names(murders)
## [1] "state"      "abb"        "region"     "population" "total"
pop <- murders$population
length(pop)
## [1] 51
class(pop)
## [1] "numeric"
class(murders$state)
## [1] "character"
z <- 3 == 2
z
## [1] FALSE
class(z)
## [1] "logical"
?Comparison

Factores

Se trabaja con variables categóricas, viendo sus niveles (levels) y reordenándolos según ciertos valores.

class(murders$region)
## [1] "factor"
levels(murders$region)
## [1] "Northeast"     "South"         "North Central" "West"
region <- murders$region
value <- murders$total
region <- reorder(region, value, FUN = sum)
levels(region)
## [1] "Northeast"     "North Central" "West"          "South"

Listas

Se crean listas que pueden contener distintos tipos de datos y se accede a sus elementos.

record <- list(name = "Juan Perez",
               student_id = 1234,
               grades = c(95, 82, 91, 97, 93),
               final_grade = "A")
record
## $name
## [1] "Juan Perez"
## 
## $student_id
## [1] 1234
## 
## $grades
## [1] 95 82 91 97 93
## 
## $final_grade
## [1] "A"
class(record)
## [1] "list"
record$student_id
## [1] 1234
record[["student_id"]]
## [1] 1234
record2 <- list("Juan Perez", 1234)
record2
## [[1]]
## [1] "Juan Perez"
## 
## [[2]]
## [1] 1234
record2[[1]]
## [1] "Juan Perez"

Matrices

Se crean matrices y se aprende a acceder a sus filas, columnas y subconjuntos.

mat <- matrix(1:12, 4, 3)
mat
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
mat[2, 3]
## [1] 10
mat[2, ]
## [1]  2  6 10
mat[, 3]
## [1]  9 10 11 12
mat[, 2:3]
##      [,1] [,2]
## [1,]    5    9
## [2,]    6   10
## [3,]    7   11
## [4,]    8   12
mat[1:2, 2:3]
##      [,1] [,2]
## [1,]    5    9
## [2,]    6   10
as.data.frame(mat)
##   V1 V2 V3
## 1  1  5  9
## 2  2  6 10
## 3  3  7 11
## 4  4  8 12
data("murders")
murders[25, 1]
## [1] "Mississippi"
murders[2:3, ]
##     state abb region population total
## 2  Alaska  AK   West     710231    19
## 3 Arizona  AZ   West    6392017   232

Vectores

Se crean vectores numéricos y de texto, se asignan nombres y se analiza su estructura.

codes <- c(380, 124, 818)
codes
## [1] 380 124 818
country <- c("italy", "canada", "egypt")
country <- c('italy', 'canada', 'egypt')
country
## [1] "italy"  "canada" "egypt"
codes <- c(italy = 380, canada = 124, egypt = 818)
codes
##  italy canada  egypt 
##    380    124    818
class(codes)
## [1] "numeric"
names(codes)
## [1] "italy"  "canada" "egypt"
codes <- c("italy" = 380, "canada" = 124, "egypt" = 818)
codes
##  italy canada  egypt 
##    380    124    818
codes <- c(380, 124, 818)
country <- c("italy","canada","egypt")
names(codes) <- country
codes
##  italy canada  egypt 
##    380    124    818

Secuencias

Se generan secuencias numéricas usando seq() y el operador :.

seq(1, 10)
##  [1]  1  2  3  4  5  6  7  8  9 10
seq(1, 10, 2)
## [1] 1 3 5 7 9
1:10
##  [1]  1  2  3  4  5  6  7  8  9 10
class(1:10)
## [1] "integer"
class(seq(1, 10, 0.5))
## [1] "numeric"

Subconjuntos

Se extraen elementos específicos de vectores mediante índices o nombres.

codes[2]
## canada 
##    124
codes[c(1,3)]
## italy egypt 
##   380   818
codes[1:2]
##  italy canada 
##    380    124
codes["canada"]
## canada 
##    124
codes[c("egypt","italy")]
## egypt italy 
##   818   380

Conversión forzada

Se convierten datos de un tipo a otro (por ejemplo, de numérico a carácter).

x <- c(1, "canada", 3)
x
## [1] "1"      "canada" "3"
class(x)
## [1] "character"
x <- c(1, "canada", 3)
x <- 1:5
y <- as.character(x)
y
## [1] "1" "2" "3" "4" "5"
as.numeric(y)
## [1] 1 2 3 4 5

Not available (NA)

Se muestra cómo R maneja valores faltantes o inválidos (NA).

x <- c("1", "b", "3")
as.numeric(x)
## Warning: NAs introduced by coercion
## [1]  1 NA  3

Ordenamientos

sort

Ordena valores de menor a mayor.

library(dslabs)
data(murders)
sort(murders$total)
##  [1]    2    4    5    5    7    8   11   12   12   16   19   21   22   27   32
## [16]   36   38   53   63   65   67   84   93   93   97   97   99  111  116  118
## [31]  120  135  142  207  219  232  246  250  286  293  310  321  351  364  376
## [46]  413  457  517  669  805 1257

order

Devuelve los índices que ordenan un vector, útil para reorganizar datos.

x <- c(31, 4, 15, 92, 65)
sort(x)
## [1]  4 15 31 65 92
index <- order(x)
x[index]
## [1]  4 15 31 65 92
x
## [1] 31  4 15 92 65
order(x)
## [1] 2 3 1 5 4
murders$state[1:6]
## [1] "Alabama"    "Alaska"     "Arizona"    "Arkansas"   "California"
## [6] "Colorado"
murders$abb[1:6]
## [1] "AL" "AK" "AZ" "AR" "CA" "CO"
ind <- order(murders$total)
murders$abb[ind]
##  [1] "VT" "ND" "NH" "WY" "HI" "SD" "ME" "ID" "MT" "RI" "AK" "IA" "UT" "WV" "NE"
## [16] "OR" "DE" "MN" "KS" "CO" "NM" "NV" "AR" "WA" "CT" "WI" "DC" "OK" "KY" "MA"
## [31] "MS" "AL" "IN" "SC" "TN" "AZ" "NJ" "VA" "NC" "MD" "OH" "MO" "LA" "IL" "GA"
## [46] "MI" "PA" "NY" "FL" "TX" "CA"

max y which.max

Encuentra el valor máximo y su posición dentro de un conjunto de datos.

max(murders$total)
## [1] 1257
i_max <- which.max(murders$total)
murders$state[i_max]
## [1] "California"

rank

Asigna una clasificación numérica a los elementos de un vector según su tamaño.

x <- c(31, 4, 15, 92, 65)
rank(x)
## [1] 3 1 2 5 4

reciclaje

Explica cómo R recicla valores cuando se operan vectores de diferentes tamaños.

x <- c(1, 2, 3)
y <- c(10, 20, 30, 40, 50, 60, 70)
x+y
## Warning in x + y: longer object length is not a multiple of shorter object
## length
## [1] 11 22 33 41 52 63 71

Aritmética de vectores

Se realizan operaciones matemáticas con vectores completos, como cálculos de tasas o conversiones.

library(dslabs)
data("murders")
murders$state[which.max(murders$population)]
## [1] "California"

Re-escalar un vector

Se transforman valores (por ejemplo, pulgadas a centímetros o centrarlos en un valor).

inches <- c(69, 62, 66, 70, 70, 73, 67, 73, 67, 70)
inches * 2.54
##  [1] 175.26 157.48 167.64 177.80 177.80 185.42 170.18 185.42 170.18 177.80
inches - 69
##  [1]  0 -7 -3  1  1  4 -2  4 -2  1

Dos vectores

Se realizan operaciones entre dos vectores para obtener nuevos resultados (como tasas).

murder_rate <- murders$total/ murders$population * 100000
murders$abb[order(murder_rate)]
##  [1] "VT" "NH" "HI" "ND" "IA" "ID" "UT" "ME" "WY" "OR" "SD" "MN" "MT" "CO" "WA"
## [16] "WV" "RI" "WI" "NE" "MA" "IN" "KS" "NY" "KY" "AK" "OH" "CT" "NJ" "AL" "IL"
## [31] "OK" "NC" "NV" "VA" "AR" "TX" "NM" "CA" "FL" "TN" "PA" "AZ" "GA" "MS" "MI"
## [46] "DE" "SC" "MD" "MO" "LA" "DC"

Indexación

Permite seleccionar datos específicos dentro de estructuras como vectores o data frames.

library(dslabs)
data("murders")

Cómo crear subconjuntos con lógicos

Se filtran datos usando condiciones (por ejemplo, tasas menores a cierto valor).

murder_rate <- murders$total/ murders$population * 100000
ind <- murder_rate < 0.71
ind <- murder_rate <= 0.71
murders$state[ind]
## [1] "Hawaii"        "Iowa"          "New Hampshire" "North Dakota" 
## [5] "Vermont"
sum(ind)
## [1] 5

operadores lógicos

Se combinan condiciones con operadores como & para obtener resultados más específicos.

TRUE & TRUE
## [1] TRUE
TRUE & FALSE
## [1] FALSE
FALSE & FALSE
## [1] FALSE
west <- murders$region == "West"
safe <- murder_rate <= 1
ind <- safe & west
murders$state[ind]
## [1] "Hawaii"  "Idaho"   "Oregon"  "Utah"    "Wyoming"

which

Devuelve las posiciones de los elementos que cumplen una condición.

ind <- which(murders$state == "California")
murder_rate[ind]
## [1] 3.374138

match

Encuentra la posición de valores específicos dentro de un vector.

ind <- match(c("New York", "Florida", "Texas"), murders$state)
ind
## [1] 33 10 44
murder_rate[ind]
## [1] 2.667960 3.398069 3.201360

%in%

Verifica si ciertos valores existen dentro de un conjunto de datos.

c("Boston", "Dakota", "Washington") %in% murders$state
## [1] FALSE FALSE  TRUE
match(c("New York", "Florida", "Texas"), murders$state)
## [1] 33 10 44
which(murders$state%in%c("New York", "Florida", "Texas"))
## [1] 10 33 44

Gráficos básicos

plot

Crea gráficos de dispersión para visualizar relaciones entre variables.

x <- murders$population/ 10^6
y <- murders$total
plot(x, y)

with(murders, plot(population, total))

hist

Genera histogramas para ver la distribución de los datos.

x <- with(murders, total/ population * 100000)
hist(x)

murders$state[which.max(x)]
## [1] "District of Columbia"

boxplot

Muestra la distribución de datos agrupados mediante diagramas de caja.

murders$rate <- with(murders, total/ population * 100000)
boxplot(rate~region, data = murders)

image

Representa datos en forma de matriz como una imagen de colores.

x <- matrix(1:120, 12, 10)
image(x)

Conceptos básicos de programación

Expresiones condicionales

Se utilizan estructuras if, else e ifelse para ejecutar código dependiendo de condiciones.

a <- 1

if(a!=0){
  print(1/a)
} else{
  print("No existe inverso multiplicativo para 0")
}
## [1] 1
library(dslabs)
data(murders)
murder_rate <- murders$total/ murders$population*100000

ind <- which.min(murder_rate)

if(murder_rate[ind] < 0.5){
  print(murders$state[ind])
} else{
  print("Ningún estado tiene una tasa de homicidios tan baja.")
}
## [1] "Vermont"
if(murder_rate[ind] < 0.25){
  print(murders$state[ind])
} else{
  print("Ningún estado tiene una tasa de homicidios tan baja.")
}
## [1] "Ningún estado tiene una tasa de homicidios tan baja."
a <- 0
ifelse(a > 0, 1/a, NA)
## [1] NA
a <- c(0, 1, 2, -4, 5)
result <- ifelse(a > 0, 1/a, NA)

data(na_example)
no_nas <- ifelse(is.na(na_example), 0, na_example)
sum(is.na(no_nas))
## [1] 0
z <- c(TRUE, TRUE, FALSE)
any(z)
## [1] TRUE
all(z)
## [1] FALSE

Cómo definir funciones

Se crean funciones personalizadas para realizar cálculos reutilizables.

avg <- function(x){
  s <- sum(x)
  n <- length(x)
  s/n
}

x <- 1:100
identical(mean(x), avg(x))
## [1] TRUE
s <- 3
avg(1:10)
## [1] 5.5
s
## [1] 3
avg <- function(x, arithmetic = TRUE){
  n <- length(x)
  ifelse(arithmetic, sum(x)/n, prod(x)^(1/n))
}

Namespaces

Permite acceder a funciones específicas de paquetes evitando conflictos de nombres.

search()
##  [1] ".GlobalEnv"        "package:dslabs"    "package:stats"    
##  [4] "package:graphics"  "package:grDevices" "package:utils"    
##  [7] "package:datasets"  "package:methods"   "Autoloads"        
## [10] "package:base"
stats::filter
## function (x, filter, method = c("convolution", "recursive"), 
##     sides = 2L, circular = FALSE, init = NULL) 
## {
##     method <- match.arg(method)
##     x <- as.ts(x)
##     storage.mode(x) <- "double"
##     xtsp <- tsp(x)
##     n <- as.integer(NROW(x))
##     if (is.na(n)) 
##         stop(gettextf("invalid value of %s", "NROW(x)"), domain = NA)
##     nser <- NCOL(x)
##     filter <- as.double(filter)
##     nfilt <- as.integer(length(filter))
##     if (is.na(nfilt)) 
##         stop(gettextf("invalid value of %s", "length(filter)"), 
##             domain = NA)
##     if (anyNA(filter)) 
##         stop("missing values in 'filter'")
##     if (method == "convolution") {
##         if (nfilt > n) 
##             stop("'filter' is longer than time series")
##         sides <- as.integer(sides)
##         if (is.na(sides) || (sides != 1L && sides != 2L)) 
##             stop("argument 'sides' must be 1 or 2")
##         circular <- as.logical(circular)
##         if (is.na(circular)) 
##             stop("'circular' must be logical and not NA")
##         if (is.matrix(x)) {
##             y <- matrix(NA, n, nser)
##             for (i in seq_len(nser)) y[, i] <- .Call(C_cfilter, 
##                 x[, i], filter, sides, circular)
##         }
##         else y <- .Call(C_cfilter, x, filter, sides, circular)
##     }
##     else {
##         if (missing(init)) {
##             init <- matrix(0, nfilt, nser)
##         }
##         else {
##             ni <- NROW(init)
##             if (ni != nfilt) 
##                 stop("length of 'init' must equal length of 'filter'")
##             if (NCOL(init) != 1L && NCOL(init) != nser) {
##                 stop(sprintf(ngettext(nser, "'init' must have %d column", 
##                   "'init' must have 1 or %d columns", domain = "R-stats"), 
##                   nser), domain = NA)
##             }
##             if (!is.matrix(init)) 
##                 dim(init) <- c(nfilt, nser)
##         }
##         ind <- seq_len(nfilt)
##         if (is.matrix(x)) {
##             y <- matrix(NA, n, nser)
##             for (i in seq_len(nser)) y[, i] <- .Call(C_rfilter, 
##                 x[, i], filter, c(rev(init[, i]), double(n)))[-ind]
##         }
##         else y <- .Call(C_rfilter, x, filter, c(rev(init[, 1L]), 
##             double(n)))[-ind]
##     }
##     tsp(y) <- xtsp
##     class(y) <- if (nser > 1L) 
##         c("mts", "ts")
##     else "ts"
##     y
## }
## <bytecode: 0x12c6b5438>
## <environment: namespace:stats>
dplyr::filter
## function (.data, ..., .by = NULL, .preserve = FALSE) 
## {
##     check_by_typo(...)
##     check_not_both_by_and_preserve({
##         {
##             .by
##         }
##     }, .preserve)
##     UseMethod("filter")
## }
## <bytecode: 0x10c15d828>
## <environment: namespace:dplyr>

Ciclos - for

Se utilizan bucles para repetir operaciones varias veces.

compute_s_n <- function(n){
  x <- 1:n
  sum(x)
}

for(i in 1:5){
  print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
m <- 25
s_n <- vector(length = m) # crea un vector vacío
for(n in 1:m){
  s_n[n] <- compute_s_n(n)
}

n <- 1:m
plot(n, s_n)

Vectorización y funcionales

Se aplican funciones a vectores completos de forma eficiente usando herramientas como sapply.

x <- 1:10
sqrt(x)
##  [1] 1.000000 1.414214 1.732051 2.000000 2.236068 2.449490 2.645751 2.828427
##  [9] 3.000000 3.162278
y <- 1:10
x*y
##  [1]   1   4   9  16  25  36  49  64  81 100
n <- 1:25
compute_s_n(n)
## Warning in 1:n: numerical expression has 25 elements: only the first used
## [1] 1
x <- 1:10
sapply(x, sqrt)
##  [1] 1.000000 1.414214 1.732051 2.000000 2.236068 2.449490 2.645751 2.828427
##  [9] 3.000000 3.162278
n <- 1:25
s_n <- sapply(n, compute_s_n)
s_n
##  [1]   1   3   6  10  15  21  28  36  45  55  66  78  91 105 120 136 153 171 190
## [20] 210 231 253 276 300 325