PROGRAMACIÓN EN R PARA CIENCIA DE DATOS | R PROGRAMMING FOR DATA SCIENCE

JEISON MAURICIO ALARCÓN BECERRA

2018-II

COMANDOS Y SINTAXIS BÁSICA

ACERCA DE \(\texttt{R}\)

Podemos obtener información útil e importante de \(\texttt{R}\) mediante las siguientes instrucciones.

license()       # Conocer la licencia actual
contributors()  # Conocer los autores de R
citation()      # Sintaxis para citar R
demo()          # Demos disponibles
help()          # Documentación

Con el comando ls() podemos observar las variables guardadas en la consola. Y si deseamos eliminar todas las variables almacenadas hasta el momento la sentencia rm(list=ls()) nos lo permitirá.

ls(); rm(list=ls())
## character(0)

Podemos preguntar acerca de la descripción, forma en que se usa y los argumentos de un función mediante help() ó ?. O hacer una consulta más específica preguntando por el concepto mediante ??.

help(help)
?sum
??beanplot

Después de conocer la información relevante de \(\texttt{R}\) y cómo podemos acceder a la información y descripción de funciones/métodos mediante help(), es imprescindible antes de empezar un proyecto definir el escritorio de trabajo, donde se guardarán los plot’s, se llamarán script’s, funciones, bases de datos e imágenes, para lo cual tenemos las siguientes sentencias.

getwd() # Conocer el directorio de trabajo
setwd() # Establecer el directorio de trabajo

Valores Especiales

VALORES FALTANTES:

  • \(\texttt{NA:}\) Not Available.
  • \(\texttt{NaN:}\) Not a Number. (Un valor NaN es al mismo tiempo NA, pero no se tiene el recíproco)

CONCEPTOS:

  • \(\texttt{Inf:}\) Concepto de infinito positivo “\(\infty\)
  • \(\texttt{-Inf:}\) Concepto de infinito negativo “\(-\infty\)
12/0
#[1] Inf
Inf*(-1)
#[1] -Inf
0/0
#[1] NaN
NA + 7
#[1] NA

\(\texttt{R}\) COMO CALCULADORA

Podemos realizar las operaciones usuales en la consola de \(\texttt{R}\) como si de una calculadora se tratara.

8+8; 8^2; (8-2)*5; (1+7)/(8-4)
#[1] 16   6   30    2
12345679 * 9
#[1] 111111111
(-1)^3
#[1] -1
sqrt(2)
#[1] 1.414214
8^(1/2) - sqrt(8)
#[1] 0

FUNCIONES BÁSICAS

Algunas de las funciones más comunes y que vienen definidas por defecto (no se requiere ningún paquete) se presentan a continuación.

Para mayor información acerca de los distintas funciones de redondeo hacer clic aquí.

ceiling() # Entero mayor o igual
floor()   # Entero menor o igual
trunc()   # Entero más próximo a cero

cos()     # Coseno
sin()     # Seno
tan()     # Tangente
dim()     # Dimensión de la matriz
length()  # Tamaño del vector

sum()     # Suma
abs()     # Valor absoluto
prod()    # Producto
sqrt()    # Raíz cuadrada
exp()     # Exponencial
log()     # Logaritmo neperiano
log(10)   # Logaritmo en base 10

max()     # Máximo
min()     # Mínimo
range()   # Rango
mean()    # Media
median()  # Mediana
var()     # Varianza
sd()      # Desviación estándar

rev()     # Los mismos elementos en orden descendente (de mayor a menor)
sort()    # Los mismos elementos en orden ascendente (de menor a mayor)
sample()  # Genera muestras aleatorias
summary() # Resumen estadístico

Por ejemplo,

( Decimal <- 33.66 )
#[1] 33.66
floor(Decimal)    # Parte Entera []
#[1] 33
ceiling(Decimal)  # Aproximación decimal
#[1] 34
floor(pi)
#[1] 3
ceiling(pi)
#[1] 4
ceiling(pi+0.5)
#[1] 4
trunc(-0.7); trunc(0.7)
#[1] 0   0
round(-0.7); round(0.7)
#[1] -1    1

cos(pi); sin(pi/2)
#[1] -1   1
( e <- exp(1) ) # exp(x) = e^x
#[1] 2.718282
log(10, base = 10)
#[1] 1
log(e)
#[1] 1
log(1)
#[1] 0
log(0)
#[1] -Inf
log(8, base = 2)
#[1] 3
factorial(5)
#[1] 120
abs(-2)
#[1] 2

SECUENCIAS Y REPETICIONES

Podemos realizar tanto secuencias como repeticiones en \(\texttt{R}\), la sintaxis básica para realizar secuencias puede resumirse en seq(de, hasta, incremento, longitud) para el caso de repeticiones es más complicado ya que posee varios argumentos opcionales de entrada.

seq(from = 0, to = 5, by = 0.1)
##  [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8
## [20] 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7
## [39] 3.8 3.9 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.0
seq(from = 0, to = 10, length = 20)
##  [1]  0.0000000  0.5263158  1.0526316  1.5789474  2.1052632  2.6315789
##  [7]  3.1578947  3.6842105  4.2105263  4.7368421  5.2631579  5.7894737
## [13]  6.3157895  6.8421053  7.3684211  7.8947368  8.4210526  8.9473684
## [19]  9.4736842 10.0000000
rep(1,10)
##  [1] 1 1 1 1 1 1 1 1 1 1
rep(1:5, 2)             # Repite todo el vector dos veces
##  [1] 1 2 3 4 5 1 2 3 4 5
rep(1:5, each = 2)      # (a) Repite cada componente dos veces
##  [1] 1 1 2 2 3 3 4 4 5 5
rep(1:5, c(1,2,3,4,5))  # Especificando cuántas veces cada componente
##  [1] 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5
rep(1:5, each = 2, times = 3) # Repite tres veces la secuencia (a)
##  [1] 1 1 2 2 3 3 4 4 5 5 1 1 2 2 3 3 4 4 5 5 1 1 2 2 3 3 4 4 5 5

VECTORES

Asignación de Valores

x <- 10
x
## [1] 10
( x<-10 ) # Si deseamos observar en una sola sentencia el valor de la variable
## [1] 10
( y <- c(2,3,5,7,11,13,17) )
#[1]  2  3  5  7 11 13 17
( z <- as.vector(seq(30,50)) )
#[1] 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
( w <- 20:1 )
#[1] 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1

z <- scan() # Si deseamos ingresar manualmente los valores en la consola
edit(z)     # Para editar los valores ingresados

Operaciones con Vectores

( a <- c(23,34,56,76,65,43,23,12) )
#[1] 23 34 56 76 65 43 23 12
class(a)
#[1] "numeric"
a<30
#[1]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE
class(a>0)
#[1] "logical"
a==23
#[1]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
sum(a); max(a); min(a); range(a); var(a); sd(a)
#[1] 332   76    12    12-76   509.4286    22.57052
summary(a)
#   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#  12.00   23.00   38.50   41.50   58.25   76.00 
c <- 1:10
#[1]  1  2  3  4  5  6  7  8  9 10
d <- -10:-1
#[1] -10  -9  -8  -7  -6  -5  -4  -3  -2  -1
e <- 10:1-1
#[1] 9 8 7 6 5 4 3 2 1 0

Podemos observar que al ser vectores las operaciones se realizan elemento por elemento.

c+d
##  [1] -9 -7 -5 -3 -1  1  3  5  7  9
c-d
##  [1] 11 11 11 11 11 11 11 11 11 11
c*d
##  [1] -10 -18 -24 -28 -30 -30 -28 -24 -18 -10

Las siguientes dos sentencias son de gran utilidad, search() nos ofrece una lista de paquetes adjuntos y objetos \(\texttt{R}\), como data.frames, que se están corriendo en la sesión. Mientras que objects() al igual que ls()nos ofrece una lista con la variables guardadas en la sesión.

search()
##  [1] ".GlobalEnv"          "package:fontawesome" "package:MASS"       
##  [4] "package:expm"        "package:Matrix"      "package:stats"      
##  [7] "package:graphics"    "package:grDevices"   "package:utils"      
## [10] "package:datasets"    "package:methods"     "Autoloads"          
## [13] "package:base"
objects(); ls()
## [1] "c" "d" "e" "x"
## [1] "c" "d" "e" "x"

Extracción de Valores

La sintaxis básica para extraer elementos de un vector es con corchetes \(\color{Green} {\texttt{[ ]}}\), por ejemplo, \(\color{Blue} {\texttt{[}}\)posición de elementos deseados\(\color{Blue} {\texttt{]}}\) o si está acompañado con un “\(\color{Red} {\texttt{-}}\)\(\color{Orange} {\texttt{[}}\)-posición de elementos a omitir\(\color{Orange} {\texttt{]}}\).

( v1<-1:10 )
#[1]  1  2  3  4  5  6  7  8  9 10
v1[3:8]
#[1] 3 4 5 6 7 8
v1[-5]
#[1]  1  2  3  4  6  7  8  9 10
length(v1)  # Observe que no cambia el tamaño del vector
#[1] 10

Similar a la extracción con vectores, para una matriz la sintaxis es muy sencilla y quedaría como \(\color{Red} {[\color{Blue} {\texttt{filas}}, \color{Green} {\texttt{columnas}}]}\). Si no se especifica nada extraerá todos los valores.

( v2 <- cbind(c(2,4,6,8,10),-2*c(2,4,6,8,10)) )
##      [,1] [,2]
## [1,]    2   -4
## [2,]    4   -8
## [3,]    6  -12
## [4,]    8  -16
## [5,]   10  -20
dim(v2)
## [1] 5 2
v2[2:4,]
##      [,1] [,2]
## [1,]    4   -8
## [2,]    6  -12
## [3,]    8  -16

También podemos extraer datos realizando sentencias lógicas, para ello debemos conocer algunos de los operados lógicos más usados,

( x<-c(23,34,56,76,65,43,23,12) )
# [1] 23 34 56 76 65 43 23 12
x>26
# [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
x[x>26]     # Nos devuelve los elementos que cumplen con la condición NO la posición
# [1] 34 56 76 65 43

which(x>26) # Nos devuelve la posición de los elementos que cumplen la condición
# [1] 2 3 4 5 6
x[c(1,4,7)] # Extraemos los valores en las posiciones indicadas
# [1] 23 76 23

sum(x>70) # Nos arroja la cantidad (cuántos) de elementos que cumplen la condición
# [1] 1
sum(x>70)/length(x) # Estaríamos dividendo los casos favorables sobre el total de casos posibles
                    # Es decir, la probabilidad de obtener un número mayor a 70.
# [1] 0.125

x[1]          # Extraemos el primer elemento
# [1] 23
x[length(x)]  # Extraemos el último elemento
# [1] 12
x[-c(2:(length(x)-1))] # Extraemos el primer y último elemento, omitimos los demás
# [1] 23 12
x[1]=100  # Asignamos al primer elemento el valor de 100
x         # Observamos que efectivamente se realizó el cambio
# [1] 100  34  56  76  65  43  23  12
x[c(2,3)]=c(-50,50) # Asignando múltiples valores
x
# [1] 100 -50  50  76  65  43  23  12

Más ejemplos de operaciones con vectores,

x1 <- 1:5
x1>1 & x1<5   # Evalúa que elementos cumplen la condición
# [1] FALSE  TRUE  TRUE  TRUE FALSE
x1>1 && x1<5  # Solo se fija si el primer elemento cumple la condición
# [1] FALSE
x1>1 | x1<5
# [1] TRUE TRUE TRUE TRUE TRUE
x1>1 || x1<5
# [1] TRUE

x1!=3    # Qué elementos son diferentes a 3
# [1]  TRUE  TRUE FALSE  TRUE  TRUE
!x1==3   # Otra manera de hacerlo
# [1]  TRUE  TRUE FALSE  TRUE  TRUE
!x1=="3" # Funciona si se compara con un carácter o un número
# [1]  TRUE  TRUE FALSE  TRUE  TRUE

Los ejemplos mostrados anteriormente son de vital importancia. Imagine el siguiente ejemplo con un poco más de contexto, en el que se tiene en un vector una muestra de 20 familias con el número de hijos que éstas tienen y se desea responder a ciertas preguntas de interés.

Hijos <- c(0,1,2,3,1,2,2,2,0,0,0,5,3,2,3,1,0,1,2,2)
sum(Hijos==3)   # ¿Cuántas familias tienen 3 hijos?
## [1] 3
# [1] 3
which(Hijos==3) # ¿En qué posiciones de la muestra se encuentran las familias anteriores?
## [1]  4 13 15
# [1]  4 13 15
which(Hijos>=(mean(Hijos))) # ¿Qué muestras están por encima de la media?
##  [1]  3  4  6  7  8 12 13 14 15 19 20
# [1]  3  4  6  7  8 12 13 14 15 19 20
MayorMedia <- which(Hijos>=(mean(Hijos))) # ¿Qué valores son los que están por encima de la media?
Hijos[MayorMedia]
##  [1] 2 3 2 2 2 5 3 2 3 2 2
# [1] 2 3 2 2 2 5 3 2 3 2 2
sum(Hijos>=(mean(Hijos))) # ¿Cuántas muestras están por encima de la media?
## [1] 11
# [1] 11

MATRICES

Construcción

Para la construcción de matrices tenemos dos alternativas, la primera de ella es usar la función matrix(x, nrow, ncol, byrow, ...), a continuación, se explican algunos de sus argumentos:

  • \(\color{DarkOrange}{\texttt{ncol}}:\) Número de columnas.
  • \(\color{Purple}{\texttt{nrow}}:\) Número de filas.
  • \(\color{Magenta}{\texttt{byrow}}:\) Indica si se organizan (se llena la matriz) por filas (TRUE), o por columnas (FALSE).
# Observe que se rellena columna a columna (de izquierda a derecha)
( m <- matrix(1:10, nrow = 2, ncol = 5) )
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    3    5    7    9
## [2,]    2    4    6    8   10
x <- 1:16
matrix(x, nrow = 2)
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,]    1    3    5    7    9   11   13   15
## [2,]    2    4    6    8   10   12   14   16
matrix(x, nrow = 2, byrow = TRUE)
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,]    1    2    3    4    5    6    7    8
## [2,]    9   10   11   12   13   14   15   16
matrix(x, ncol = 4)
##      [,1] [,2] [,3] [,4]
## [1,]    1    5    9   13
## [2,]    2    6   10   14
## [3,]    3    7   11   15
## [4,]    4    8   12   16
matrix(x, ncol = 4, byrow = TRUE)
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16

Observe los siguientes aspectos o propiedades de la matriz m creada anteriormente.

dim(m)        # Dimensión -> c(nrow(m),ncol(m))
## [1] 2 5
length(m)     # Tamaño    -> nrow(m)*ncol(m)
## [1] 10
class(m)      # Clase
## [1] "matrix" "array"
attributes(m) # Atributos
## $dim
## [1] 2 5

La segunda alternativa es pegar vectores, tanto columna como fila, y así formar la matriz, para ello debemos conocer las siguientes funciones:

  • \(\color{DarkGreen}{\texttt{cbind()}}:\) Va pegando los vectores como si fuesen columnas, uno al lado del otro.
  • \(\color{DarkBlue}{\texttt{rbind()}}:\) Va pegando los vectores como si fuesen filas, uno bajo el otro.
a <- 1:4
b <- rep(0,4)
c <- c(5,7,11,13)
cbind(a,b,c)
##      a b  c
## [1,] 1 0  5
## [2,] 2 0  7
## [3,] 3 0 11
## [4,] 4 0 13
rbind(a,b,c)
##   [,1] [,2] [,3] [,4]
## a    1    2    3    4
## b    0    0    0    0
## c    5    7   11   13

También podemos transformar un vector a una matriz con la siguiente sentencia.

( v <- 1:10 )
##  [1]  1  2  3  4  5  6  7  8  9 10
dim(v) <- c(2,5)
v
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    3    5    7    9
## [2,]    2    4    6    8   10

Por último y antes de pasar a las funciones con matrices, observe que le podemos poner nombre tanto a las filas como a las columnas de una matriz.

( mm <- matrix(1:4, nrow=2, ncol=2) )
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
dimnames(mm) <- list(c('A','B'), c('C','D'))
mm
##   C D
## A 1 3
## B 2 4

Entradas y Trozos de Matrices

Al igual que con los vectores los corchetes también permiten el acceso a los elementos, en este caso de un matiz, podemos obtener entradas específicas, con la diferencia que para especificar la posición de un elemento deseado debemos especificar ahora dos coordenadas. Una coma dentro de los corchetes separa los índices de filas y columnas. La sintaxis se resume a continuación,

  • \(\texttt{M}\color{Red} {[\color{Blue}{\texttt{i}}, \color{Green}{\texttt{j}}]}\): Entrada \((i,j)\) de \(\texttt{M}\)
  • \(\texttt{M}\color{Orange} {[\color{Blue}{\texttt{i}}, ]}\): Fila i-ésima de \(\texttt{M}\)
  • \(\texttt{M}\color{Magenta} {[, \color{Green}{\texttt{j}}]}\): Columna j-ésima de \(\texttt{M}\)
  • \(\texttt{diag()}\): Diagonal principal de la matriz.
( M <- matrix(1:20, ncol = 5, byrow = TRUE) )
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    2    3    4    5
## [2,]    6    7    8    9   10
## [3,]   11   12   13   14   15
## [4,]   16   17   18   19   20
M[1,]
## [1] 1 2 3 4 5
M[,1]
## [1]  1  6 11 16
M[1:3,1:3]
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    6    7    8
## [3,]   11   12   13

Funciones Matriciales Específicas

Entre las funciones matriciales predefinidas más importantes encontramos:

  • \(\color{Red}{\texttt{diag()}}\): Dependiendo del tipo de estructura que ingrese a ella la función operara de acuerdo con ello. Si introducimos una matriz, ésta extraerá la diagonal principal como vector. Si por lo contrario ingresamos un vector, ésta creará una matriz diagonal con el vector introducido en la diagonal. Finalmente, si introducimos un escalar, ésta creará una matriz idéntica del orden ingresado.
( A <- matrix(1:9, nrow = 3, ncol = 3, byrow = TRUE) )
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
diag(A)
## [1] 1 5 9
diag(c(1,2,3,4))
##      [,1] [,2] [,3] [,4]
## [1,]    1    0    0    0
## [2,]    0    2    0    0
## [3,]    0    0    3    0
## [4,]    0    0    0    4
diag(pi+0.8) # Si ingresamos un decimal usará la función floor(.) para saber de qué tamaño debe ser la matriz por crear
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    1    0
## [3,]    0    0    1
diag(-1)  # Nos arrojara un error, pues espera un número no negativo
## Error in diag(-1): valor 'nrow' no válido (< 0)
diag(0)   # Nos creará efectivamente un matriz de orden 0x0
## <0 x 0 matrix>
  • \(\color{Magenta}{\texttt{t()}}\): Devuelve la matriz transpuesta.
t(A)
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
  • \(\color{Blue}{\texttt{det()}}\): Calcula el determinante de una matriz cuadrada. Puede verificar numéricamente (líneas comentadas) algunas de las propiedades del determinante como:
    • \(\left| A^n \right| = \left| A \right|^n\)
    • \(\left| A^{-1} \right| = \frac{1}{\left| A \right|}\)
    • \(\left| A^t \right| = \left| A \right|\)
    • \(\left| k\cdot A_{n\times n} \right| = k^n\cdot \left| A \right|\)
    • \(\left| A\cdot B \right| = \left| A \right| \cdot \left| B \right|\)
( A <- diag(c(2,4,8)) )
##      [,1] [,2] [,3]
## [1,]    2    0    0
## [2,]    0    4    0
## [3,]    0    0    8
det(A)
## [1] 64
prod(eigen(A)$values) # Otra forma de calcular el determinante
## [1] 64
# library(expm) # Para usar el operador %^%
# det(A%^%3); det(A)^3
# det(solve(A)); 1/det(A)
# det(t(A)); det(A)
# det(2*A); (2^nrow(A))*det(A)
# B <- matrix(sample(9),3,3)
# det(A%*%B); det(A)*det(B)
  • \(\color{Green}{\texttt{solve()}}\): Devuelve la inversa de una matriz cuadrada y definida positiva. Si se introduce además dentro de los argumentos un vector \(\vec{b}\), se resolverá el sistema \(A\vec{x}=\vec{b}\), retornando el vector \(\vec{x}\). Puede verificar numéricamente (líneas comentadas) algunas de las propiedades del determinante como:
    • \((A\cdot B)^{-1} = B^{-1}\cdot A^{-1}\)
    • \((A^{-1})^{-1} = A\)
    • \((k\cdot A)^{-1} = \frac{1}{k}\cdot A^{-1}\)
    • \((A^t)^{-1} = (A^{-1})^t\)
A <- matrix(c(2,4,0,3,3,1,4,2,0), nrow = 3)
fractions(solve(A))
##      [,1] [,2] [,3]
## [1,] -1/6  1/3 -1/2
## [2,]    0    0    1
## [3,]  1/3 -1/6 -1/2
solve(A)%*%A # Comprobación
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    1    0
## [3,]    0    0    1
solve(A, c(1,2,3))
## [1] -1.0  3.0 -1.5
# B <- matrix(c(1,0,1,2,2,2,-1,3,2), nrow = 3)
# fractions( solve(A%*%B) ); fractions( solve(B)%*%solve(A) )
# solve(solve(A)) - A
# fractions( solve(5*A) ); fractions( (1/5)*solve(A) )
# solve(t(A)) - t(solve(A))
  • \(\color{DarkOrange}{\texttt{lower.tri() | upper.tri()}}\): Devuelve una matriz de lógicos del mismo tamaño de la matriz dada con entradas TRUE en la triangular inferior o superior, respectivamente. El argumento opcional diag = T/F indica si deseamos o no incluir los elementos de la diagonal.
lower.tri(A); upper.tri(A)
##       [,1]  [,2]  [,3]
## [1,] FALSE FALSE FALSE
## [2,]  TRUE FALSE FALSE
## [3,]  TRUE  TRUE FALSE
##       [,1]  [,2]  [,3]
## [1,] FALSE  TRUE  TRUE
## [2,] FALSE FALSE  TRUE
## [3,] FALSE FALSE FALSE
A*upper.tri(A)
##      [,1] [,2] [,3]
## [1,]    0    3    4
## [2,]    0    0    2
## [3,]    0    0    0
A*!lower.tri(A, diag = T) # Otra forma de obtener A*upper.tri(A)
##      [,1] [,2] [,3]
## [1,]    0    3    4
## [2,]    0    0    2
## [3,]    0    0    0
A[upper.tri(A)] # Si deseo un vector con dichos valores
## [1] 3 4 2
# Incluyendo la diagonal principal
A*upper.tri(A, diag = T); A*lower.tri(A, diag = T)
##      [,1] [,2] [,3]
## [1,]    2    3    4
## [2,]    0    3    2
## [3,]    0    0    0
##      [,1] [,2] [,3]
## [1,]    2    0    0
## [2,]    4    3    0
## [3,]    0    1    0
  • \(\color{Purple}{\texttt{eigen()}}\): Devuelve los vectores y valores propios de la matriz pasada como parámetro. Con el parámetro only.values = T/F se puede solicitar si desea solo los valores propios omitiendo los vectores propios,
A <- matrix(sample(9),3,3)
Results <- eigen(A)

summary.default(Results)
##         Length Class  Mode   
## values  3      -none- numeric
## vectors 9      -none- numeric
Results$values  # Valores Propios (otra forma de ingresar a ellos es Results[[1]])
## [1]  1.465331e+01  6.346688e+00 -1.474695e-15
Results$vectors # Vectores Propios (otra forma de ingresar a ellos es Results[[2]])
##           [,1]        [,2]       [,3]
## [1,] 0.7597497  0.92109460  0.1978141
## [2,] 0.5220303 -0.38726648 -0.6593805
## [3,] 0.3876401 -0.04011747  0.7253185
  • \(\color{Teal}{\texttt{traza()}}\): \(\texttt{R}\) no dispone en si con una función para realizar dicho calculo, pero con las funciones ya vistas podemos crearla fácilmente.
traza <- function(Matriz) { return(sum(diag(Matriz))) }
traza(A)
## [1] 21
# OTRA FORMA CREATIVA DE CALCULAR LA TRAZA
# Observe que cbind(1:nrow(A),1:nrow(A)) crea una matriz cuyos elementos son
# (1,1), (2,2), ... , (n,n). Obteniendo así los elementos diagonales.
sum(A[cbind(1:nrow(A),1:nrow(A))])
## [1] 21
  • \(\color{DarkRed}{\texttt{DefPositiva()}}\): En muchas ocasiones nos encontramos con la necesidad de conocer si una matriz es definida positiva, por ejemplo, para evitar errores en algunas funciones que requiere que la matriz a ingresar sea definida positiva, por lo tanto, con lo aprendido y conociendo algo de teoría podemos crearla fácilmente.
DefPositiva <- function(Matriz){
  Logical <- all(eigen(Matriz)$values>0)
  return(Logical)
}
A <- matrix(c(8,-5,1,-5,9,-2,1,-2,4), nrow = 3)
DefPositiva(A)
## [1] TRUE
  • \(\color{Darkblue}{\texttt{chol()}}\): Calcula la factorización por el método de Cholesky de una matriz cuadrada, simétrica, real y definida positiva.
chol(A)
##          [,1]      [,2]       [,3]
## [1,] 2.828427 -1.767767  0.3535534
## [2,] 0.000000  2.423840 -0.5672817
## [3,] 0.000000  0.000000  1.8849911
t(chol(A))%*%chol(A) # Comprobación
##      [,1] [,2] [,3]
## [1,]    8   -5    1
## [2,]   -5    9   -2
## [3,]    1   -2    4
  • \(\color{DarkGreen}{\texttt{qr()}}\): Calcula la descomposición QR de una matriz.
qr(A)
## $qr
##            [,1]       [,2]      [,3]
## [1,] -9.4868330  9.1706052 -2.319004
## [2,] -0.5270463 -5.0892043  1.912545
## [3,]  0.1054093 -0.2337578  3.458958
## 
## $rank
## [1] 3
## 
## $qraux
## [1] 1.843274 1.972295 3.458958
## 
## $pivot
## [1] 1 2 3
## 
## attr(,"class")
## [1] "qr"
  • \(\color{Purple}{\texttt{svd()}}\): Calcula la descomposición en valores singulares de una matriz rectangular.
svd(A)
## $d
## [1] 13.990893  4.092396  2.916711
## 
## $u
##            [,1]       [,2]      [,3]
## [1,] -0.6468343 -0.6186113 0.4460107
## [2,]  0.7327383 -0.3419844 0.5883377
## [3,] -0.2114236  0.7073661 0.6744874
## 
## $v
##            [,1]       [,2]      [,3]
## [1,] -0.6468343 -0.6186113 0.4460107
## [2,]  0.7327383 -0.3419844 0.5883377
## [3,] -0.2114236  0.7073661 0.6744874

Funciones Aplicadas a Matrices

  • \(\color{DarkBlue}{\texttt{colSums()}}\): Devuelve un vector donde cada componente \(j\) representa la suma de la columna \(j\)
  • \(\color{Purple}{\texttt{colMeans()}}\): Devuelve un vector donde cada componente \(j\) representa la media de la columna \(j\)
  • \(\color{DarkGreen}{\texttt{rowSums()}}\): Devuelve un vector donde cada componente \(i\) representa la suma de la fila \(i\)
  • \(\color{DarkRed}{\texttt{rowMeans()}}\): Devuelve un vector donde cada componente \(i\) representa la media de la fila \(i\)
  • \(\color{DarkOrange}{\texttt{apply(matriz, Fun=función, MARGIN=...)}}\)
    • \(\color{Blue}{\texttt{MARGIN=1}}\): Fila a fila.
    • \(\color{Green}{\texttt{MARGIN=2}}\): Columna a columna.
    • \(\color{Red}{\texttt{MARGIN=c(1,2)}}\): Entrada a entrada
M
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    2    3    4    5
## [2,]    6    7    8    9   10
## [3,]   11   12   13   14   15
## [4,]   16   17   18   19   20
colSums(M); colMeans(M)
## [1] 34 38 42 46 50
## [1]  8.5  9.5 10.5 11.5 12.5
rowSums(M); rowMeans(M)
## [1] 15 40 65 90
## [1]  3  8 13 18
apply(M, MARGIN = 1, FUN = summary)
##         [,1] [,2] [,3] [,4]
## Min.       1    6   11   16
## 1st Qu.    2    7   12   17
## Median     3    8   13   18
## Mean       3    8   13   18
## 3rd Qu.    4    9   14   19
## Max.       5   10   15   20
apply(M, MARGIN = 2, FUN = prod)
## [1]  1056  2856  5616  9576 15000
apply(M, MARGIN = c(1,2), FUN = sqrt)
##          [,1]     [,2]     [,3]     [,4]     [,5]
## [1,] 1.000000 1.414214 1.732051 2.000000 2.236068
## [2,] 2.449490 2.645751 2.828427 3.000000 3.162278
## [3,] 3.316625 3.464102 3.605551 3.741657 3.872983
## [4,] 4.000000 4.123106 4.242641 4.358899 4.472136

Operadores Aritméticos

  • \(\color{Blue}{\texttt{+ | - | * | / | ^ :}}\) Los operadores aritméticos usuales al ser aplicados en matrices se realizan elemento a elemento. Coincidiendo con la definición matricial para el caso de la suma y la resta, pero no en el caso del producto ni la potencia. Si se efectúa con un escalar se realiza a todos los elementos de la matriz, y si es un vector se realiza en cada fila.
( A <- matrix(9:1, nrow = 3, byrow = T) )
##      [,1] [,2] [,3]
## [1,]    9    8    7
## [2,]    6    5    4
## [3,]    3    2    1
A+A
##      [,1] [,2] [,3]
## [1,]   18   16   14
## [2,]   12   10    8
## [3,]    6    4    2
A+10
##      [,1] [,2] [,3]
## [1,]   19   18   17
## [2,]   16   15   14
## [3,]   13   12   11
A+c(1,2,3) # A la fila i de la matriz se le suma el elemento i del vector
##      [,1] [,2] [,3]
## [1,]   10    9    8
## [2,]    8    7    6
## [3,]    6    5    4
A/2
##      [,1] [,2] [,3]
## [1,]  4.5  4.0  3.5
## [2,]  3.0  2.5  2.0
## [3,]  1.5  1.0  0.5
A**2
##      [,1] [,2] [,3]
## [1,]   81   64   49
## [2,]   36   25   16
## [3,]    9    4    1
  • \(\color{Orange}{\texttt{%*% :}}\) Se realiza el producto matricial.
A%*%A
##      [,1] [,2] [,3]
## [1,]  150  126  102
## [2,]   96   81   66
## [3,]   42   36   30
  • \(\color{Green}{\texttt{%^% :}}\) \(\texttt{R}\) no dispone en su paquete base una función para calcular la potencia n-ésima de una matriz, para ello debemos usar la librería expm, con la cual podemos obtener \(A^n\) con A %^% n.
# library(expm)
A%^%2
##      [,1] [,2] [,3]
## [1,]  150  126  102
## [2,]   96   81   66
## [3,]   42   36   30

Ejercicios Propuestos

x <- c(2,-1,0,5,-1,2,-1,3,0,-1,2,-2,5,3,-2,40)
( A <- matrix(x, nrow = 4) )

( B <- matrix(x, ncol = 2, byrow = T) )
( C <- matrix(x, ncol = 2) )

b <- c(0,12,7,-1)
matrix(b, nrow = 4, ncol = 15)

( D <- matrix(b, nrow = 15, ncol = 4, byrow = T) )
D2 <- t(matrix(b, nrow = 4, ncol = 15))
all.equal(D, D2)

# Traza de la Diagonal Secundaria
A[,4:1]
sum(diag(A[,ncol(A):1]))

sum(A[cbind(4:1,1:4)])

# Verificar que si son valores propios (El determinante de $A-\lambdaI$ = 0)
vvp <- eigen(A)
I <- diag(nrow(A))
det(A-(vvp$values[1]*I))
det(A-(vvp$values[2]*I))
det(A-(vvp$values[3]*I))
det(A-(vvp$values[4]*I))

# Construya una copia de a en la que todos los elementos menos lo de la última columna estén ^2
CopiaA <- A^2
CopiaA[,4] <- A[,4]

DATAFRAMES

Asignación de Valores

# Fix(Data_Frame): Permite modificar/añadir TODO el data frame.

CONTROL DE FLUJO, CONDICIONALES Y OTRAS ESTRUCTURAS

El cliclo \(\texttt{FOR}\)

La forma general de un bucle FOR para ejecutar una expresión repetitiva que depende de un índice \(i\) es la siguiente:

for(i in a:b) {
  expresión(i)
}

El bucle siempre empieza con la cláusula \(for\) e incluye en su interior todo un conjunto de comandos que dependen de uno o varios índices que definen el bucle.

Ejemplo 1). Escriba una función que cree una “Matriz de Hilbert”, la cual es una matriz cuadrada cuyos campos constituyen una fracción de la unidad, y cuyo término general es:

\[H_{ij}=\frac{1}{i+j-1}, i,j=1\cdots n\]

Matriz_Hilbert = function(n) {
  Matriz = matrix(data = 0, nrow = n, ncol = n)
  for (i in 1:n) {
    for (j in 1:n) {
      Matriz[i,j] = 1/(i+j-1)
    }
  }
  return(Matriz)
}
fractions(Matriz_Hilbert(4))
##      [,1] [,2] [,3] [,4]
## [1,]   1  1/2  1/3  1/4 
## [2,] 1/2  1/3  1/4  1/5 
## [3,] 1/3  1/4  1/5  1/6 
## [4,] 1/4  1/5  1/6  1/7

El bucle \(\texttt{WHILE}\)

La sintaxis general de este bucle es la siguiente:

while (condición) {
  comandos
}

El bucle siempre empieza con la cláusula \(while\) seguida de una condición, e incluye en su interior todo un conjunto de comandos que se ejecutan mientras se cumpla la condición.

Ejemplo 1). Escriba una función cuya ejecución permita calcular el mayor número cuyo factorial no exceda \(10^{100}\).

i = 1
while (factorial(i)<10^100) {
  i=i+1
}
print(i)
## [1] 70

La estructura condicional \(\texttt{IF ELSE}\) y \(\texttt{IFELSE}\)

Esta permite ejecutar secuencias de comandos si se cumplen una determinada condición y otra secuencia de comandos diferentes si no se cumple la condición anterior. En el caso específico en el que solo hay dos condiciones (una al ser verdadera la condición y otra al ser falsa) se usa por simplicidad IFELSE.

Ejemplo 1).

ValorAbs = function(x){ ifelse(x>=0, x, -x) }
ValorAbs(c(-2:2))
## [1] 2 1 0 1 2

La estructura \(\texttt{SWITCH}\)

Esta estructura ejecuta ciertas sentencias basadas en el valor de una expresión. Su sintaxis básica es:

switch(expresión, valor1=acción1, ... , valork=acciónk)

Ejemplo 1).

EstadistBasicos <- function(x, Tipo) {
  switch(Tipo, Media=mean(x), Mediana=median(x), Longitud=length(x))
}
EstadistBasicos(1:20, Tipo = "Media")
## [1] 10.5
EstadistBasicos(1:20, Tipo = "Longitud")
## [1] 20

\(\texttt{NEXT}\)

Dicha instrucción pasa el control a la iteración siguiente en un bucle \(for\) o \(while\) en el cual aparece, ignorando las restantes instrucciones en el cuerpo del bucle.

for (i in -2:2) {
  if(i==0) next
  print(1/i)
}
## [1] -0.5
## [1] -1
## [1] 1
## [1] 0.5

\(\texttt{BREAK}\)

Dicha instrucción finaliza la ejecución de un bucle \(for\) o \(while\) en el cual aparece continuando la ejecución en la siguiente instrucción fuera del bucle.

for (i in -2:2) {
  if(i==0) break
  print(1/i)
}
## [1] -0.5
## [1] -1

La estructura \(\texttt{REPEAT}\)

Esta instrucción permite ejecutar repetidamente una expresión mientras se cumple una condición. Se suele finalizar con una instrucción \(break\) para finalizar el proceso de repetición.

i = 0
repeat{
  print(i);
  i=i+1;
  if (i==5) break
}
## [1] 0
## [1] 1
## [1] 2
## [1] 3
## [1] 4

ALGORITMOS DE CÁLCULO NUMÉRICO

Los métodos de programación permiten abordar las técnicas de cálculo numérico mediante la implementación sencilla de los algoritmos teóricos

Ejemplo 1). Método de Newton para resolver la ecuación \(f(x)=0\)

SUMMARY OF “An Introduction to \(\texttt{R}\)

Introducción y Preliminares

  • \(\texttt{R}\) puede definirse como una nueva implementación del lenguaje \(\texttt{S}\) desarrollado en AT&T por Rick Becker, John Chambers y Allan Wilks.
  • En \(\texttt{R}\), un análisis estadístico se realiza en una serie de pasos, con unos resultados intermedios que se van almacenando en objetos, para ser observados o analizados posteriormente, produciendo unas salidas mínimas. Sin embargo, en \(\color{DarkBlue} {\texttt{SAS}}\) o \(\color{Red} {\texttt{SPSS}}\) se obtendrá de modo inmediato una salida copiosa para cualquier análisis, por ejemplo, una regresión o un análisis discriminante.
  • Cuando \(\texttt{R}\) espera la entrada de órdenes, presenta un símbolo para indicarlo. El símbolo predeterminado es “\(>\)” (tenga en cuenta que es posible modificar este símbolo).
  • Para obtener información sobre una función concreta, por ejemplo \(\texttt{solve()}\), la orden en \(\texttt{R}\) es
help(solve)

Una forma alternativa es

?(solve)

Con las funciones especificadas por caracteres especiales, el argumento deberá ir entre comillas, para transformarlo en una “cadena de caracteres”:

help("[[")

En muchas versiones de \(\texttt{R}\) puede acceder a la ayuda escrita en formato \(\texttt{HTML}\), escribiendo

help.star()
  • \(\texttt{R}\) distingue entre MAYÚSCULAS y minúsculas, de tal modo que \(\texttt{A}\) y \(\texttt{a}\) son símbolos distintos y se referirán, por tanto, a objetos distintos.
  • Las ordenes elementales consisten en expresiones o en asignaciones. Si una orden consiste en una expresión, se evalúa, se imprime y su valor se pierde. Una asignación, por el contrario, evalúa una expresión, no la imprime y guarda su valor en una variable. Por ejemplo,
x <- 10   # Asignación
x/2       # Expresión
# [1] 5
  • Las órdenes se separan mediante punto y coma, (“;”), o mediante un cambio de línea.
  • Si al terminar una línea, la orden no está sintácticamente completa, \(\texttt{R}\) mostrará un signo de continuación “\(\color{Green} {\texttt{+}}\)” en la línea siguiente y las sucesivas y continuará leyendo hasta que la orden esté sintácticamente completa (dicho signo puede ser modificado fácilmente).
  • Las flechas verticales del teclado ( \(\,\,\) ) pueden utilizarse para recorrer el historial de órdenes \(\,\) .
  • Si tiene órdenes almacenadas en un archivo del sistema operativo, por ejemplo, \(\texttt{ordenes.R}\), en el directorio de trabajo, \(\texttt{trabajo}\), puede ejecutarlas dentro de una sesión de \(\texttt{R}\) con la orden
source("ordenes.R")
  • La orden \(\texttt{sink}\), como por ejemplo en
sink("resultado.lis")

enviará el resto de la salida, en vez de a la pantalla, al archivo del sistema operativo, \(\texttt{resultado.lis}\), dentro del directorio de trabajo. La orden

sink()

devuelve la salida de nuevo a la pantalla.

  • La orden \(\texttt{objects()}\) se puede utilizar para obtener los nombres de los objetos almacenados en \(\texttt{R}\). Esta función es equivalente a la función \(\texttt{ls()}\).
objects(); ls()
# [1] "x"
# [1] "x"
identical(objects(), ls())
# [1] TRUE

La colección de objetos almacenados en cada momento se denomina espacio de trabajo (workspace).

  • Para eliminar objetos puede utilizar la orden \(\texttt{rm()}\), por ejemplo:
rm(x, y, z, tinta, chatarra, temporal, barra)
rm(list=ls(all=TRUE)) # Remover todos los objetos
  • Los objetos creados durante una sesión de \(\texttt{R}\) pueden almacenarse en un archivo para su uso posterior. Al finalizar la sesión, \(\texttt{R}\) pregunta si desea hacerlo. En caso afirmativo todos los objetos se almacenan en el archivo “.RData” en el directorio de trabajo. En la siguiente ocasión que ejecute \(\texttt{R}\), se recuperarán los objetos de este archivo, así como el historial de órdenes.

Licencia de Creative Commons
Este obra cuyo autor es Jeison Mauricio Alarcón Becerra está bajo una licencia de Reconocimiento-NoComercial-SinObraDerivada 4.0 Internacional de Creative Commons.
Creado a partir de la obra en https://rpubs.com/JeisonAlarcon.